簡體   English   中英

如何創建一個AES加密的PKCS#8文件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM