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

标签 java encryption aes rsa pkcs#8

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

相关文章:

java - 从 C# 到 JAVA 的 3DES 加密

iphone - 使用保存数据加密以避免 iPhone 游戏中的作弊

java - 如何从 AES-256 切换到 AES-128?

java - Android Studio 无法解密 AES 中的消息

java - 尝试使用 AES 加密和解密字符串时出现 IllegalBlockSizeException

java - NoSuchBeanDefinitionException 预计至少有 1 个 bean 有资格作为此依赖项的 Autowiring 候选者

java - 如何将 byteArray 转换为位图图像以在 Android 中的 imageview 中显示?

java - 跨 session /设备处理应用内购买/消耗品?

java - SpringAMQP - 如何捕获 ListenerExecutionFailedException?

c# - 使用最广泛的字符串加密 C# 混淆器是什么?