未能从字节 [] 构造序列:遇到未知标记 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);
这是我的代码:
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);