Java.security - 如何将 KeyPair 密钥存储在字符串中。我收到无效的 DER 编码异常
Java.security - how to store KeyPair keys in a String. I get Invalid DER encoding exceptions
生成密钥对,使用字节数组进行编码和解码工作正常。
我想将私钥和 public 密钥都存储为字符串。这是出于实验目的。我想研究如何存储在使用前必须解码的密码。
我使用 string.getBytes() 和 new String( bytes) 将字节数组转换为字符串和 vv。
当我尝试使用字符串存储和检索这些字节数组时,使用它们对秘密文本进行编码,然后出现此异常:
Exception in thread "main" java.security.spec.InvalidKeySpecException:
java.security.InvalidKeyException: IOException: ObjectIdentifier() --
Invalid DER encoding, not ended
答案中包含解决方案,感谢 James K Polk。
谢谢@James K Polk!!这真的帮助我完成了我的实验!当你post一个答案我会"V"和“+1”那个答案!
根据James K Polk的回答,我重写了实验例子:
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class KeyPairToString {
private static final String ALGORITHM = "RSA";
private static byte[] encrypt(byte[] publicKey, byte[] inputData) throws Exception {
PublicKey key = KeyFactory.getInstance(ALGORITHM) /* ExceptionL Invalid DER encoding */
.generatePublic(new X509EncodedKeySpec(publicKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(inputData);
}
private static byte[] decrypt(byte[] privateKey, byte[] inputData) throws Exception {
PrivateKey key = KeyFactory.getInstance(ALGORITHM)
.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(inputData);
}
private static KeyPair generateKeyPair()
throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(512, random);
return keyGen.generateKeyPair();
}
private static String bytesToString(byte[] bytes) {
return new String(bytes);
}
private static byte[] stringToBytes(String astring) {
return astring.getBytes();
}
private static String bytesToEncodedString(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
private static byte[] encodedStringToBytes(String encodedString) {
return Base64.getDecoder().decode(encodedString);
}
public static void main(String[] args) throws Exception {
KeyPair generateKeyPair = generateKeyPair();
byte[] publicKey = generateKeyPair.getPublic().getEncoded();
byte[] privateKey = generateKeyPair.getPrivate().getEncoded();
// Byte array
String secretText = "hi this is secret johan here";
byte[] encryptedData = encrypt(publicKey, secretText.getBytes());
byte[] decryptedData = decrypt(privateKey, encryptedData);
System.out.println(new String(decryptedData));
// Now with Strings
String encodedPublicKeyString = bytesToEncodedString(publicKey);
String encodedPrivateKeyString = bytesToEncodedString(privateKey);
String encryptedDataString = bytesToEncodedString(
encrypt(encodedStringToBytes(encodedPublicKeyString), stringToBytes(secretText)));
String decryptedDataString = bytesToString(
decrypt(
encodedStringToBytes(encodedPrivateKeyString),
encodedStringToBytes(encryptedDataString)));
System.out.println(new String(decryptedDataString));
}
}
生成密钥对,使用字节数组进行编码和解码工作正常。
我想将私钥和 public 密钥都存储为字符串。这是出于实验目的。我想研究如何存储在使用前必须解码的密码。
我使用 string.getBytes() 和 new String( bytes) 将字节数组转换为字符串和 vv。
当我尝试使用字符串存储和检索这些字节数组时,使用它们对秘密文本进行编码,然后出现此异常:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- Invalid DER encoding, not ended
答案中包含解决方案,感谢 James K Polk。
谢谢@James K Polk!!这真的帮助我完成了我的实验!当你post一个答案我会"V"和“+1”那个答案!
根据James K Polk的回答,我重写了实验例子:
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class KeyPairToString {
private static final String ALGORITHM = "RSA";
private static byte[] encrypt(byte[] publicKey, byte[] inputData) throws Exception {
PublicKey key = KeyFactory.getInstance(ALGORITHM) /* ExceptionL Invalid DER encoding */
.generatePublic(new X509EncodedKeySpec(publicKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(inputData);
}
private static byte[] decrypt(byte[] privateKey, byte[] inputData) throws Exception {
PrivateKey key = KeyFactory.getInstance(ALGORITHM)
.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(inputData);
}
private static KeyPair generateKeyPair()
throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(512, random);
return keyGen.generateKeyPair();
}
private static String bytesToString(byte[] bytes) {
return new String(bytes);
}
private static byte[] stringToBytes(String astring) {
return astring.getBytes();
}
private static String bytesToEncodedString(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
private static byte[] encodedStringToBytes(String encodedString) {
return Base64.getDecoder().decode(encodedString);
}
public static void main(String[] args) throws Exception {
KeyPair generateKeyPair = generateKeyPair();
byte[] publicKey = generateKeyPair.getPublic().getEncoded();
byte[] privateKey = generateKeyPair.getPrivate().getEncoded();
// Byte array
String secretText = "hi this is secret johan here";
byte[] encryptedData = encrypt(publicKey, secretText.getBytes());
byte[] decryptedData = decrypt(privateKey, encryptedData);
System.out.println(new String(decryptedData));
// Now with Strings
String encodedPublicKeyString = bytesToEncodedString(publicKey);
String encodedPrivateKeyString = bytesToEncodedString(privateKey);
String encryptedDataString = bytesToEncodedString(
encrypt(encodedStringToBytes(encodedPublicKeyString), stringToBytes(secretText)));
String decryptedDataString = bytesToString(
decrypt(
encodedStringToBytes(encodedPrivateKeyString),
encodedStringToBytes(encryptedDataString)));
System.out.println(new String(decryptedDataString));
}
}