【问题标题】:How to add a password to an existing private key in Java如何将密码添加到 Java 中的现有私钥
【发布时间】:2017-05-02 00:20:38
【问题描述】:

假设我之前使用 openssl 创建了一个私钥,但我决定不使用密码保护它:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

但后来我意识到我想保护它。

我知道如何使用 openssl 保护它,但我需要在 Java 中进行。有可能吗?

【问题讨论】:

    标签: java security encryption openssl rsa


    【解决方案1】:

    首先从 pem 文件中加载并提取 pkcs#1 未加密密钥

    String pem = new String(Files.readAllBytes(Paths.get("rsa.key")));
    String privateKeyPEM = pem.replace(
            "-----BEGIN RSA PRIVATE KEY-----\n", "")
                 .replace("-----END RSA PRIVATE KEY-----", "");
     byte[] encodedPrivateKey = Base64.getDecoder().decode(privateKeyPEM);
    

    然后使用this code的第二部分加密密钥(我已经包含了它)

     // 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(encodedPrivateKey);
    
    // 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();
    

    使用以下代码解密(摘自here

    public static PrivateKey getPrivateKey(byte[]   encryptedPkcs8, String passwd) throws Exception{
    
            EncryptedPrivateKeyInfo encryptPKInfo = new EncryptedPrivateKeyInfo(encryptedPkcs8);
    
            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(ALGORITHM);
            return kf.generatePrivate(pkcs8KeySpec);
    }
    

    【讨论】:

    • 谢谢,但是 -----BEGIN RSA PRIVATE KEY----- 标头是指 pkcs8 还是 pkcs1 格式?
    • 你如何解密你的私钥?
    • @EvgeniyMishutin 我添加了一个示例来解码 pkcs8 加密密钥
    • @pedrofb,我现在就试一试,如果可行,请接受答案。
    • @VikramSinghShekhawat,openssl 可以解密 PKCS#1 和 PKCS#8 格式的私钥。如果您有 Java 生成的密钥 (PKCS # 8),则可以使用提供二进制数据 (DER) 或 PEM 格式的 openssl pkcs8 命令。见openssl.cs.utah.edu/docs/apps/pkcs8.html
    猜你喜欢
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多