无法分析Java中的RSA公钥



我使用以下代码块解析任何要加密的RSA公钥。

static byte[] encrypt(byte[] publicKey, byte[] inputData) throws Exception {
PublicKey key = KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(inputData);
return encryptedBytes;
}
public static String getEncrypted(String data, String key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(key);
return new String(Base64.getEncoder().encode(encrypt(keyBytes, data.getBytes())));
}

但对于以下RSA公钥

MIIBCgKCAQEAs6YyGDXibkazM7QSeFBXjkAn5A8P87k+nuU6v5+zLJiD1KwkZ/SYnLwVSluOx19AzPHj07abDTJtthKtKpp2997UiV4CNUSzkZM1Eorf1+iLFhqeOiz9J5tYfFkKN5qPzwoPK4aFz35hQi7R1ORF9rFDPL+Ex79Tc+ABQF/CH5tn/NTXCNUYzLezg2Y1VOZGNhxd2LIv/29ZDxpJS8dD34H20HMMZCMGGolTXUIxVKI3cR0d1XzNCvAx3jcSkEUEPPH0lfusXqQOfCxJSIjorAzi5ucaWicvXYq6BNGulPqLoGBZnJ4HrFQF0oq1SU4i60VHqOgoiqMPQ+8cyjFBHQIDAQAB

解析时,我得到以下异常

Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.x509.X509Key.decode(X509Key.java:397)
at sun.security.x509.X509Key.decode(X509Key.java:402)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:86)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)

任何失败的地方以及如何生成通用RSA公钥解析代码的想法。

您的问题与InvalidKeySpecException中的问题类似:algid解析错误,不是序列,但不相同。就像PKCS8是(几乎(任何算法中私钥的通用格式一样,Java通过包含识别算法算法特定数据的AlgorithmIdentifier,使用X.509/PKIX为公钥定义的通用格式SubjectPublicKeyInfo(SPKI(,Java称之为X509EncodedKeySpec,其中包含AlgId和算法特定数据。(请参阅java.security.Key的javadoc;由于某种原因,我目前无法访问docs.oracle.com以获取链接。(您只有PKCS1 RSAPublicKey定义的算法特定数据。

您可以使用BouncyCastle"手动"解析并使用它,也可以将它转换为SPKI并使用它。或者(给定BC或另一个ASN.1库(,您可以使用与#31941413中相同的方法,除了省略Integer版本(0(并将数据包装在DERBitString中而不是DERBoctetString中,或者如果我使用X.509或PKCS#1,我在RSA中显示的更简单、更直接的方法。

请注意,这不是"通用"。您的格式与通用算法相反,如前所述,通用算法是SPKI和PCKS8的目的。它也不是通用的;除其他外,OpenSSH、PGP、Microsoft、PKCS11、JWK和XML都使用与此不同的公钥格式,并且不容易与Java兼容。

您的公钥(这里只是Base64编码的部分(似乎是"RSA公钥"而不是"公钥"。后者是Java能够使用的格式。

要读取"RSA公钥",您需要Bouncy Castle库和额外的7行代码。由于你有一个没有"换行"页眉和页脚的键,我将两者相加手动划线。

请记住,以下代码没有适当的异常处理,仅用于教育目的

结果:

key: Sun RSA public key, 2048 bits
params: null
modulus: 22678610734153400983507431374302231631648011897672768754638644005690558018788055145838420912495825001883497816406549666369767766949853573723573636289962789479998547620264293389522975840594912755684410510779642046063268111520844008640320545114702934792800828432077361704284837605938354936920018742130341245366517474980128047515437565419306561322350155414838564407700303406271838590880852369997316303577351737008942081641382006211591786506015023574950120763293965668830106827392978781367691242570394862298000041087969687942746452359360224223895623579995775734139473237799095359767270215802792812274542667250920043135261
public exponent: 65537

代码:

import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import java.io.IOException;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
public class MainSO {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
System.out.println("https://stackoverflow.com/questions/63454577/failed-to-parse-rsa-publickey-in-java");
Security.addProvider(new BouncyCastleProvider());
String rsaPublicKeyHeader = "-----BEGIN RSA PUBLIC KEY-----n";
String rsaPublicKeyFooter = "n-----END RSA PUBLIC KEY-----";
String rsaPublicKeyString = "MIIBCgKCAQEAs6YyGDXibkazM7QSeFBXjkAn5A8P87k+nuU6v5+zLJiD1KwkZ/SYnLwVSluOx19AzPHj07abDTJtthKtKpp2997UiV4CNUSzkZM1Eorf1+iLFhqeOiz9J5tYfFkKN5qPzwoPK4aFz35hQi7R1ORF9rFDPL+Ex79Tc+ABQF/CH5tn/NTXCNUYzLezg2Y1VOZGNhxd2LIv/29ZDxpJS8dD34H20HMMZCMGGolTXUIxVKI3cR0d1XzNCvAx3jcSkEUEPPH0lfusXqQOfCxJSIjorAzi5ucaWicvXYq6BNGulPqLoGBZnJ4HrFQF0oq1SU4i60VHqOgoiqMPQ+8cyjFBHQIDAQAB";
PEMParser pemParser = new PEMParser(new StringReader(rsaPublicKeyHeader +
rsaPublicKeyString + rsaPublicKeyFooter));
SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) pemParser.readObject();
byte[] publicKey = subjectPublicKeyInfo.getEncoded();
// original code starts here
PublicKey key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey));
// check key
System.out.println("key: " + key);
}
}

相关内容

  • 没有找到相关文章

最新更新