InvalidKeyException:在 Java 中从 PEM 文件读取 EC 私钥时密钥格式无效 [英] InvalidKeyException: invalid key format when reading EC Private Key from PEM file in Java

查看:194
本文介绍了InvalidKeyException:在 Java 中从 PEM 文件读取 EC 私钥时密钥格式无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从给定的 .pem 文件创建一个私钥对象.该文件具有以下结构:

I'm trying to create a private key object from a given .pem file. The file has this structure:

-----BEGIN EC PRIVATE KEY-----
...............................
...............................
...............................
-----END EC PRIVATE KEY-----

我正在尝试使用以下代码创建私钥对象:

I am attempting to create the private key object with this code:

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;

运行此方法后,我收到此错误:

Upon running this method, I receive this error:

java.security.InvalidKeyException: invalid key format

我能够解析文本并去除任何不需要的字符就好了,但我无法创建私钥对象.我能够使用非常相似的方法从类似的 .crt 文件生成一个公钥对象.我希望能够仅在 Java 中执行此操作,而无需使用 openssl.任何帮助将不胜感激.

I am able to parse the text and strip away any unwanted characters just fine, but I'm not able to create the private key object. I am able to generate a public key object from a similar .crt file using very similar methods. I want to be able to do this solely within Java and no openssl. Any help would be greatly appreciated.

推荐答案

您的代码未正确解码 base64 数据:

Your code does not properly decode the base64 data:

privateKeyPEM 包含 BEGINEND 数据(base64 编码)之间的字符串数据.

privateKeyPEM contains the String data between the BEGIN and END data (which is base64 encoded).

您的代码执行以下操作:

Your code does the following:

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 编码,然后在下一行对其进行解码 - 这两个步骤放在一起都没有用.

Why are you encoding the data base64 and then in the next line decoding it - both steps together are just useless.

您真正需要的是将 base64 解码一次应用于 privateKeyPEM:

What you really need is to apply the base64 decode one time onto privateKeyPEM:

byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);

如果 base64 解码失败,则您的 base64 数据无效 - 很可能是因为包含空格或 \r.

If the base64 decode fails then your base64 data is invalid - most likely because of contained spaces or \r.

这篇关于InvalidKeyException:在 Java 中从 PEM 文件读取 EC 私钥时密钥格式无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆