在我的应用程序中,我生成了一个公钥/私钥对并将它们存储在磁盘上供以后使用。加载和重新初始化私钥工作正常,但对于私钥,我得到一个未知的 KeySpec 类型:java.security.spec.PKCS8EncodedKeySpec - 我不知道为什么。
这就是我创建和保存 key 的方式(代码稍微简化以便于阅读):
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);
那我做错了什么?从磁盘加载公钥数据的正确方法是什么?
谢谢!
最佳答案
公钥和私钥的编码方式不同。虽然私钥在 PKCS #8 中编码,但公钥不是。根据 ASN.1 规范,它们以 X.509 编码。
Key.getFormat() 方法的说明:
Returns the name of the primary encoding format of this key, or null if this key does not support encoding. The primary encoding format is named in terms of the appropriate ASN.1 data format, if an ASN.1 specification for this key exists. For example, the name of the ASN.1 data format for public keys is SubjectPublicKeyInfo, as defined by the X.509 standard; in this case, the returned format is "X.509". Similarly, the name of the ASN.1 data format for private keys is PrivateKeyInfo, as defined by the PKCS #8 standard; in this case, the returned format is "PKCS#8".
据此,您不应将公钥读取为 PKCS #8,而应将其读取为 X.509。
考虑更改您的公钥读取代码:
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data);
到:
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(data);
关于java - 从文件加载公钥数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19640735/