如何用java读取密码加密密钥?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2654949/
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
How to read a password encrypted key with java?
提问by Denis
I have private key stored in file in PKCS8 DER format and protected by password. What is the easiest way to read it?
我将私钥以 PKCS8 DER 格式存储在文件中并受密码保护。什么是最简单的阅读方法?
Here is the code I use to load unencrypted one:
这是我用来加载未加密的代码:
InputStream in = new FileInputStream(privateKeyFilename);
byte[] privateKeydata = new byte[in.available()];
in.read(privateKeydata);
in.close();
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);
It works fine for unencrypted keys with the same specification. By the way, I am using BouncyCastle.
它适用于具有相同规格的未加密密钥。顺便说一下,我正在使用 BouncyCastle。
I can view this private key using following openssl command
我可以使用以下 openssl 命令查看此私钥
openssl pkcs8 -in ./privatekey.key -inform DER -passin pass:thisismypass
Please, Help!!!
请帮忙!!!
I,ve posted some solutions in my own answer to this topic. But I keep question unanswered in case anybody can help with making it work without extra library, just BouncyCastle.
我已经在我自己对这个主题的回答中发布了一些解决方案。但是我一直没有回答这个问题,以防有人可以帮助它在没有额外库的情况下工作,只是 BouncyCastle。
回答by Denis
I found the solution! Maybe its not so elegant, but... Here I will post two solutions:
我找到了解决方案!也许它不是那么优雅,但是......在这里我将发布两个解决方案:
- Prefferable, but not working
- Working one, but requires additional library
- 可取,但不起作用
- 工作一个,但需要额外的库
First:
第一:
I found a kind of solution here, but it throws exception. Solution:
我在这里找到了一种解决方案,但它引发了异常。解决方案:
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
/*
* This class demonstrates how to import an encrypted RSA private key as
* generated by openssl. The input file is presumed to be in DER
* format.
*/
public class ImportEncryptedPrivateKey
{
public static byte[] readPK8FromFile(String fileName) throws IOException
{
File f = new File(fileName);
DataInputStream dis = new DataInputStream(new FileInputStream(f));
byte[] theData = new byte[(int) f.length()];
dis.readFully(theData);
return theData;
}
public static void main(String[] args) throws IOException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeySpecException, InvalidKeyException,
InvalidAlgorithmParameterException
{
byte[] encryptedPKInfo = readPK8FromFile("rsapriv.pk8");
EncryptedPrivateKeyInfo ePKInfo = new EncryptedPrivateKeyInfo(
encryptedPKInfo);
char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
Cipher cipher = Cipher.getInstance(ePKInfo.getAlgName());
PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
// Now create the Key from the PBEKeySpec
SecretKeyFactory skFac = SecretKeyFactory.getInstance(ePKInfo
.getAlgName());
Key pbeKey = skFac.generateSecret(pbeKeySpec);
// Extract the iteration count and the salt
AlgorithmParameters algParams = ePKInfo.getAlgParameters();
cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
// Decrypt the encryped private key into a PKCS8EncodedKeySpec
KeySpec pkcs8KeySpec = ePKInfo.getKeySpec(cipher);
// Now retrieve the RSA Public and private keys by using an
// RSA keyfactory.
KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
// First get the private key
RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) rsaKeyFac.generatePrivate(pkcs8KeySpec);
// Now derive the RSA public key from the private key
RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(rsaPriv.getModulus(), rsaPriv.getPublicExponent());
RSAPublicKey rsaPubKey = (RSAPublicKey) rsaKeyFac.generatePublic(rsaPubKeySpec);
}
}
And my exception:
而我的例外:
Exception in thread "main" java.security.NoSuchAlgorithmException: No such algorithm: 1.2.840.113549.1.5.13
Second:
第二:
And following this http://juliusdavies.ca/commons-ssl/pkcs8.htmlyou can read about the second, working solution
在此http://juliusdavies.ca/commons-ssl/pkcs8.html 之后,您可以阅读有关第二个有效解决方案的信息
回答by Stiopa
This is my code and it work's :)
这是我的代码,它有效:)
File f = new File(keyFile);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(keyBytes);
Cipher cipher = Cipher.getInstance(encryptPKInfo.getAlgName());
PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray());
SecretKeyFactory secFac = SecretKeyFactory.getInstance(encryptPKInfo.getAlgName());
Key pbeKey = secFac.generateSecret(pbeKeySpec);
AlgorithmParameters algParams = encryptPKInfo.getAlgParameters();
cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
KeySpec pkcs8KeySpec = encryptPKInfo.getKeySpec(cipher);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(pkcs8KeySpec);