Java:写入和读取基于密码的加密私钥
我试图从文件中读取基于密码的加密私钥,但遇到以下异常:Java:写入和读取基于密码的加密私钥,java,encryption,private-key,Java,Encryption,Private Key,我试图从文件中读取基于密码的加密私钥,但遇到以下异常: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. at sun.security.util.DerInputStream.getLength(DerInputStream.java:561) at sun.security.util.DerValue.init(DerValue.java:365) at sun.security.util.Der
java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.util.DerInputStream.getLength(DerInputStream.java:561)
at sun.security.util.DerValue.init(DerValue.java:365)
at sun.security.util.DerValue.<init>(DerValue.java:294)
at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:84) ...
。。。这就是我试图读取加密私钥的方式:
public static void savePrivateKeyToDisk(PrivateKey privateKey, String passord){
try {
// unencrypted PKCS#8 private key
byte[] encodedPrivateKey = privateKey.getEncoded();
String MYPBEALG = "PBEWithSHA1AndDESede";
int count = 20;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[8];
random.nextBytes(salt);
// Create PBE parameter set
PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
Cipher pbeCipher = Cipher.getInstance(MYPBEALG);
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Encrypt the encoded Private Key with the PBE key
byte[] cipherText = pbeCipher.doFinal(encodedPrivateKey);
// Now construct PKCS #8 EncryptedPrivateKeyInfo object
AlgorithmParameters algparms = AlgorithmParameters.getInstance(MYPBEALG);
algparms.init(pbeParamSpec);
EncryptedPrivateKeyInfo encinfo = new EncryptedPrivateKeyInfo(algparms, cipherText);
// DER encoded PKCS#8 encrypted key
byte[] encryptedPkcs8 = encinfo.getEncoded();
File encryptedPrivate = new File(PRIVATE_KEY_FILE);
if (encryptedPrivate.getParentFile() != null) {
encryptedPrivate.getParentFile().mkdirs();
}
encryptedPrivate.createNewFile();
ObjectOutputStream publicKeyOS = new ObjectOutputStream(
new FileOutputStream(encryptedPrivate));
publicKeyOS.writeObject(encryptedPkcs8);
publicKeyOS.close();
}
catch (Exception e){
e.printStackTrace();
}
}
public static PrivateKey getPrivateKey(String passwd){
try {
byte[] encodedPrivateKey = getFileBytes(PRIVATE_KEY_FILE);
// exception thrown from here
EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(encodedPrivateKey);
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(ALGORITHM);
return kf.generatePrivate(pkcs8KeySpec);
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
。。。getFileBytes方法:
private static byte[] getFileBytes(String infile){
File f = new File(infile) ;
int sizecontent = ((int) f.length());
byte[] data = new byte[sizecontent];
try
{
FileInputStream freader = new FileInputStream(f);
freader.read(data, 0, sizecontent) ;
freader.close();
return data;
}
catch(IOException ioe)
{
System.out.println(ioe.toString());
return null;
}
}
似乎加密的私钥的格式不正确,但我将其保存为DER PKCS#8格式。
所以,问题是:这段代码有什么错误?我想问题是你写了一个
对象,但是你读了字节[]
(不是对象
)
我建议您要么读取整个对象,然后获取所需的字节,要么最好直接写入byte[]
(不要使用ObjectOutputStream
),然后加载这些字节,例如:
FileOutputStream fos = new FileOutputStream(PRIVATE_KEY_FILE);
fos.write(myByteArray);
fos.close();
然后检索它:
byte[] bytes = Files.readAllBytes(Paths.get(PRIVATE_KEY_FILE));
我想问题是你写了一个对象
,但是你读了字节[]
(不是对象
)
我建议您要么读取整个对象,然后获取所需的字节,要么最好直接写入byte[]
(不要使用ObjectOutputStream
),然后加载这些字节,例如:
FileOutputStream fos = new FileOutputStream(PRIVATE_KEY_FILE);
fos.write(myByteArray);
fos.close();
然后检索它:
byte[] bytes = Files.readAllBytes(Paths.get(PRIVATE_KEY_FILE));
非对称加密不适用于加密大于其密钥大小的数据。非对称加密不适用于加密大于其密钥大小的数据。构造函数EncryptedPrivateKeyInfo
仍会引发异常,即java.io.IOException:DerValue.getOctetString,不是八位字节字符串:3
。现在我正在编写FileOutputStream fos=newfileoutputstream(PRIVATE\u KEY\u文件);fos.write(加密PKCS8);fos.close()
和readingbyte[]bytes=Files.readAllBytes(path.get(PRIVATE_KEY_FILE));EncryptedPrivateKeyInfo encryptPKInfo=新的EncryptedPrivateKeyInfo(字节)
方法DerValue.getOctetString
需要一个八位字符串标记,但它得到一个位字符串标记。构造函数EncryptedPrivateKeyInfo
仍然抛出异常,即java.io.IOException:DerValue.getOctetString,而不是八位字符串:3
。现在我正在编写FileOutputStream fos=newfileoutputstream(PRIVATE\u KEY\u文件);fos.write(加密PKCS8);fos.close()
和readingbyte[]bytes=Files.readAllBytes(path.get(PRIVATE_KEY_FILE));EncryptedPrivateKeyInfo encryptPKInfo=新的EncryptedPrivateKeyInfo(字节)
方法DerValue.getOctetString
需要一个八位字符串标记,但它得到一个位字符串标记。