我想用java中的证书签名文件内容.
有了terminal和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()));