Java中的充气城堡签名文件(sign file with bouncy castle in java)

15 IT屋

I want to sign a file content with certificate in java.

With terminal and openssl, I can do this :

openssl smime -sign -in nosign.mobileconfig -out signed.mobileconfig -signer server.crt -inkey server.key -certfile cacert.crt -outform der -nodetach

server.crt and .key are the files to sign, and I think I understand the cacert.crt is embedded inside the out content.

finally, I have a file signed and trusted.

In Java, I can't use openssl (don't want to launch openssl command) so, I have to sign it with a lib.

To do that, I use Bouncy Castle (version 1.53)

here is my code :

    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());

Can you help me to have the good signed data please ? Thanks !

EDIT : I've got an error at

    X509CertificateHolder holder = new X509CertificateHolder(caCertificate);

java.io.IOException: unknown tag 13 encountered

解决方案

The CA certificate file is obviously in PEM (ASCII) format. The constructor for X509CertificateHolder needs the BER/DER (binary) encoding of the certificate.

You can convert it by adding this:

PEMParser pemParser = new PEMParser(new FileReader("src/main/resources/cacert.crt"));
X509CertificateHolder caCertificate = (X509CertificateHolder) pemParser.readObject();

You should add the signing certificate to the CMS structure as well:

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

我想在Java中使用证书对文件内容进行签名。



使用终端和openssl,我可以这样做:



  openssl smime -sign -in nosign.mobileconfig -outsigned.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)



这是我的代码:



 个字节[] = ...; //我也可以在字符串

中使用它//证书在-certfile
中FileInputStream inputStream = new FileInputStream(" src / main / resources / cacert.crt");

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

//要签名的证书:server.crt,嵌入在p12中
X509Certificate serverCertificate =(X509Certificate)this.keyStore.getCertificate(" 1");

//私钥是服务器。
ContentSigner sha1Signer = new JcaContentSignerBuilder(" SHA1withRSA")。setProvider(" BC")。build(this.privateKey);

CMSSignedDataGenerator生成器=新的CMSSignedDataGenerator();
generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder()。setProvider(" BC")。build())。build(sha1Signer,serverCertificate));

//嵌入式证书:cacert.crt,但我不知道用这种方式这样做是否好
X509CertificateHolder持有人= new X509CertificateHolder(caCertificate);

generator.addCertificate(holder);

CMSProcessableByteArray字节=新的CMSProcessableByteArray(配置文件);
CMSSignedDatasignedData = generator.generate(bytes,true);

System.out.println(" signedData:\n" + signedData.getEncoded());


请问您能帮我获得好的签名数据吗?谢谢!



编辑:
我遇到了一个错误



  X509CertificateHolder持有人=新的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())); 

本文地址:IT屋 » Java中的充气城堡签名文件