如何用java读取密码加密密钥?

发布于 2024-08-29 04:17:25 字数 762 浏览 8 评论 0原文

我的私钥以 PKCS8 DER 格式存储在文件中,并受密码保护。最简单的阅读方法是什么?

这是我用来加载未加密密钥的代码:

InputStream in = new FileInputStream(privateKeyFilename);
byte[] privateKeydata = new byte[in.available()];
in.read(privateKeydata);
in.close();
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);

对于具有相同规格的未加密密钥,它工作得很好。顺便说一句,我正在使用 BouncyCastle。

我可以使用以下 openssl 命令查看此私钥

openssl pkcs8 -in ./privatekey.key -inform DER -passin pass:thisismypass

请帮忙!!!

我在自己对此主题的回答中发布了一些解决方案。但我没有回答问题,以防有人可以帮助使其在没有额外库(只需 BouncyCastle)的情况下工作。

I have private key stored in file in PKCS8 DER format and protected by password. What is the easiest way to read it?

Here is the code I use to load unencrypted one:

InputStream in = new FileInputStream(privateKeyFilename);
byte[] privateKeydata = new byte[in.available()];
in.read(privateKeydata);
in.close();
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privateKeydata);
PrivateKey privateKey = privateKeyFactory.generatePrivate(encodedKeySpec);

It works fine for unencrypted keys with the same specification. By the way, I am using BouncyCastle.

I can view this private key using following openssl command

openssl pkcs8 -in ./privatekey.key -inform DER -passin pass:thisismypass

Please, Help!!!

I,ve posted some solutions in my own answer to this topic. But I keep question unanswered in case anybody can help with making it work without extra library, just BouncyCastle.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

带上头具痛哭 2024-09-05 04:17:25

我找到了解决方案!也许它不是那么优雅,但是......
在这里我将发布两个解决方案:

  1. 首选,但不起作用
  2. 工作一个,但需要额外的库

第一个

我找到了一种解决方案 这里,但它抛出异常。解决方案:

import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

import javax.crypto.*;
import javax.crypto.spec.*;

/*
 * This class demonstrates how to import an encrypted RSA private key as
 * generated by openssl. The input file is presumed to be in DER
 * format.
 */
public class ImportEncryptedPrivateKey
{
    public static byte[] readPK8FromFile(String fileName) throws IOException
    {
        File f = new File(fileName);
        DataInputStream dis = new DataInputStream(new FileInputStream(f));
        byte[] theData = new byte[(int) f.length()];
        dis.readFully(theData);
        return theData;
    }

    public static void main(String[] args) throws IOException,
            NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeySpecException, InvalidKeyException,
            InvalidAlgorithmParameterException
    {
        byte[] encryptedPKInfo = readPK8FromFile("rsapriv.pk8");
        EncryptedPrivateKeyInfo ePKInfo = new EncryptedPrivateKeyInfo(
                encryptedPKInfo);
        char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
        Cipher cipher = Cipher.getInstance(ePKInfo.getAlgName());
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
        // Now create the Key from the PBEKeySpec
        SecretKeyFactory skFac = SecretKeyFactory.getInstance(ePKInfo
                .getAlgName());
        Key pbeKey = skFac.generateSecret(pbeKeySpec);
        // Extract the iteration count and the salt
        AlgorithmParameters algParams = ePKInfo.getAlgParameters();
        cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
        // Decrypt the encryped private key into a PKCS8EncodedKeySpec
        KeySpec pkcs8KeySpec = ePKInfo.getKeySpec(cipher);
        // Now retrieve the RSA Public and private keys by using an
        // RSA keyfactory.
        KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
        // First get the private key
        RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) rsaKeyFac.generatePrivate(pkcs8KeySpec);
        // Now derive the RSA public key from the private key
        RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(rsaPriv.getModulus(), rsaPriv.getPublicExponent());
        RSAPublicKey rsaPubKey = (RSAPublicKey) rsaKeyFac.generatePublic(rsaPubKeySpec);
    }

}

我的例外:

Exception in thread "main" java.security.NoSuchAlgorithmException: No such algorithm: 1.2.840.113549.1.5.13

第二

按照此http://juliusdavies.ca/commons-ssl/pkcs8.html 您可以阅读第二个可行的解决方案

I found the solution! Maybe its not so elegant, but...
Here I will post two solutions:

  1. Prefferable, but not working
  2. Working one, but requires additional library

First:

I found a kind of solution here, but it throws exception. Solution:

import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

import javax.crypto.*;
import javax.crypto.spec.*;

/*
 * This class demonstrates how to import an encrypted RSA private key as
 * generated by openssl. The input file is presumed to be in DER
 * format.
 */
public class ImportEncryptedPrivateKey
{
    public static byte[] readPK8FromFile(String fileName) throws IOException
    {
        File f = new File(fileName);
        DataInputStream dis = new DataInputStream(new FileInputStream(f));
        byte[] theData = new byte[(int) f.length()];
        dis.readFully(theData);
        return theData;
    }

    public static void main(String[] args) throws IOException,
            NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeySpecException, InvalidKeyException,
            InvalidAlgorithmParameterException
    {
        byte[] encryptedPKInfo = readPK8FromFile("rsapriv.pk8");
        EncryptedPrivateKeyInfo ePKInfo = new EncryptedPrivateKeyInfo(
                encryptedPKInfo);
        char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
        Cipher cipher = Cipher.getInstance(ePKInfo.getAlgName());
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
        // Now create the Key from the PBEKeySpec
        SecretKeyFactory skFac = SecretKeyFactory.getInstance(ePKInfo
                .getAlgName());
        Key pbeKey = skFac.generateSecret(pbeKeySpec);
        // Extract the iteration count and the salt
        AlgorithmParameters algParams = ePKInfo.getAlgParameters();
        cipher.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
        // Decrypt the encryped private key into a PKCS8EncodedKeySpec
        KeySpec pkcs8KeySpec = ePKInfo.getKeySpec(cipher);
        // Now retrieve the RSA Public and private keys by using an
        // RSA keyfactory.
        KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
        // First get the private key
        RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) rsaKeyFac.generatePrivate(pkcs8KeySpec);
        // Now derive the RSA public key from the private key
        RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(rsaPriv.getModulus(), rsaPriv.getPublicExponent());
        RSAPublicKey rsaPubKey = (RSAPublicKey) rsaKeyFac.generatePublic(rsaPubKeySpec);
    }

}

And my exception:

Exception in thread "main" java.security.NoSuchAlgorithmException: No such algorithm: 1.2.840.113549.1.5.13

Second:

And following this http://juliusdavies.ca/commons-ssl/pkcs8.html you can read about the second, working solution

醉殇 2024-09-05 04:17:25

这是我的代码,它可以工作:)

File f = new File(keyFile);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(keyBytes);
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("RSA");
return kf.generatePrivate(pkcs8KeySpec);

This is my code and it work's :)

File f = new File(keyFile);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(keyBytes);
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("RSA");
return kf.generatePrivate(pkcs8KeySpec);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文