如何创建AES加密的PKCS#8文件?

时间:2015-01-29 08:55:58

标签: java encryption aes rsa pkcs#8

我正在尝试使用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

1 个答案:

答案 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();