2014-11-12 5 views
1

저는 포르투갈 시민 카드를 사용하여 PDF 파일 용 디지털 서명 (CAdES)을 구현하려했지만 완벽하게 작동하는 솔루션을 찾는 데 어려움을 겪고 있습니다. 현재 두 세트의 코드가 있습니다.CAdES 디지털 서명

먼저 하나

첫 번째 작품
public void signCAdES(...) 
{ 
     String pkcs11Config = "name=GemPC" + "\n" + "library=C:\\WINDOWS\\SysWOW64\\pteidpkcs11.dll"; 
     ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes()); 
     Provider pkcs11Provider = new sun.security.pkcs11.SunPKCS11(configStream); 

        //provider_name: SunPKCS11-GemPC 
     Security.addProvider(pkcs11Provider); 

     javax.security.auth.callback.CallbackHandler cmdLineHdlr = new DialogCallbackHandler(); 

     KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", pkcs11Provider, 
       new KeyStore.CallbackHandlerProtection(cmdLineHdlr)); 
     KeyStore ks= builder.getKeyStore(); 

     PdfReader reader = new PdfReader(src); 
     FileOutputStream os = new FileOutputStream(dest); 

     PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', new File(tempPath), true); 
     PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); 

     appearance.setReason(reason); 
     appearance.setLocation(location); 
     appearance.setCertificationLevel(level); 

     String alias = "CITIZEN SIGNATURE CERTIFICATE"; 

        //certificates from electronic card and resources folder 
     Certificate[] certs = getSignatureCertificatesChain(ks); 

     PrivateKey pk = (PrivateKey) ks.getKey(alias, null); 

     ExternalSignature es = new PrivateKeySignature(pk, "SHA-1", pkcs11Provider.getName()); 
     ExternalDigest digest = new BouncyCastleDigest(); 

     MakeSignature.signDetached(appearance, digest, es, certs, null, null, null, 0, MakeSignature.CryptoStandard.CADES); 
} 

그러나 내가 가지고 PDF의 서명이 기준을 만족하고 속성 중 하나가 누락 된 것 같습니다 경우 확인 나에게 주어진 발리 (서명 발급자의 일련 번호).

두 번째는 다른, 나는 그러나 생성 된 PDF가 손상 수동으로 속성을 추가해야합니다 (그리고 내가 너무 발행자 일련의 속성을 추가해야 할 수도 있습니다) :

private static void signCAdES(byte[] aDocument, PrivateKey aPrivateKey, Certificate[] certChain, String outputPath) { 
    try { 

     Security.addProvider(new BouncyCastleProvider()); 
     ArrayList<X509Certificate> certsin = new ArrayList<X509Certificate>(); 
     for (Certificate certChain1 : certChain) { 
      certsin.add((X509Certificate) certChain1); 
     } 

     X509Certificate signingCertificate= certsin.get(0); 

     MessageDigest dig = MessageDigest.getInstance("SHA-1"); 
     byte[] certHash = dig.digest(signingCertificate.getEncoded()); 

     ESSCertID essCertid = new ESSCertID(certHash); 
     DERSet set = new DERSet(new SigningCertificate(essCertid)); 

     Attribute certHAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate, set); 
     AttributeTable at = getAttributeTableWithSigningCertificateAttribute(certHAttribute); 
     CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(at); 

     SignerInfoGeneratorBuilder genBuild = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()); 
     genBuild.setSignedAttributeGenerator(attrGen); 

     CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 
     ContentSigner shaSigner = new JcaContentSignerBuilder("SHA1withRSA").build(aPrivateKey); 
     SignerInfoGenerator sifGen = genBuild.build(shaSigner, new X509CertificateHolder(signingCertificate.getEncoded())); 
     gen.addSignerInfoGenerator(sifGen); 
     JcaCertStore jcaCertStore = new JcaCertStore(certsin); 
     gen.addCertificates(jcaCertStore); 

     CMSTypedData msg = new CMSProcessableByteArray(aDocument); 
     CMSSignedData sigData = gen.generate(msg, false); // false=detached 

     byte[] encoded = sigData.getEncoded(); 

     ASN1InputStream in = new ASN1InputStream(encoded); 
     CMSSignedData sigData2 = new CMSSignedData(new CMSProcessableByteArray(aDocument), in); 
     byte[] encoded2 = sigData2.getEncoded(); 

     FileOutputStream fos = new FileOutputStream(outputPath); 
     fos.write(encoded2); 
//  fos.write(encoded); 
     fos.flush(); 
     fos.close(); 
    } catch (CMSException | IOException | OperatorCreationException | CertificateEncodingException ex) { 
     log("signCAdES", "Error: " + ex.toString()); 
    } 
} 

이 거기 사람이 Java를 사용하여 CAdES 디지털 서명을 누가 이해합니까? 어떤 도움을 주시면 감사하겠습니다!

+0

샘플 문서를 공유하십시오. 또한 유효성 검사기 이름을 지정하고 유효성 검사 보고서를 공유 할 수 있습니까? – mkl

+0

유효성 검사기의 소스 코드는 https://github.com/arhs/sd-dss (ARHS 그룹)에 있습니다. 유효성 확인 보고서에 따르면 첫 번째 코드 집합에 의해 수행 된 서명은 유효하지만 " issuer-serial '특성이 없거나!"과 일치하지 않는다는 경고가 표시됩니다. 샘플 문서는 서명/서명 된 PDF를 의미합니까? – aries23

+0

* 샘플 문서는 서명/서명 된 PDF를 의미합니까? * - 예, 서명 된 PDF. 경고와 관련하여 : 잘못되었거나 누락 된 발행자 - 직렬 속성의 위치를 ​​나타 냅니까? 포함하는 인증서의 속성 인 경우 코드에서 수정할 수는 없지만 다른 더 우수한 발급 기관으로 전환하면됩니다. – mkl

답변

1

'issuer-serial'속성이 없거나 일치하지 않습니다!

귀하의 cades 서명이 서명 된 속성 : 서명 된 인증서에 대한 참조 또는이 참조가 변조되었음을 의미합니다.

확인하세요 ETSI TS 101 733 V2.2.1 (2013-04)에 더 많은 정보는 다음

5.7.3 인증서 참조 서명

서명 인증서 기준 특성

가 어느 를 이용하여 지원되는 속성 ESS 서명 인증 속성 또는 ESS-signing-certificate-v2 속성 ...