Creating RSA Public Key From String(从字符串创建 RSA 公钥)
问题描述
我使用 1024 RSA 生成了这个测试公钥,然后在另一个编码平台中将其编码为 DER 和 Base64.我将密钥复制到 Android/Eclipse 中的字符串中,并尝试使用 KeyFactory 将其转换为公钥.无论我尝试什么,它都会一直给我一个 InvalidKeySpecException .任何建议都将不胜感激.
I've generated this test public key using 1024 RSA and then encoded it to DER and Base64 in another coding platform. I copied the key into a string in Android/Eclipse and I am trying to turn it into a public key using KeyFactory. It just keeps giving me an InvalidKeySpecException no matter what I try. Any advice at all would be appreciated.
private void prepKeys() {
String AppKeyPub = "MIGHAoGBAOX+TFdFVIKYyCVxWlnbGYbmgkkmHmEv2qStZzAFt6NVqKPLK989Ow0RcqcDTZaZBfO5" +
"5JSVHNIKoqULELruACfqtGoATfgwBp4Owfww8M891gKNSlI/M0yzDQHns5CKwPE01jD6qGZ8/2IZ" +
"OjLJNH6qC9At8iMCbPe9GeXIPFWRAgER";
// create the key factory
try {
KeyFactory kFactory = KeyFactory.getInstance("RSA");
// decode base64 of your key
byte yourKey[] = Base64.decode(AppKeyPub,0);
// generate the public key
X509EncodedKeySpec spec = new X509EncodedKeySpec(yourKey);
PublicKey publicKey = (PublicKey) kFactory.generatePublic(spec);
System.out.println("Public Key: " + publicKey);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
推荐答案
您拥有的密钥是 PKCS#1 格式,而不是 Java 接受的 SubjectPublicKeyInfo 结构.PKCS#1 只是 RSA 参数的编码,缺少诸如算法标识符之类的东西.SubjectPublicKeyInfo 在内部使用 PKCS#1 - 无论如何都用于 RSA 公钥.
The key you have is in PKCS#1 format instead of SubjectPublicKeyInfo structure that Java accepts. PKCS#1 is the encoding of the RSA parameters only and lacks things such as an algorithm identifier. SubjectPublicKeyInfo uses PKCS#1 internally - for RSA public keys anyway.
由于 PKCS#1 公钥位于 SubjectPublicKeyInfo 结构的末尾,因此可以简单地为字节添加前缀,以便它们成为 RSA SubjectPublicKeyInfo.该解决方案更易于执行,无需额外的库,例如 Bouncy Castle.因此,如果您需要不使用外部库,那么您可以查看我的答案此处.
As the PKCS#1 public key is at the end of the SubjectPublicKeyInfo structure it is possible to simply prefix the bytes so that they become an RSA SubjectPublicKeyInfo. That solution is easier to perform without additional libraries such as Bouncy Castle. So if you need to go without an external library then you may have a look at my answer here.
或者,可以编写一个简单的 BER 解码器,将结构解码为两个 BigInteger 值.结构本身并不复杂但BER/DER长度编码需要一些时间来适应.
Alternatively a simple BER decoder could be written to decode the structure into the two BigInteger values. The structure itself is not that complicated but the BER/DER length encoding takes some getting used to.
不过,您也可以使用 Bouncy Castle(轻量级 API)来解决您的问题:
However, you can also use Bouncy Castle (lightweight API) to solve your issues:
String publicKeyB64 = "MIGHAoGBAOX+TFdFVIKYyCVxWlnbGYbmgkkmHmEv2qStZzAFt6NVqKPLK989Ow0RcqcDTZaZBfO5"
+ "5JSVHNIKoqULELruACfqtGoATfgwBp4Owfww8M891gKNSlI/M0yzDQHns5CKwPE01jD6qGZ8/2IZ"
+ "OjLJNH6qC9At8iMCbPe9GeXIPFWRAgER";
// ok, you may need to use the Base64 decoder of bouncy or Android instead
byte[] decoded = Base64.getDecoder().decode(publicKeyB64);
org.bouncycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(decoded);
BigInteger modulus = pkcs1PublicKey.getModulus();
BigInteger publicExponent = pkcs1PublicKey.getPublicExponent();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatedPublic = kf.generatePublic(keySpec);
System.out.printf("Modulus: %X%n", modulus);
System.out.printf("Public exponent: %d ... 17? Why?%n", publicExponent); // 17? OK.
System.out.printf("See, Java class result: %s, is RSAPublicKey: %b%n", generatedPublic.getClass().getName(), generatedPublic instanceof RSAPublicKey);
正如您所见,它实际上只需要一个类作为接口,尽管这当然得到了 Bouncy Castle 中整个 ASN.1/BER 解码器功能的支持.
As you can see it actually only requires a single class as interface, although that is of course backed up with the entire ASN.1/BER decoder functionality within Bouncy Castle.
请注意,可能需要将 Base 64 解码器更改为 Android 特定的一个(android.util.Base64
).此代码已在等效的 Java 运行时测试.
Note that it may be required to change the Base 64 decoder to the Android specific one (android.util.Base64
). This code was tested on an equivalent Java runtime.
这篇关于从字符串创建 RSA 公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从字符串创建 RSA 公钥


- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01