我正在尝试使用AES密钥加密RSA私钥,以使用标准Java库创建PKCS#8文件。
当我运行下面的示例代码(使用Java 7)时,我得到一个例外:
Exception in thread "main" java.security.NoSuchAlgorithmException: unrecognized algorithm name: AES at sun.security.x509.AlgorithmId.get(AlgorithmId.java:440) at javax.crypto.EncryptedPrivateKeyInfo.(EncryptedPrivateKeyInfo.java:178) at Example.main(Example.java:30)
sun.security.x509.AlgorithmId
的{p> Digging into the code,此异常表示无法将"AES"
映射到合适的OID。
我尝试将"AES"
替换为"AES/CBC/PKCS5Padding"
,但这导致AlgorithmParameters.getInstance()
调用失败并显示“ AES / CBC / PKCS5Padding AlgorithmParameters not available ”。< / p>
我还尝试将明确的算法声明为2.16.840.1.101.3.4.1.2,但也因“ AlgorithmParameters not available ”错误而失败。
作为noted in the comments below,Java 8中不会发生此错误。
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024);
KeyPair keyPair = generator.generateKeyPair();
SecretKey zmkKey = new SecretKeySpec(new byte[16], "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.WRAP_MODE, zmkKey, new IvParameterSpec(new byte[16]));
byte[] encryptedPrivateKey = c.wrap(keyPair.getPrivate());
AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("AES");
algorithmParameters.init(new IvParameterSpec(new byte[16]));
new EncryptedPrivateKeyInfo(algorithmParameters, encryptedPrivateKey); // line 30
答案 0 :(得分:1)
目前,我已经使用了BouncyCastle。下面是生成PEM编码的,AES加密的PKCS#8对象的代码。
如果有一个仅使用标准JDK库的解决方案(并且在Java 8之前工作),我仍然会感兴趣。
final byte[] iv = new byte[16]; // random would be better
OutputEncryptor encryptor = new OutputEncryptor() {
@Override
public OutputStream getOutputStream(OutputStream encOut) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, zmkKey, new IvParameterSpec(iv));
return new CipherOutputStream(encOut, cipher);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public GenericKey getKey() {
return new JceGenericKey(getAlgorithmIdentifier(), zmkKey);
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return new AlgorithmIdentifier(
NISTObjectIdentifiers.id_aes128_CBC,
// AES CBC mode requires an IV, specified as an octet string
new DEROctetString(iv));
}
};
PKCS8Generator pkcs8Generator = new JcaPKCS8Generator(keyPair.getPrivate(), encryptor);
StringWriter sw = new StringWriter();
try (PemWriter writer = new PemWriter(sw)) {
writer.writeObject(pkcs8Generator);
}
String pemPKCS8 = sw.toString();