未能从字节 [] 构造序列:遇到未知标记 13

failed to construct sequence from byte[]: unknown tag 13 encountered

这是我的代码:

import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.PEMKeyPair;
import java.security.KeyPair;
import java.io.StringReader;
import javax.crypto.Cipher;
import java.util.Base64;
import java.security.interfaces.RSAPrivateKey;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        String key = "-----BEGIN PRIVATE KEY-----\n" +
"MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqPfgaTEWEP3S9w0t\n" +
"gsicURfo+nLW09/0KfOPinhYZ4ouzU+3xC4pSlEp8Ut9FgL0AgqNslNaK34Kq+NZ\n" +
"jO9DAQIDAQABAkAgkuLEHLaqkWhLgNKagSajeobLS3rPT0Agm0f7k55FXVt743hw\n" +
"Ngkp98bMNrzy9AQ1mJGbQZGrpr4c8ZAx3aRNAiEAoxK/MgGeeLui385KJ7ZOYktj\n" +
"hLBNAB69fKwTZFsUNh0CIQEJQRpFCcydunv2bENcN/oBTRw39E8GNv2pIcNxZkcb\n" +
"NQIgbYSzn3Py6AasNj6nEtCfB+i1p3F35TK/87DlPSrmAgkCIQDJLhFoj1gbwRbH\n" +
"/bDRPrtlRUDDx44wHoEhSDRdy77eiQIgE6z/k6I+ChN1LLttwX0galITxmAYrOBh\n" +
"BVl433tgTTQ=\n" +
"-----END PRIVATE KEY-----";

        String ciphertext = "L812/9Y8TSpwErlLR6Bz4J3uR/T5YaqtTtB5jxtD1qazGPI5t15V9drWi58colGOZFeCnGKpCrtQWKk4HWRocQ==";

        // load the private key
        ASN1Sequence ASN1 = ASN1Sequence.getInstance(key.getBytes());
        PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(ASN1);
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        RSAPrivateKey privateKey = (RSAPrivateKey) converter.getPrivateKey(privateKeyInfo);

        // load the ciphertext
        byte[] cipherBytes = Base64.getDecoder().decode(ciphertext);

        // perform the actual decryption
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] plaintextBytes = cipher.doFinal(cipherBytes);
        String plaintext = new String(plaintextBytes);

        System.out.println(plaintext);
    }
}

运行 它给了我以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: failed to construct sequence from byte[]: unknown tag 13 encountered
        at org.bouncycastle.asn1.ASN1Sequence.getInstance(Unknown Source)
        at MyTest.main(Test.java:48)

我不明白。 OpenSSL 的 asn1parse 没有密钥问题:

$ openssl asn1parse -in test.pem
    0:d=0  hl=4 l= 340 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=2 l=  13 cons: SEQUENCE
    9:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   20:d=2  hl=2 l=   0 prim: NULL
   22:d=1  hl=4 l= 318 prim: OCTET STRING      [HEX DUMP]:3082013A020100024100A8F7E069311610FDD2F70D2D82C89C5117E8FA72D6D3DFF429F38F8A7858678A2ECD4FB7C42E294A5129F14B7D1602F4020A8DB2535A2B7E0AABE3598CEF4301020301000102402092E2C41CB6AA91684B80D29A8126A37A86CB4B7ACF4F40209B47FB939E455D5B7BE37870360929F7C6CC36BCF2F4043598919B4191ABA6BE1CF19031DDA44D022100A312BF32019E78BBA2DFCE4A27B64E624B6384B04D001EBD7CAC13645B14361D02210109411A4509CC9DBA7BF66C435C37FA014D1C37F44F0636FDA921C37166471B3502206D84B39F73F2E806AC363EA712D09F07E8B5A77177E532BFF3B0E53D2AE60209022100C92E11688F581BC116C7FDB0D13EBB654540C3C78E301E812148345DCBBEDE89022013ACFF93A23E0A13752CBB6DC17D206A5213C66018ACE061055978DF7B604D34

所以我知道问题是什么。

有什么想法吗?

问题是您获取的是 Base64 字节 String 而不是原始 ASN1 数据。

删除 -----BEGIN PRIVATE KEY----------END PRIVATE KEY----- 行。同时删除所有 \n。然后使用 Base64 解码器解码 PEM 密钥:

String key =
        "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqPfgaTEWEP3S9w0t" +
        "gsicURfo+nLW09/0KfOPinhYZ4ouzU+3xC4pSlEp8Ut9FgL0AgqNslNaK34Kq+NZ" +
        "jO9DAQIDAQABAkAgkuLEHLaqkWhLgNKagSajeobLS3rPT0Agm0f7k55FXVt743hw" +
        "Ngkp98bMNrzy9AQ1mJGbQZGrpr4c8ZAx3aRNAiEAoxK/MgGeeLui385KJ7ZOYktj" +
        "hLBNAB69fKwTZFsUNh0CIQEJQRpFCcydunv2bENcN/oBTRw39E8GNv2pIcNxZkcb" +
        "NQIgbYSzn3Py6AasNj6nEtCfB+i1p3F35TK/87DlPSrmAgkCIQDJLhFoj1gbwRbH" +
        "/bDRPrtlRUDDx44wHoEhSDRdy77eiQIgE6z/k6I+ChN1LLttwX0galITxmAYrOBh" +
        "BVl433tgTTQ=";

byte[] keyBytes = Base64.getDecoder().decode(key);
// load the private key
ASN1Sequence ASN1 = ASN1Sequence.getInstance(keyBytes);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(ASN1);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
RSAPrivateKey privateKey = (RSAPrivateKey) converter.getPrivateKey(privateKeyInfo);

您也可以在解码 Base64 后省略对 ASN1Sequence.getInstance 的调用:

byte[] keyBytes = Base64.getDecoder().decode(key);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(keyBytes);
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
RSAPrivateKey privateKey = (RSAPrivateKey) converter.getPrivateKey(privateKeyInfo);