当前位置: 首页 > 知识库问答 >
问题:

使用Java生成有效的CMS签名文件,添加外部PKCS#1

宗政安歌
2023-03-14



第一步是从要在返回PKCS#1字节数组的外部应用程序中签名的原始文件中获取签名属性。

然后使用原始文件哈希、签名数据(PKCS#1)和证书构建标准org.bouncycastle.cms.SignerInfoDynamator以添加到CMS,最后创建附加签名。

但当我试图使用此代码验证它时:

        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);


我得到验证:false

我正在添加内容类型、签名时间、消息摘要和 OCSP 作为签名属性,将 TSP 令牌添加为未签名属性(我不确定这是否正确)。

我还尝试使用以下代码从CMS签名中恢复数据:

        //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());
            }

        }

但是我无法检索OCSP响应或TSP令牌信息。此外,我下载了这个浏览器软件来帮助验证它:

任何帮助将不胜感激。

共有1个答案

袁成化
2023-03-14

我发现了一个名为j4sign的项目,它实现了带有外部PKCS#1的CMS签名。链接指向该项目的论坛,在那里我发布了使用他们的类的代码示例和使验证生效的最终修正。

 类似资料:
  • 我开始学密码学了。我需要用XML、RSA私钥(证书中不包括的是文件扩展名。key)和证书。cer扩展名生成一个PKCS#7文件。 为此,我使用了一个bouncycastle。 编辑:

  • 我想做的是: 使用证书使用openssl对zip文件进行签名,并创建签名文件(PKCS#7) 我安装了openssl并打开了控制台 我创建了一个rsa密钥(openssl genrsa-out key.pem 2048) 我创建了一个请求(openssl req-batch-sha256-new-key key.pem-out request.pem-subj'/c=../st=../l=../o

  • 我想使用BouncyCastle生成一个简单的CMS签名。这代码管用! 但是,如何添加签名属性呢? 我要删除默认签名属性并添加签名策略标识符。 文章非常欢迎。

  • 我正在使用谷歌KMS(https://cloud.google.com/kms/)使用非对称签名密钥对节点中的JSON Web令牌(jwt)进行签名。js应用程序。 我能够创建标头和有效载荷,并与谷歌KMS nodejs库(https://github.com/googleapis/nodejs-kms)我可以签署令牌。 但似乎生成的令牌无效。 事实上,我正在执行以下步骤来生成令牌: 将jwt头定

  • 问题内容: 我想使用Bouncycastle生成一个简单的CMS签名。此代码有效! 但是,如何添加签名属性? 我想删除默认的签名属性并添加signature-policy-identifier。 文章非常受欢迎。 问题答案: 首先,您似乎正在使用最新版本的Bouncy Castle中不推荐使用的构造。要添加经过身份验证/签名的属性,您必须将它们打包到AttributeTable中,将签名的属性添加

  • 我想用pdf摘要签署pdf文件。我使用下面的代码创建了散列, 最后,我需要把这个签名附在我的PDF上。我找到了一个解决方案,从文件摘要创建pkcs7签名,但在链接中使用的算法是SHA256with RSA。我的privatekey是使用EC算法生成的,我需要使用SHA256withECDSA。是否可以使用SHA256withECDSA对哈希进行签名,并使用PDFBox ExternalSignin