在 java 中使用充气城堡签署文件
sign file with bouncy castle in java
我想用 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 嵌入在输出内容中。
最后,我有一个已签名并受信任的文件。
在 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()));
我想用 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 嵌入在输出内容中。
最后,我有一个已签名并受信任的文件。
在 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()));