Generate valid CMS Signature file adding external PKCS#1 with Java

耗尽温柔 提交于 2020-01-15 05:56:07

问题


I'm generating CMS signature files with external PKCS#1 based on this thread.

The first step is obtain the signed attributes from the original file to be signed in external application which is returning PKCS#1 byte array.

Then build standard org.bouncycastle.cms.SignerInfoGenerator with original file hash, signed data (PKCS#1) and certificate to add to CMS, and finally create the attached signature.

But when i'd tried to validate it using this code:

        String originalFile = "aG9sYQ0KYXNkYXMNCg0KYWZzDQo=";
        String cmsSignedFile = "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBg...j2Dwytp6kzQNwtXGO8QbWty1lOo8oYm+6LR8EWba3ikO/m9ol/G808vit9gAAAAAAAA==";
        byte[] signedByte = DatatypeConverter.parseBase64Binary(cmsSignedFile);

        Security.addProvider(new BouncyCastleProvider());

        CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(DatatypeConverter.parseBase64Binary(originalFile)), signedByte);
        SignerInformationStore signers = s.getSignerInfos();
        SignerInformation signerInfo = (SignerInformation)signers.getSigners().iterator().next();

        FileInputStream fis = new FileInputStream("C:/myCertificate.cer");
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate)cf.generateCertificates(fis).iterator().next();

        boolean result = signerInfo.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert.getPublicKey())); 
        System.out.println("Verified: "+result);


I get Verified: false

I'm adding Content Type, Signing time, Message digest and OCSP as signed attributes and TSP Token as unsigned attribute (I'm not sure if this is right).

I'm also trying to recover data from CMS signature, using the code below:

        //load cms signed file with attached data
        CMSSignedData cms = new CMSSignedData(FileUtils.readFileToByteArray(new File("C:/tmp/tempFile1864328163858309463.cms")));

        System.out.println(cms.getSignerInfos().getSigners().iterator().next().getDigestAlgorithmID().getAlgorithm().getId());
        System.out.println(Hex.encodeHexString(cms.getSignerInfos().getSigners().iterator().next().getSignature()));

        //recover signer certificate info
        Store certs = cms.getCertificates();
        Collection<X509CertificateHolder> col = certs.getMatches(null);
        X509CertificateHolder []h1 = col.toArray(new X509CertificateHolder[col.size()]);
        X509CertificateHolder firmante = h1[0];
        System.out.println(firmante.getSubject());
        System.out.println(h1[1].getSubject());
        SignerInformation sinfo = cms.getSignerInfos().getSigners().iterator().next();

        //recover OCSP information
        //THIS FAILS :(
//          Store infocspbasic = cms.getOtherRevocationInfo(OCSPObjectIdentifiers.id_pkix_ocsp_basic);
//          Object basic = infocspbasic.getMatches(null).iterator().next();


        //recover signing time
        if (sinfo.getSignedAttributes() != null) {

            Attribute timeStampAttr = sinfo.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_signingTime);
            ASN1Encodable attrValue = timeStampAttr.getAttrValues().getObjectAt(0);

            final Date signingDate;
            if (attrValue instanceof ASN1UTCTime) {
                ASN1UTCTime time =  ASN1UTCTime.getInstance(attrValue);
                Date d = time.getDate();
                System.out.println("ASN1UTCTime:" + d);
            } else if (attrValue instanceof Time) {
                signingDate = ((Time) attrValue).getDate();
            } else if (attrValue instanceof ASN1GeneralizedTime) {
                System.out.println("ASN1GeneralizedTimeASN1GeneralizedTime");
            } else {
                signingDate = null;
            }
        }


        //recover timestamp TOken
        //unsigned attributes are null :(
        if (sinfo.getUnsignedAttributes() != null) {

            Attribute timeStampAttr = sinfo.getUnsignedAttributes().get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);

            for (ASN1Encodable value : timeStampAttr.getAttrValues().toArray()) {
                TimeStampToken token = new TimeStampToken(new CMSSignedData(value.toASN1Primitive().getEncoded()));
                System.out.println(token.getTimeStampInfo().getGenTime());
            }

        }

But I can't retrieve OCSP response nor TSP Token information. Additionally I've downloaded this viewer software to help verify it:

Any help would be very appreciated.


回答1:


I found a project named j4sign which implements CMS signature with external PKCS#1. The link goes to the project's forum where I posted the code sample using their classes and the final correction to make the validation works.



来源:https://stackoverflow.com/questions/39143180/generate-valid-cms-signature-file-adding-external-pkcs1-with-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!