2017-06-26 12 views
1

I持つC#のための弾む城を使用して暗号化された秘密鍵の作成、次の方法:復号化パスフレーズ保護PEM秘密鍵

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----- 

私はドン何を私の解読メソッドで秘密鍵を暗号化するために使用されたパスワードを消費する方法がわかっています。今、彼にpasswordを使って自分の秘密鍵を「解読」する方法を知らなくても、私は次の例外を取得:

Org.BouncyCastle.OpenSsl.PemException:問題ENCRYPTED 秘密鍵の作成:System.NullReferenceException:オブジェクト参照をオブジェクトのインスタンスに を設定しないでください。 でここ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; 
} 
+0

いくつかのタグを追加してタイトルを変更しました(ランタイムの特性を質問本体に移しています)。私はBCの実装をオンラインで見つけることができませんでしたので、これはいくつかの注意を喚起することを願っています: –

答えて

1

あなたがプライベートを復号化する必要があると私には思えますそれを使用するキー。現在、パスワードパラメータは使用されていません。残念ながら、これを行う方法を見つけるのは簡単ではないようです。


他の多くのJava APIと同様に、Bouncy Castleはパスワードハンドラを使用してパスワードを取得します。これを行う理由は、プログラムが必要なときにのみパスワードをユーザに尋ねることができるようにするためです。これにより、プログラムは、パスワードを最短時間メモリに残すことができます。

ので、復号化を可能に次のコンストラクタを使用する:IPasswordFinderの実装と

PemReader(TextReader reader, IPasswordFinder pFinder); 

を(C#のための弾む城は、そうでない場合は、デリゲートは、おそらく使用されていたであろう、主にJavaのポートです)。


お客様の便宜のため、コードです。このコードは、秘密鍵だけでなく、鍵のペア全体も再構成します。

import文:

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; 
} 

必要なヘルパークラス:通常、あなただけchar[]の代わりに01を使用する必要があります

private class PasswordFinder : IPasswordFinder 
{ 
    private string password; 

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


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

注意パスワードの場合は、使用後はクリアすることができます。stringは使用できません。char[]

これで、秘密鍵の復号化が簡単になるはずです。

+0

さらにいくつかのテスト(例えば、 'RsaPrivateCrtKeyParameters'にオブジェクトをキャストする前に、 –

関連する問題