复制“OpenSSL的SMIME”在Java中与充气城堡?(Replicating 'ope

2019-09-23 12:41发布

我手上有问题。 我的同事,谁不知道Java的使用OpenSSL的命令签署一份文件,如下所示:

openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem \
  -inkey passkey.pem -in manifest.json -out signature -outform DER \
  -passin pass:12345

正如你可以看到这里有三个文件都送给了OpenSSL的命令生成签名。

现在,我们要复制使用Java,因为我们是假设要签名的内容将是动态的,是服务器端在本质上相同的功能。 我读了BouncyCastle的是要走的路。 但我不知道如何去使用这个库。 我不是很熟悉的加密技术太。 我无法理解我怎么使用上面的所有三个文件签署的内容manifest.json

如果有人能请指导我正确的代码或给我一开始我会很感激你的努力。

Answer 1:

我也有复制在java中了OpenSSL命令,这是我如何完成它。 无需使用运行。

public byte[] signMobileConfig(byte[] mobileconfig) 
            throws CertificateEncodingException, PEMException, FileNotFoundException, IOException, CertificateException, OperatorCreationException, CMSException {
    Security.addProvider(new BouncyCastleProvider());

    X509CertificateHolder caCertificate = loadCertfile();

    JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter();
    X509Certificate serverCertificate = certificateConverter.getCertificate(loadSigner());

    PrivateKeyInfo privateKeyInfo = loadInKey();
    PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey);

    CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
    JcaDigestCalculatorProviderBuilder digestProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC");
    JcaSignerInfoGeneratorBuilder generatotBuilder = new JcaSignerInfoGeneratorBuilder(digestProviderBuilder.build());

    generator.addSignerInfoGenerator(generatotBuilder.build(sha1Signer, serverCertificate));
    generator.addCertificate(new X509CertificateHolder(serverCertificate.getEncoded()));
    generator.addCertificate(new X509CertificateHolder(caCertificate.getEncoded()));

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

    return signedData.getEncoded();
}

这里就是我如何加载文件:

public X509CertificateHolder loadSigner() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (X509CertificateHolder) parser.readObject();
}

public PrivateKeyInfo loadInKey() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.key");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (PrivateKeyInfo) parser.readObject();
}

public X509CertificateHolder loadCertfile() throws FileNotFoundException, IOException {
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt");
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream));
    return (X509CertificateHolder) parser.readObject();
}

这是我的文件映射:

myCrtFile.crt -> signerCertHolder
myKeyFile.key -> privateKeyInfo
bundleCertificate.crt -> certificateHolder


Answer 2:

首先,不觉得不好努力理解BouncyCastle的。 这是一个非常有用的API,但它的不良记录。 最好的办法是,以搜索周围的例子,将教你如何使用API​​。

由于我没有用BouncyCastle的用于SMIME之前(我主要是用它的PGP和/或JCE)的“短暂追捕bouncycastle smime example ”我已经买了这个网页 ,并具体地讲, 这个例子 。

希望这是一个良好的开端,从中进一步谷歌搜索将有助于了解在使用API​​类。 我猜想,例如单独将让你的存在方式80%。


如果有关于您的输入文件的目的的任何困惑:

-certfile WWDR.pem - 这是一个附加的证书的消息中指定。 验证签名时,签名邮件的收件人会考虑这个证书。

-signer passcertificate.pem - 这是直接对应于您的签名密钥证书。

-inkey passkey.pem - 这是您的签名密钥



Answer 3:

所以,如果有人想知道如何解决我上面这里我的问题是我做过什么:

我用Java的运行对象!

String openSSLCommand = openssl smime -binary 
-sign -certfile WWDR.pem -signer passcertificate.pem
-inkey passkey.pem -in manifest.json -out signature -outform DER
-passin pass:12345

Process process = Runtime.getRuntime().exec(openSSLCommand);

谢谢大家



文章来源: Replicating 'openssl smime' in Java with Bouncy Castle?