从文件加载公钥数据

在我的应用程序中,我生成一个公钥/私钥对,并将其存储起来,以便以后在磁盘上使用。 加载和重新初始化私钥工作正常,但对于私钥我得到一个未知的KeySpectypes:java.security.spec.PKCS8EncodedKeySpec – 我不知道为什么。

这就是我创build和保存密钥的方法(代码有点简化,以便于阅读):

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(4096); KeyPair keyPair = kpg.generateKeyPair(); privKey =keyPair.getPrivate(); pubKey =keyPair.getPublic(); DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PRIVKEY_FILE,Context.MODE_PRIVATE)); byte[] data=privKey.getEncoded(); out.write(data); out.close(); DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PUBKEY_FILE,Context.MODE_PRIVATE)); byte[] data=pubKey.getEncoded(); out.write(data); out.close(); 

下一次加载的私钥工作正常:

 DataInputStream in=new DataInputStream(ctx.openFileInput(PRIVKEY_FILE)); byte[] data=new byte[in.available()]; in.readFully(data); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); KeyFactory kf = KeyFactory.getInstance("RSA"); privKey = kf.generatePrivate(keySpec); decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); decryptCipher.init(Cipher.DECRYPT_MODE, privKey); 

类似的公钥的代码失败了:

 DataInputStream in=new DataInputStream(ctx.openFileInput(PUBKEY_FILE)); byte[] data=new byte[in.available()]; in.readFully(data); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); KeyFactory kf = KeyFactory.getInstance("RSA"); pubKey = kf.generatePublic(keySpec); --> here the exception is thrown encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); encryptCipher.init(Cipher.ENCRYPT_MODE, pubKey); 

那么我做错了什么? 从磁盘加载公钥数据的正确方法是什么?

谢谢!

Solutions Collecting From Web of "从文件加载公钥数据"

公钥和私钥的编码方式不同。 私钥在PKCS#8中编码,而公钥则不是。 根据ASN.1规范,它们被编码在X.509中。

来自Key.getFormat()方法的描述:

返回此密钥的主编码格式的名称,如果此密钥不支持编码,则返回null。 如果存在该密钥的ASN.1规范,主要编码格式将根据相应的ASN.1数据格式命名。 例如,公钥的ASN.1数据格式的名称是SubjectPublicKeyInfo,由X.509标准定义; 在这种情况下,返回的格式是“X.509”。 同样,私钥的ASN.1数据格式的名称是PrivateKeyInfo,由PKCS#8标准定义; 在这种情况下,返回的格式是“PKCS#8”。

据此,不要将公钥读作PKCS#8,而应该将其读为X.509。

考虑改变你的公钥阅读代码:

 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); 

至:

 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(data);