以下列格式发送字符串:
-----BEGIN RSA PUBLIC KEY-----
MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY
mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma
XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED
-----END RSA PUBLIC KEY-----
如何从此字符串构造PublicKey对象? 试过以下 删除页眉和页脚,base64解码缓冲区
public static PublicKey getFromString(String keystr) throws Exception
{
//String S1= asciiToHex(keystr);
byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
作为无效密钥格式失败或将失败
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
at PublicKeyReader.getFromString(PublicKeyReader.java:30)
at Tst.main(Tst.java:36)
密钥是通过openSSL PEM_write_bio_RSAPublicKey(bio, rsa);
答案 0 :(得分:9)
通过调用PEM_write_bio_RSAPublicKey
,只将密钥模数和公共指数编码到输出PEM数据中。但是,X509EncodedKeySpec
应该是ASN.1密钥格式:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
您应该使用使用SubjectPublicKeyInfo结构对公钥进行编码的PEM_write_bio_PUBKEY
函数,该结构符合X509EncodedKeySpec
的预期
解码密钥的其他可能解决方案。不幸的是,我不认为只能使用标准JDK API,但可以使用Bouncycastle库来完成
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
public static PublicKey getFromString(String keystr) throws Exception
{
//String S1= asciiToHex(keystr);
byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
ASN1InputStream in = new ASN1InputStream(keyBytes);
DERObject obj = in.readObject();
RSAPublicKeyStructure pStruct = RSAPublicKeyStructure.getInstance(obj);
RSAPublicKeySpec spec = new RSAPublicKeySpec(pStrcut.getModulus(), pStruct.getPublicExponent());
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
答案 1 :(得分:5)
BouncyCastle的PEMReader将为您完成此任务:
String pemKey = "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY\n"
+ "mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma\n"
+ "XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED\n"
+ "-----END RSA PUBLIC KEY-----\n";
PEMReader pemReader = new PEMReader(new StringReader(pemKey));
RSAPublicKey rsaPubKey = (RSAPublicKey) pemReader.readObject();
System.out.println("Public key: "+rsaPubKey);
(请注意,您之前可能需要Security.addProvider(new BouncyCastleProvider());
。)
答案 2 :(得分:0)
更新:极大地简化了流程和代码,感谢@ dave_thompson_085
您可以从您提供的字符串构造一个PublicKey对象,如下所示:
我的解决方案的预先要求:
完整的Java 7+示例:
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import java.io.IOException;
import java.io.StringReader;
import java.security.PublicKey;
public interface PemToDer
{
static void main(String[] args) throws IOException {
createRsaPublicKey(
"-----BEGIN RSA PUBLIC KEY-----\n" +
"MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY\n" +
"mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma\n" +
"XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED\n" +
"-----END RSA PUBLIC KEY-----"
);
}
static PublicKey createRsaPublicKey(String keystr) throws IOException {
try (StringReader reader = new StringReader(keystr);
PEMParser pemParser = new PEMParser(reader)) {
SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) pemParser.readObject();
JcaPEMKeyConverter pemKeyConverter = new JcaPEMKeyConverter();
return pemKeyConverter.getPublicKey(subjectPublicKeyInfo);
}
}
}