【问题标题】:Java 11 - elliptic curve private key - java.security.InvalidKeyException: IOException : DER input, Integer tag errorJava 11 - 椭圆曲线私钥 - java.security.InvalidKeyException:IOException:DER 输入,整数标记错误
【发布时间】:2022-01-09 18:40:00
【问题描述】:

关于如何在 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:

然后,我可以在输出上运行 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)

请问有什么问题吗? 另外,请问怎么解决?

谢谢

【问题讨论】:

    标签: java encryption elliptic-curve


    【解决方案1】:

    没有问题,但是您尝试读取的 (EC) 密钥是加密的 - 纯 Java 无法读取此类密钥。

    您可以编写大量代码来解析和解密密钥,或者使用 Bouncy Castle 为您完成这项工作。

    将此行添加到程序的顶部:

    Security.addProvider(new BouncyCastleProvider());
    

    然后使用这个函数,其中 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);
        }
    }
    

    【讨论】:

    • 确实,非常感谢@Michael!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 2020-03-04
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多