我正在尝试使用标准 Java 库使用 AES key 加密 RSA 私钥,以创建 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)
Digging into the code of sun.security.x509.AlgorithmId
, this exception suggests it was unable to map "AES"
to a suitable OID.
I tried replacing "AES"
with "AES/CBC/PKCS5Padding"
, but that causes the AlgorithmParameters.getInstance()
call to fail with "AES/CBC/PKCS5Padding AlgorithmParameters not available".
I also tried declaring the algorithm explicitlty as 2.16.840.1.101.3.4.1.2, but that also fails with an "AlgorithmParameters not available" error.
As noted in the comments below, this error does not occur in Java 8.
Example Code
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
最佳答案
目前,我求助于 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();
关于java - 如何创建 AES 加密的 PKCS #8 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28210511/