我手上有问题。 我的同事,谁不知道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
。
如果有人能请指导我正确的代码或给我一开始我会很感激你的努力。
我也有复制在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
首先,不觉得不好努力理解BouncyCastle的。 这是一个非常有用的API,但它的不良记录。 最好的办法是,以搜索周围的例子,将教你如何使用API。
由于我没有用BouncyCastle的用于SMIME之前(我主要是用它的PGP和/或JCE)的“短暂追捕bouncycastle smime example
”我已经买了这个网页 ,并具体地讲, 这个例子 。
希望这是一个良好的开端,从中进一步谷歌搜索将有助于了解在使用API类。 我猜想,例如单独将让你的存在方式80%。
如果有关于您的输入文件的目的的任何困惑:
-certfile WWDR.pem
- 这是一个附加的证书的消息中指定。 验证签名时,签名邮件的收件人会考虑这个证书。
-signer passcertificate.pem
- 这是直接对应于您的签名密钥证书。
-inkey passkey.pem
- 这是您的签名密钥
所以,如果有人想知道如何解决我上面这里我的问题是我做过什么:
我用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);
谢谢大家