解密包含私钥的受密码保护的PEM [英] Decrypt passphrase protected PEM containing private key

查看:230
本文介绍了解密包含私钥的受密码保护的PEM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下方法,该方法使用Bouncy Castle for C#创建加密的私钥:

I have the following method that creates an Encrypted Private Key using Bouncy Castle for C#:

public string GetPrivateKey(AsymmetricCipherKeyPair keyPair, string password)
{
    var generator = new Pkcs8Generator(keyPair.Private, Pkcs8Generator.PbeSha1_3DES);
    generator.IterationCount = 4;
    generator.Password = password.ToCharArray();
    var pem = generator.Generate();

    TextWriter textWriter = new StringWriter();
    PemWriter pemWriter = new PemWriter(textWriter);
    pemWriter.WriteObject(pem);
    pemWriter.Writer.Flush();
    string privateKey = textWriter.ToString();
    return privateKey;
}

看起来像这样:

-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

我不知道如何使用用于加密私钥的密码我的解密方法。现在,在不知道如何使用他的密码解密我的私钥时,我得到了以下异常:

What I don't know is how to consume the password used to encrypt the private key in my Decrypt method. Right now, without knowing how to "decrypt" my private key using he password, I get the following Exception:


Org.BouncyCastle.OpenSsl.PemException:创建ENCRYPTED
私钥时出现问题:System.NullReferenceException:对象引用未将
设置为对象的实例。在
处Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)

Org.BouncyCastle.OpenSsl.PemException : problem creating ENCRYPTED private key: System.NullReferenceException: Object reference not set to an instance of an object. at Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)

以下是代码解密方法:

public string Decrypt(string base64Input, string privateKey, string password)
{
    var bytesToDecrypt = Convert.FromBase64String(base64Input);

    //get a stream from the string
    AsymmetricCipherKeyPair keyPair;
    var decryptEngine = new Pkcs1Encoding(new RsaEngine());

    using (var txtreader = new StringReader(privateKey))
    {
        var obj = new PemReader(txtreader).ReadObject();
        keyPair = (AsymmetricCipherKeyPair) obj;

        decryptEngine.Init(false, keyPair.Private);
    }

    var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
    return decrypted;
}


推荐答案

在我看来,您需要解密私钥才能使用它。目前,您的密码参数尚未使用。不幸的是,要做到这一点似乎并不那么容易。

It seems to me that you need to decrypt the private key to use it. Currently your password parameter isn't used. Unfortunately it doesn't seem to be all that easy to find out how do this.

Bouncy Castle,还有许多其他景点Java API,使用密码处理程序来检索密码。这样做的原因是允许程序仅在需要时才询问用户密码。这样可以使程序在最短的时间内将密码保留在内存中。

Bouncy Castle, as many other Java API's, use a password handler to retrieve the password. The reason to do this is to allow the program to ask the user for the password only when it is required. This allows the program to leave the password in memory for the shortest amount of time.

因此,为了进行解密,请使用以下构造函数:

So to allow for decryption, use the following constructor:

PemReader(TextReader reader, IPasswordFinder pFinder);

使用 IPasswordFinder 的实现(Bouncy Castle因为C#主要是Java端口,否则可能会使用委托。)

with an implementation of IPasswordFinder (Bouncy Castle for C# is mainly a Java port, otherwise a delegate would probably have been used).

为方便起见,代码。这段代码还重构了整个密钥对,而不仅仅是私有密钥。

For your convenience, the code. This code also reconstructs the entire key pair, not just the private key.

导入语句:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.IO;

解码器:

private static AsymmetricCipherKeyPair DecodePrivateKey(string encryptedPrivateKey, string password)
{
    TextReader textReader = new StringReader(encryptedPrivateKey);
    PemReader pemReader = new PemReader(textReader, new PasswordFinder(password));
    object privateKeyObject = pemReader.ReadObject();
    RsaPrivateCrtKeyParameters rsaPrivatekey = (RsaPrivateCrtKeyParameters)privateKeyObject;
    RsaKeyParameters rsaPublicKey = new RsaKeyParameters(false, rsaPrivatekey.Modulus, rsaPrivatekey.PublicExponent);
    AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(rsaPublicKey, rsaPrivatekey);
    return kp;
}

所需的帮助类:

private class PasswordFinder : IPasswordFinder
{
    private string password;

    public PasswordFinder(string password)
    {
        this.password = password;
    }


    public char[] GetPassword()
    {
        return password.ToCharArray();
    }
}






请注意,通常对于密码,您只应使用 char [] 而不是 string 作为 char [ ] 使用后可以清除,而 string 无法清除。


Note that normally you should only use char[] instead of string for passwords as char[] can be cleared after use, while string cannot.

现在,私钥解密应该很容易。

Now you have the private key decryption should be easy.

这篇关于解密包含私钥的受密码保护的PEM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆