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

CAdES数字签名

能远
2023-03-14
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已损坏(然后我可能需要添加发行人序列属性):

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数字签名?任何帮助都将不胜感激!

共有1个答案

汪丁雷
2023-03-14

'issuer-serial'属性不存在或不匹配!

这意味着您的cades签名没有签名属性:对签名证书的签名引用或此引用被篡改。

有关更多信息,请查看:ETSI TS 101 733 V2.2.1(2013-04):

 类似资料:
  • 我的java applet能够使用Detached类型的Bouncy Castle 1.4.9生成CMSSignedData。然后将字节数组sigData.getEncoded()存储在服务器上的一个表中(该表可以访问未包含的内容数据)。现在我想在服务器中创建封装的CMSSignedData,以便用户下载一个.p7m文件。 我需要开发的函数具有分离签名的字节数组和内容数据的字节数组,并且必须返回一

  • 数字签名 类似在纸质合同上签名确认合同内容,数字签名用于证实某数字内容的完整性(integrity)和来源(或不可抵赖,non-repudiation)。 一个典型的场景是,A 要发给 B 一个文件(一份信息),B 如何获知所得到的文件即为 A 发出的原始版本?A 先对文件进行摘要,然后用自己的私钥进行加密,将文件和加密串都发给 B。B 收到后文件和加密串,用 A 的公钥来解密加密串,得到原始的数

  • 我有字节数组格式的公钥。在我的数据库里。像这样 在此处输入图像描述 总是suc=false。我确信bytetoverify的值与方法符号中的输入值相同。 我不知道我用这种方式生成公钥是问题还是符号有问题。在符号方法中,我使用sh1和pkcs1,但在验证中,我只找到sh1。 每个人都能帮我吗?

  • 我这里需要帮助,有人能帮我吗?

  • 在我的应用程序中,我有一个公钥(表示为字符串),普通消息和数字签名,表示为base64编码字符串,用SHA256散列,用RSA加密)。现在,我需要验证数字签名。我试图做如下操作: 从创建(取自此处) 根据原始消息创建SHA256摘要 使用函数验证签名 (我正在努力避免使用OpenSSL函数) 此外,我的数字签名是使用Java的SHA256withRSA方法创建的。我在这里读到SHA256WithR

  • 印度的《公司法》有一些变化。其中值得注意的是,有一项规定,如果公司进行了数字签名,则可以以电子形式维护其登记册。以下几点让我感到困惑: > 记录一旦以数字方式标注日期和签名,不得编辑或更改; 记录应能够根据法案的规定或根据法案制定的规则进行更新,更新日期应能够记录在每次更新中。 想象一下,我们正在对PDF中的表进行数字签名。如果表中最初有2行,并且用户对pdf进行数字签名。现在,我们在pdf中再添