[英]How to create an AES-encrypted PKCS #8 file?
我正在嘗試使用標准Java庫用AES密鑰加密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)
深入研究sun.security.x509.AlgorithmId
的代碼 ,此異常表明它無法將"AES"
映射到合適的OID。
我嘗試將"AES"
替換為"AES/CBC/PKCS5Padding"
,但這會導致AlgorithmParameters.getInstance()
調用失敗,並顯示“ AES / CBC / PKCS5Padding AlgorithmParameters not available ”。
我還嘗試將算法顯式聲明為2.16.840.1.101.3.4.1.2 ,但這也因“ AlgorithmParameters not available ”錯誤而失敗。
如以下注釋中所述 ,在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
暫時,我不得不使用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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.