![](/img/trans.png)
[英]Read an encrypted private key with bouncycastle/spongycastle
[英]Outputting encrypted PK8 private key from Java BouncyCastle
我正在尝试在Matlab中使用Java生成加密的私钥和CSR。 Matlab增加了一些小的复杂性,但这主要是Java问题。 我从一个私钥开始:
java.security.Security.addProvider(org.bouncycastle.jce.provider.BouncyCastleProvider());
keyGen = java.security.KeyPairGenerator.getInstance('RSA', 'BC');
keyGen.initialize(2048, java.security.SecureRandom());
keypair = keyGen.generateKeyPair();
privateKey = keypair.getPrivate();
如果我加密密钥并将其输出为PEM:
m=org.bouncycastle.openssl.PKCS8Generator.PBE_SHA1_3DES;
encryptorBuilder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder(m);
encryptorBuilder.setRandom(java.security.SecureRandom());
encryptorBuilder.setPasssword(password);
oe = encryptorBuilder.build();
gen = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator(privateKey,oe);
privKeyObj = gen.generate();
fos = java.io.FileWriter('private.pem');
pem = org.bouncycastle.openssl.jcajce.JcaPEMWriter(fos);
pem.writeObject(privKeyObj);
pem.flush();
fos.close();
我得到一个完美的钥匙。 问题是我想将密钥与jdbc一起使用,因此我需要一个DER格式的pk8密钥。 我无法弄清楚如何从BouncyCastle中解脱出来。 成功的kludge解决方法:
textWriter = java.io.StringWriter();
pem = org.bouncycastle.openssl.jcajce.JcaPEMWriter(textWriter);
pem.writeObject(privateKey);
pem.flush();
thekey = char(textWriter.toString());
cmd = ['echo "' thekey '"|openssl pkcs8 -topk8 -out private.pk8 -inform PEM -outform DER -passout pass:' password];
system(cmd);
现在,很明显,这同时暴露了未加密的私钥和密码。 我已经尝试了各种方法来将privKeyObj强制转换为DER,但是它们通常使我陷入困境:
$openssl pkcs8 -inform DER -outform PEM -in private.pk8 -out private.pem
Error decrypting key
140735211835472:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1201:
140735211835472:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:tasn_dec.c:765:
140735211835472:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:697:Field=version, Type=PKCS8_PRIV_KEY_INFO
该代码的目的是在最终用户的计算机上生成一个我签名的CSR,然后使用该计算机的MAC地址(和盐)对其进行加密,以便该程序仅在授权的计算机上运行,并且仅授权的机器将能够访问我的PostgreSql数据库。
建议?
我想到了。 在我的原始代码中,我使用了BcPKCS12PBEOutputEncryptorBuilder。 错误! 正确的调用是对JcePKCSPBEOutputEncryptorBuilder。 正确的代码(在MATLAB中,但是转换为Java很简单)是:
java.security.Security.addProvider(org.bouncycastle.jce.provider.BouncyCastleProvider());
keyGen = java.security.KeyPairGenerator.getInstance('RSA', 'BC');
keyGen.initialize(2048, java.security.SecureRandom());
keypair = keyGen.generateKeyPair();
privateKey = keypair.getPrivate();
builder=org.bouncycastle.pkcs.jcajce.JcaPKCS8EncryptedPrivateKeyInfoBuilder(privateKey);
m=org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC;
encryptorBuilder = org.bouncycastle.pkcs.jcajce.JcePKCSPBEOutputEncryptorBuilder(m);
password = 'test';
outputBuilder = encryptorBuilder.build(password);
privKeyObj = builder.build(outputBuilder);
fos = java.io.FileOutputStream('testkey.pk8');
fos.write(privKeyObj.getEncoded());
fos.flush();
fos.close();
这将生成DER格式的PCS#8文件。
openssl pkcs8 -inform DER -outform PEM -in testkey.pk8 -out testkey.pem
现在返回PEM私钥。 读取密钥:
myPath = java.nio.file.Paths.get(pwd,'testkey.pk8');
encodedKey = java.nio.file.Files.readAllBytes(myPath);
privKeyObj =org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo(encodedKey);
cp=org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter();
cp.setProvider('BC');
decryptorBuilder = org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder();
inputBuilder = decryptorBuilder.build(password);
info = privKeyObj.decryptPrivateKeyInfo(inputBuilder);
decodedKey=cp.getPrivateKey(info);
请注意,在MATLAB中,您无需声明返回对象的类型,也不需要在构造函数之前放置“ new”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.