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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 00:59:51  来源:igfitidea点击:

RSA encryption :InvalidKeyException: invalid key format

javaencryption

提问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;
}