InvalidKeyException:从 Java 中的 PEM 文件读取 EC 私钥时密钥格式无效
InvalidKeyException: invalid key format when reading EC Private Key from PEM file in Java
我正在尝试从给定的 .pem 文件创建私钥对象。该文件具有以下结构:
-----BEGIN EC PRIVATE KEY-----
...............................
...............................
...............................
-----END EC PRIVATE KEY-----
我正在尝试使用以下代码创建私钥对象:
public static String getKeyFromFile(String filename) throws IOException {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String key = new String(keyBytes);
return key;
}
public static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, NoSuchProviderException {
String privateKeyPEM = getKeyFromFile("MY_FILE.pem");
privateKeyPEM = privateKeyPEM.replace("-----BEGIN EC PRIVATE KEY-----\n", "");
privateKeyPEM = privateKeyPEM.replace("-----END EC PRIVATE KEY-----", "");
privateKeyPEM = privateKeyPEM.replaceAll("\n", "");
privateKeyPEM = privateKeyPEM.replaceAll(" ", "");
byte[] privateKeyBytes = privateKeyPEM.getBytes();
String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
byte[] decodedString = Base64.getDecoder().decode(encodedString);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(decodedString);
KeyFactory kf = KeyFactory.getInstance("EC");
PrivateKey privKey = kf.generatePrivate(privKeySpec);
return privKey;
使用运行这个方法,我收到这个错误:
java.security.InvalidKeyException: invalid key format
我能够很好地解析文本并删除任何不需要的字符,但我无法创建私钥对象。我能够使用非常相似的方法从相似的 .crt 文件生成一个 public 关键对象。我希望能够仅在 Java 内并且没有 openssl 来执行此操作。任何帮助将不胜感激。
您的代码没有正确解码 base64 数据:
privateKeyPEM
包含 BEGIN
和 END
数据之间的字符串数据(base64 编码)。
您的代码执行以下操作:
byte[] privateKeyBytes = privateKeyPEM.getBytes();
// privateKeyBytes now contains the base64 encoded key data
String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
// encoded String contains now the base64 encoded data of the base64 encoded key data
byte[] decodedString = Base64.getDecoder().decode(encodedString);
// decodedString is not the base64 encoded data of your key data
为什么要对数据库进行 base64 编码,然后在下一行对其进行解码 - 两个步骤加在一起都是无用的。
您真正需要的是对 privateKeyPEM 进行一次 base64 解码:
byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);
如果 base64 解码失败,则您的 base64 数据无效 - 很可能是因为包含空格或 \r
.
我正在尝试从给定的 .pem 文件创建私钥对象。该文件具有以下结构:
-----BEGIN EC PRIVATE KEY-----
...............................
...............................
...............................
-----END EC PRIVATE KEY-----
我正在尝试使用以下代码创建私钥对象:
public static String getKeyFromFile(String filename) throws IOException {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String key = new String(keyBytes);
return key;
}
public static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, NoSuchProviderException {
String privateKeyPEM = getKeyFromFile("MY_FILE.pem");
privateKeyPEM = privateKeyPEM.replace("-----BEGIN EC PRIVATE KEY-----\n", "");
privateKeyPEM = privateKeyPEM.replace("-----END EC PRIVATE KEY-----", "");
privateKeyPEM = privateKeyPEM.replaceAll("\n", "");
privateKeyPEM = privateKeyPEM.replaceAll(" ", "");
byte[] privateKeyBytes = privateKeyPEM.getBytes();
String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
byte[] decodedString = Base64.getDecoder().decode(encodedString);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(decodedString);
KeyFactory kf = KeyFactory.getInstance("EC");
PrivateKey privKey = kf.generatePrivate(privKeySpec);
return privKey;
使用运行这个方法,我收到这个错误:
java.security.InvalidKeyException: invalid key format
我能够很好地解析文本并删除任何不需要的字符,但我无法创建私钥对象。我能够使用非常相似的方法从相似的 .crt 文件生成一个 public 关键对象。我希望能够仅在 Java 内并且没有 openssl 来执行此操作。任何帮助将不胜感激。
您的代码没有正确解码 base64 数据:
privateKeyPEM
包含 BEGIN
和 END
数据之间的字符串数据(base64 编码)。
您的代码执行以下操作:
byte[] privateKeyBytes = privateKeyPEM.getBytes();
// privateKeyBytes now contains the base64 encoded key data
String encodedString = Base64.getEncoder().encodeToString(privateKeyBytes);
// encoded String contains now the base64 encoded data of the base64 encoded key data
byte[] decodedString = Base64.getDecoder().decode(encodedString);
// decodedString is not the base64 encoded data of your key data
为什么要对数据库进行 base64 编码,然后在下一行对其进行解码 - 两个步骤加在一起都是无用的。
您真正需要的是对 privateKeyPEM 进行一次 base64 解码:
byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);
如果 base64 解码失败,则您的 base64 数据无效 - 很可能是因为包含空格或 \r
.