簡體   English   中英

Java 11 - 橢圓曲線私鑰 - java.security.InvalidKeyException:IOException:DER 輸入,Integer 標簽錯誤

[英]Java 11 - elliptic curve private key - java.security.InvalidKeyException: IOException : DER input, Integer tag error

關於如何在 java 11 中使用橢圓曲線私鑰的小問題。

我有這些命令:

openssl pkcs12 -in file.p12 -out output.txt
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

然后,我可以在 output 上運行 cat:

cat output.txt
Bag Attributes
    friendlyName: 
    localKeyID: 
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MI[...]0=
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
    friendlyName: 
    localKeyID: 
subject=/CN=
issuer=/CN=
-----BEGIN CERTIFICATE-----
MII[...]Z
-----END CERTIFICATE-----

請注意,我使用 [...] 來編輯實際內容。

我只想使用這個私鑰,在-----BEGIN ENCRYPTED PRIVATE KEY----- -----END ENCRYPTED PRIVATE KEY-----塊中的那個

因此,我嘗試了以下操作:我首先刪除了 BEGIN ENCRYPTED PRIVATE、換行符、END ENCRYPTED PRIVATE KEY

        String privateKeyPEM = "MI[...]0="; //the same private key as above
        byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
        EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);
        KeyFactory kf = KeyFactory.getInstance("EC");
        PrivateKey privKey = kf.generatePrivate(privKeySpec);

但是,我收到此錯誤:

aused by: java.security.InvalidKeyException: IOException : DER input, Integer tag error
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350)
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)
    at jdk.crypto.ec/sun.security.ec.ECPrivateKeyImpl.<init>(ECPrivateKeyImpl.java:74)
    at jdk.crypto.ec/sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
    at jdk.crypto.ec/sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)

請問有什么問題嗎? 另外,請問怎么解決?

謝謝

沒有問題,但是您嘗試讀取的(EC)密鑰是加密的 - 純 Java 無法讀取此類密鑰。

您可以編寫大量代碼來解析和解密密鑰,或者使用 Bouncy Castle 為您完成這項工作。

將此行添加到程序的頂部:

Security.addProvider(new BouncyCastleProvider());

然后使用這個 function,其中 String s 采用包括“--開始--/結束字符串”的加密密鑰:

static public PrivateKey stringToPrivateKey(String s, String password)
        throws IOException, PKCSException {
    PrivateKeyInfo pki;
    try (PEMParser pemParser = new PEMParser(new StringReader(s))) {
        Object o = pemParser.readObject();
        if (o instanceof PKCS8EncryptedPrivateKeyInfo) { // encrypted private key in pkcs8-format
            System.out.println("key in pkcs8 encoding");
            PKCS8EncryptedPrivateKeyInfo epki = (PKCS8EncryptedPrivateKeyInfo) o;
            System.out.println("epki:" + epki.getEncryptionAlgorithm().getAlgorithm());
            JcePKCSPBEInputDecryptorProviderBuilder builder =
                    new JcePKCSPBEInputDecryptorProviderBuilder().setProvider("BC");
            InputDecryptorProvider idp = builder.build(password.toCharArray());
            pki = epki.decryptPrivateKeyInfo(idp);
        } else if (o instanceof PEMEncryptedKeyPair) { // encrypted private key in pkcs8-format
            System.out.println("key in pkcs1 encoding");
            PEMEncryptedKeyPair epki = (PEMEncryptedKeyPair) o;
            PEMKeyPair pkp = epki.decryptKeyPair(new BcPEMDecryptorProvider(password.toCharArray()));
            pki = pkp.getPrivateKeyInfo();
        } else if (o instanceof PEMKeyPair) { // unencrypted private key
            System.out.println("key unencrypted");
            PEMKeyPair pkp = (PEMKeyPair) o;
            pki = pkp.getPrivateKeyInfo();
        } else {
            throw new PKCSException("Invalid encrypted private key class: " + o.getClass().getName());
        }
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        return converter.getPrivateKey(pki);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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