java - InvalidKeySpecException : How do I extract a private key from a . 文件?

标签 java rsa private-key der pkcs#8

我有一个 .der 格式的私钥文件。我试图将此私钥保存为 PrivateKey 对象(使用 Java),如下所示:

PrivateKey clientPrivKey = getPrivateKeyFromKeyFile("C:\\Users\\Bob\\Desktop\\Assignments\\Project\\VPN Project\\src\\client-private.der");

这就是 getPrivateKeyFromKeyFile 方法的样子:

private static PrivateKey getPrivateKeyFromKeyFile(String keyfile) throws Exception
    {
        Path path = Paths.get(keyfile);
        byte[] privKeyByteArray = Files.readAllBytes(path);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyByteArray);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec); 
        return myPrivKey;
    }

但是当我尝试这样做时,由于这行代码,我不断收到 InvalidKeySpecException:

PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);

我不确定这里出了什么问题。我打开私钥文件,一切看起来都很好。它以 -----BEGIN RSA PRIVATE KEY----- 开头,以 -----END RSA PRIVATE KEY----- 结束。

如果相关的话,我使用以下 OpenSSL 命令创建了这个私钥:

genrsa -out client-private.der 2048

最佳答案

生成的文件

openssl genrsa -out <path to output-file> 2048

实际上不是 .der 文件,而是 .pem 文件(例如 What are the differences between .pem, .cer and .der? ),并且数据不存储在 中PKCS8-格式,但采用 PKCS1-格式(参见例如 PKCS#1 and PKCS#8 format for RSA private key )。 无法使用标准 Java 工具直接处理 PKCS1 格式的 key 。为此,需要像 BouncyCaSTLe 这样的第三方库(参见 Read RSA private key of format PKCS1 in JAVA )。

另一种可能性是首先使用 OpenSSL 将 PKCS1 格式的 key 转换为 PKCS8 格式的 key (参见例如 Load a RSA private key in Java (algid parse error, not a sequence) ):

openssl pkcs8 -topk8 -inform PEM -outform PEM -in <path to the input-pkcs1-pem-file> -out <path to the output-pkcs8-pem-file> -nocrypt

然后,在(编程)删除开始/结束行之后以及在进行 base64 解码之后,可以生成私钥(参见例如 How to read .pem file to get private and public key ),例如与

private static PrivateKey getPrivateKeyFromKeyFile(String keyfile) throws Exception
{
    Path path = Paths.get(keyfile);
    byte[] privKeyByteArray = Files.readAllBytes(path);
    // added ----------------------------------------------------------------
    String privKeyString = new String(privKeyByteArray);
    privKeyString = privKeyString.replace("-----BEGIN PRIVATE KEY-----", "");
    privKeyString = privKeyString.replace("-----END PRIVATE KEY-----", "");
    privKeyString = privKeyString.replace("\r\n", "");
    privKeyByteArray = Base64.getDecoder().decode(privKeyString);
    // ----------------------------------------------------------------------
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyByteArray);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec); 
    return myPrivKey;
}

关于java - InvalidKeySpecException : How do I extract a private key from a . 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54168369/

相关文章:

java - ConcurrentHashMap 的迭代

rsa - PKCS11Interop Hash with SHA256 和 Sign with RSA 分两步

c++ - 在 Qt 应用程序中保护私钥

java - 代码通过其接口(interface)类型(例如 Set)而不是其实现类型来引用 Collection

java - 是否可以在不影响记录的情况下判断 java ResultSet 是否为空?

java - Java 中的 RSA 加密/解密

java - 如何在Java中将私钥写入受密码保护的DER格式?

python - 非对称加密 - 明文大小错误

c# - azure 上的 CngKey.Import

java - 如何将输出与java中的字符串进行比较?