【问题标题】:How to generate a RSA keyPair with a Privatekey encrypted with password?如何使用用密码加密的私钥生成 RSA 密钥对?
【发布时间】:2014-09-29 15:25:31
【问题描述】:

我想生成一个用密码加密的私钥 PKCS8 格式,我尝试使用以下代码:

String password = "123456";
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048);
KeyPair key = gen.generateKeyPair();
PrivateKey privateKey = key.getPrivate();
PublicKey publicKey = key.getPublic();

FileOutputStream pvt = new FileOutputStream("d:\\pvt123456.der");
try {
    pvt.write(privateKey.getEncoded());
    pvt.flush();
} finally {
    pvt.close();
}
FileOutputStream pub = new FileOutputStream("d:\\pub123456.der");
try {
    pub.write(publicKey.getEncoded());
    pub.flush();
} finally {
    pub.close();
}

但我不知道如何使用 3des 加密密码以兼容 openssl 格式。

【问题讨论】:

    标签: java openssl bouncycastle private-key


    【解决方案1】:

    我知道这有点晚了,但我也一直在寻找一种方法来做到这一点,在我搜索时我发现了你的问题,现在我找到了一种方法来做到这一点,我决定回来分享这个:

    // generate key pair
    
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.genKeyPair();
    
    // extract the encoded private key, this is an unencrypted PKCS#8 private key
    byte[] encodedprivkey = keyPair.getPrivate().getEncoded();
    
    // We must use a PasswordBasedEncryption algorithm in order to encrypt the private key, you may use any common algorithm supported by openssl, you can check them in the openssl documentation http://www.openssl.org/docs/apps/pkcs8.html
    String MYPBEALG = "PBEWithSHA1AndDESede";
    String password = "pleaseChangeit!";
    
    int count = 20;// hash iteration count
    SecureRandom random = new SecureRandom();
    byte[] salt = new byte[8];
    random.nextBytes(salt);
    
    // Create PBE parameter set
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
    PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
    SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);
    SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
    
    Cipher pbeCipher = Cipher.getInstance(MYPBEALG);
    
    // Initialize PBE Cipher with key and parameters
    pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
    
    // Encrypt the encoded Private Key with the PBE key
    byte[] ciphertext = pbeCipher.doFinal(encodedprivkey);
    
    // Now construct  PKCS #8 EncryptedPrivateKeyInfo object
    AlgorithmParameters algparms = AlgorithmParameters.getInstance(MYPBEALG);
    algparms.init(pbeParamSpec);
    EncryptedPrivateKeyInfo encinfo = new EncryptedPrivateKeyInfo(algparms, ciphertext);
    
    // and here we have it! a DER encoded PKCS#8 encrypted key!
    byte[] encryptedPkcs8 = encinfo.getEncoded();
    

    此示例代码基于我找到的以下代码:http://www.jensign.com/JavaScience/PEM/EncPrivKeyInfo/EncPrivKeyInfo.java

    但以下资源也帮助我更好地理解了一点:http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html

    【讨论】: