Java RSA 加密 :InvalidKeyException: 无效的密钥格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3465561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RSA encryption :InvalidKeyException: invalid key format
提问by Prajakta
I have to read pem key files to get RSA Public key,and then use them to encrypt. I can do this using openssl and convert pem file to der file. and then load my key using X509EncodedKeySpec and PKCS8EncodedKeySpec. But I don't want to do this because pem is the user key exchange format. user can register it's own key can like this :
我必须阅读 pem 密钥文件以获取 RSA 公钥,然后使用它们进行加密。我可以使用 openssl 执行此操作并将 pem 文件转换为 der 文件。然后使用 X509EncodedKeySpec 和 PKCS8EncodedKeySpec 加载我的密钥。但我不想这样做,因为 pem 是用户密钥交换格式。用户可以像这样注册自己的密钥:
--BEGIN PUBLIC KEY-- MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGi0/vKrSIIQMOm4atiw+2s8tSojOKHsWJU3oPTm
b1a5UQIH7CM3NgtLvUF5DqhsP2jTqgYSsZSl+W2RtqCFTavZTWvmc0UsuK8tTzvnCXETsnpjeL13
Hul9JIpxZVej7b6KxgyxFAhuz2AGscvCXnepElkVh7oGOqkUKL7gZSD7AgMBAAE=
--END PUBLIC KEY--
and this key is store in a database in this format...
并且此密钥以这种格式存储在数据库中...
Here is the code I have tried..
这是我试过的代码..
File pubKeyFile=new File("D:/public_key.pem");
DataInputStream dis = new DataInputStream(new FileInputStream(pubKeyFile));
byte[] pubKeyBytes = new byte[(int)pubKeyFile.length()];
dis.readFully(pubKeyBytes);
dis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec);
I am getting exception as
我得到了例外
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
As I am completely new to encryption concepts can anyone please help me to solve this exception?
由于我对加密概念完全陌生,有人可以帮我解决这个异常吗?
Many thanks.
非常感谢。
回答by Maurice Perry
With bouncycastle, it would be done this way:
使用bouncycastle,可以这样做:
CertificateFactory cf = CertificateFactory.getInstance("X509", "BC");
InputStream is = new FileInputStream("D:/public_key.pem");
X509Certificate certificate = (X509Certificate) cf.generateCertificate(is);
is.close();
RSAPublicKey pubKey = (RSAPublicKey)certificate.getPublicKey();
回答by erickson
You were almost there, with the standard provider. You just need to strip the header and footer lines:
您就快到了,标准提供商。您只需要去除页眉和页脚行:
List<String> lines = Files.readAllLines(Paths.get(path), StandardCharsets.US_ASCII);
if (lines.size() < 2)
throw new IllegalArgumentException("Insufficient input");
if (!lines.remove(0).startsWith("--"))
throw new IllegalArgumentException("Expected header");
if (!lines.remove(lines.size() - 1).startsWith("--"))
throw new IllegalArgumentException("Expected footer");
byte[] raw = Base64.getDecoder().decode(String.join("", lines));
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(new X509EncodedKeySpec(raw));
回答by manishbhadu
try using bouncycastele's PemReader .
尝试使用 bouncycastele 的 PemReader 。
PublicKey getPublicKey(String pubKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
PemObject pem = new PemReader(new StringReader(pubKeyStr)).readPemObject();
byte[] pubKeyBytes = pem.getContent();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec);
return pubKey;
}