用java中的bouncy castle为文件签名

用java中的bouncy castle为文件签名,java,security,certificate,bouncycastle,sign,Java,Security,Certificate,Bouncycastle,Sign,我想用java对文件内容和证书进行签名 通过终端和openssl,我可以做到: openssl smime -sign -in nosign.mobileconfig -out signed.mobileconfig -signer server.crt -inkey server.key -certfile cacert.crt -outform der -nodetach server.crt和.key是要签名的文件,我想我知道cacert.crt是嵌入在out内容中的 最后,我得到了一个

我想用java对文件内容和证书进行签名

通过终端和openssl,我可以做到:

openssl smime -sign -in nosign.mobileconfig -out signed.mobileconfig -signer server.crt -inkey server.key -certfile cacert.crt -outform der -nodetach
server.crt和.key是要签名的文件,我想我知道cacert.crt是嵌入在out内容中的

最后,我得到了一个签名并受信任的文件

在Java中,我不能使用openssl(不想启动openssl命令),所以我必须用lib对其进行签名

为此,我使用Bouncy Castle(1.53版)

这是我的密码:

    byte[] profile = ...; // I can have it also in String

    // the certificate in -certfile
    FileInputStream inputStream = new FileInputStream("src/main/resources/cacert.crt"); 

    byte[] caCertificate = ByteStreams.toByteArray(inputStream);

    // the certificate to sign : server.crt, embedded in p12
    X509Certificate serverCertificate = (X509Certificate) this.keyStore.getCertificate("1");

    // Private key is the server.key
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(this.privateKey);

    CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
    generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
            new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, serverCertificate));

    // the embedded certificate : cacert.crt, but  I don't know if it is good to do that this way
    X509CertificateHolder holder = new X509CertificateHolder(caCertificate);

    generator.addCertificate(holder);

    CMSProcessableByteArray bytes = new CMSProcessableByteArray(profile);
    CMSSignedData signedData = generator.generate(bytes, true);

    System.out.println("signedData : \n" + signedData.getEncoded());
你能帮我拿到好的签名资料吗?谢谢

编辑: 我有一个错误

    X509CertificateHolder holder = new X509CertificateHolder(caCertificate);

java.io.IOException:遇到未知标记13

CA证书文件显然是PEM(ASCII)格式。X509CertificateHolder的构造函数需要证书的BER/DER(二进制)编码

您可以通过添加以下内容对其进行转换:

PEMParser pemParser = new PEMParser(new FileReader("src/main/resources/cacert.crt"));
X509CertificateHolder caCertificate = (X509CertificateHolder) pemParser.readObject();
您还应将签名证书添加到CMS结构中:

generator.addCertificate(new X509CertificateHolder(serverCertificate.getEncoded()));

你读过本教程了吗?你的问题是什么?您是否收到任何错误消息或其他信息?我在X509CertificateHolder=new X509CertificateHolder(caCertificate)上有一个错误;java.io.IOException:遇到未知标记13我检查了cacert,它的格式很好..谢谢!它帮助我嵌入cacert.crt,现在不再出错。对于记录,PEMReader不再存在,但我可以使用PEMParser parser=newpemparser(fileReader);parser.readObject();我的配置文件已生成,但仍无法识别为由我的OS@zarghol我已经更新了我的答案。除了不添加签名者证书之外,您的代码看起来非常好。但是,您遗漏了很多东西,如果p12文件不是用Java生成的,那么它们经常会出现问题。如果仍然遇到问题,请创建一个.I used generator.addCertificate((X509CertificateHolder)parser.readObject());自从我在30小时前发表评论以来,它是有效的,但是,它现在起作用了,它被认为是已签名的!我会尝试一些改变,但它是全球性的。谢谢你的帮助!