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

如何使用BC将分离的CAdES签名转换为包络签名?

宓和同
2023-03-14

我的java applet能够使用Detached类型的Bouncy Castle 1.4.9生成CMSSignedData。然后将字节数组sigData.getEncoded()存储在服务器上的一个表中(该表可以访问未包含的内容数据)。现在我想在服务器中创建封装的CMSSignedData,以便用户下载一个.p7m文件。

我需要开发的函数具有分离签名的字节数组和内容数据的字节数组,并且必须返回一个CaDES包络签名的字节数组,该字节数组将用于下载.p7m文件。

问题是我无法将分离的信号转换为一个包封的信号。

private byte[] signCAdES(byte[] aDocument, PrivateKey aPrivateKey, Certificate[] certChain)
        throws GeneralSecurityException {
    byte[] digitalSignature = null;
    try {

        Security.addProvider(new BouncyCastleProvider());
        ArrayList<X509Certificate> certsin = new ArrayList<X509Certificate>();
        for (int i = 0; i < certChain.length; i++) {
            certsin.add((X509Certificate) certChain[i]);
        }
        X509Certificate cert = certsin.get(0);
        //Nel nuovo standard di firma digitale e' richiesto l'hash del certificato di sottoscrizione:
        String digestAlgorithm = "SHA-256";
        String digitalSignatureAlgorithmName = "SHA256withRSA";
        MessageDigest sha = MessageDigest.getInstance(digestAlgorithm);
        byte[] digestedCert = sha.digest(cert.getEncoded());

        //Viene ora create l'attributo ESSCertID versione 2 cosi come richiesto nel nuovo standard:
        AlgorithmIdentifier aiSha256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
        ESSCertIDv2 essCert1 = new ESSCertIDv2(aiSha256, digestedCert);
        ESSCertIDv2[] essCert1Arr = {essCert1};
        SigningCertificateV2 scv2 = new SigningCertificateV2(essCert1Arr);
        Attribute certHAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(scv2));

        //Aggiungiamo l'attributo al vettore degli attributi da firmare:
        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(certHAttribute);
        AttributeTable at = new AttributeTable(v);
        CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(at);

        //Creaiamo l'oggetto che firma e crea l'involucro attraverso le librerie di Bouncy Castle:
        SignerInfoGeneratorBuilder genBuild = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider());
        genBuild.setSignedAttributeGenerator(attrGen);

        //Si effettua la firma con l'algoritmo SHA256withRSA che crea l'hash e lo firma con l'algoritmo RSA:
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        ContentSigner shaSigner = new JcaContentSignerBuilder("SHA256withRSA").build(aPrivateKey);
        SignerInfoGenerator sifGen = genBuild.build(shaSigner, new X509CertificateHolder(cert.getEncoded()));
        gen.addSignerInfoGenerator(sifGen);
        X509CollectionStoreParameters x509CollectionStoreParameters = new X509CollectionStoreParameters(certsin);
        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();

        FileOutputStream fos = new FileOutputStream("H:\\prova2.txt.p7m");
        fos.write(attach(aDocument, encoded));
        fos.flush();
        fos.close();
        digitalSignature = encoded;


    } catch (CMSException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    } catch (OperatorCreationException ex) {
        ex.printStackTrace();
    }
    return digitalSignature;
}
public static byte[] attach(byte[] originalData, byte[] detached) {
    try {
        ASN1InputStream in = new ASN1InputStream(detached);

        CMSSignedData sigData = new CMSSignedData(new CMSProcessableByteArray(originalData), in);

        return sigData.getEncoded();
    } catch (Exception e) {
        return null;
    }
}

共有1个答案

韩弘阔
2023-03-14

这个回应来得有点晚。你肯定会找到另一种选择,因为不可能把一个独立的CAdES转换成信封

查看RFC 3852-CMS中定义的CAdES签名的signeddata节点的ASN.1结构

SignedData包括EncapContentInfo,该EncapContentInfo包含要为信封签名签名的原始数据,但不存在于分离签名中。由于signeddata是签名的,因此不可能添加原始数据以将分离的数据转换为封装

 类似资料:
  • 第二个是不同的,我必须手动添加属性,但是生成的PDF已损坏(然后我可能需要添加发行人序列属性): 有没有人懂使用java的CAdES数字签名?任何帮助都将不胜感激!

  • 我想使用BouncyCastle解析和验证OpenPGP分离签名。签名如下所示: 下面是我如何尝试在Kotlin中创建CMSSignedData: 我应该如何使用BouncyCastle验证这种签名?

  • 我正在尝试使用.NET(CNG提供商)的现有ECDSA密钥,以便使用Bouncy Castle对数据进行签名,然后在两种签名格式(P1363和ASN.1)之间进行转换。然而,我总是得到不同的签名。我不太确定转换是否不正确,或者我是否使用了不正确的方法来使用Bouncy Castle读取.NET密钥。 由于某些原因,和已经不同,我假设问题甚至可能在转换之前就出现了。我已经看过许多StackOverf

  • 我正在编写一个接收PKCS7数据(从签名的PDF文档中提取)的服务,并需要对其进行验证。 我使用iText7 PdfPKCS7进行验证,但签名验证总是失败。我可以从PKCS7读取所有其他信息(证书、时间戳等,我也用OpenSSL验证了这一点)。只有签名显示为无效。 下面是测试案例: 输出总是: 我想我在进口方面做错了什么,但就是找不到什么... 顺便说一句,验证其他pdf工具(Adobe DC、P

  • 我想实现PDF的“并行”签名过程,这样用户就可以不是“一个接一个”地进行数字签名,而是同时进行数字签名。为了实现这一点,我决定为所有用户创建初始文档的单独副本,并在它们上获得签名。最终,所有签名都应该连接到单个PDF中。 让我们假设,PDF在签名过程中没有变化,除了签名字段创建(所有acroForms、signaturecontainer、可视签名等都是在之前创建的,并且对所有这些都是相似的)。

  • 你能详细解释一下吗?最后给我举个例子(一个是附加的,一个是分离的),说明iText分离签名的确切含义? 我发现了这个精彩的留档: iText数字签名pdf关于iText数字签名,但我仍然不确定我是否理解iText分离签名的概念。 阅读文档(参见链接),我发现了以下定义: 在PDF中,我们有时指的是分离的签名。根据维基百科的说法,分离签名是一种“与签名数据分离”的数字签名,而不是“捆绑在一起形成一个