如何在Java中向现有私钥添加密码

如何在Java中向现有私钥添加密码,java,security,encryption,openssl,rsa,Java,Security,Encryption,Openssl,Rsa,假设我有一个以前使用openssl创建的私钥,但我决定不使用密码短语保护它: -----BEGIN RSA PRIVATE KEY----- BASE64 ENCODED DATA -----END RSA PRIVATE KEY----- 但后来我意识到我想保护它 我知道如何使用openssl来保护它,但我需要用Java来保护它。是否可能?首先从pem文件中加载并提取pkcs#1未加密密钥 String pem = new String(Files.readAllBytes(Paths.ge

假设我有一个以前使用openssl创建的私钥,但我决定不使用密码短语保护它:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
但后来我意识到我想保护它


我知道如何使用openssl来保护它,但我需要用Java来保护它。是否可能?

首先从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);
然后使用的第二部分对密钥进行加密(我已经包括了它)

使用以下代码进行解密(从中提取)


谢谢,但是------BEGIN RSA PRIVATE KEY------头是指pkcs8格式还是pkcs1格式?如何将私钥解密回来?@EvgeniyMishutin我添加了一个示例来解码加密的pkcs8key@pedrofb,我现在就试试看,如果答案行得通,我就接受。@VikramSinghShekhawat,openssl可以解密PKCS#1和PKCS#8格式的私钥。如果您有Java生成的密钥(PKCS#8),则可以使用
openssl pkcs8
命令提供二进制数据(DER)或PEM格式。看见
 // 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();
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);
}