1

これまでに見つけたアイテムの多くは、少しあいまいであったり、具体的でなかったりしたので、答えを得たいと思っています。

私は2つの小さな方法を持っています - そのように見える簡単なもの...

    private const string initVector = "1234567890123456";
    private const string SaltValue = "ThisIsMySaltValue";
    private const int KeySize = 256;

    public static string Encrypt(string textToEncrypt)
    {
        var rijndael = new RijndaelManaged {KeySize = KeySize};
        var salt = SaltValue.ToByteArray();
        var vector = initVector.ToByteArray();

        var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
        var key = rfcBytes.GetBytes(rijndael.KeySize/8);

        ICryptoTransform encrypt = rijndael.CreateEncryptor(key, vector);

        var stream = new MemoryStream();
        var data = Encoding.ASCII.GetBytes(textToEncrypt);
        stream.Write(data, 0, data.Length);

        var cryptoStream = new CryptoStream(stream, encrypt, CryptoStreamMode.Write);
        cryptoStream.Write(data, 0, data.Length);
        cryptoStream.FlushFinalBlock();

        cryptoStream.Close();
        return Convert.ToBase64String(stream.ToArray());
    }


    public static string Decrypt(string textToDecrypt)
    {
        var vector = initVector.ToByteArray();
        var salt = SaltValue.ToByteArray();
        var encrypted = textToDecrypt.ToByteArray();

        var rijndael = new RijndaelManaged {KeySize = KeySize};

        var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
        var key = rfcBytes.GetBytes(rijndael.KeySize/8);

        var decrypt = rijndael.CreateDecryptor(key, vector);

        var stream = new MemoryStream(encrypted);
        var cryptoStream = new CryptoStream(stream, decrypt, CryptoStreamMode.Read);

        byte[] plainBytes = new byte[textToDecrypt.Length];

        var decryptedLength = cryptoStream.Read(plainBytes, 0, plainBytes.Length);

        var plainText = Encoding.UTF8.GetString(plainBytes, 0, decryptedLength);
        return plainText;
    }

単体テストはこんな感じ…

    [Test]
    public void JustTestingThisOut()
    {
        var encryptMe = "SomethingToEncrypt";
        string result = encryptMe.ConvertToEncrypted();
        result.ShouldNotEqual(encryptMe);
        string backToReadAble = result.ConvertToDecrpted();
        backToReadAble.ShouldEqual(encryptMe);
    }

ToByteArray は単に return Encoding.UTF8.GetBytes(toByte); を行います。私のテスト文字列は単純です-「SomethingToEncrypt」。私は、違いがないように見える問題 (Convert.ToBase64String および Convert.FromBase64String) である可能性があるこの考えを見つけるといううさぎの穴を掘り下げました。エラーについては...

TestCase 'Tests.Encryption.EncryptionUnitTests.JustTestingThisOut' が失敗しました: System.Security.Cryptography.CryptographicException: 復号化するデータの長さが無効です。System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (Byte[] inputBuffer、Int32 inputOffset、Int32 inputCount) で

私はそこに FlushFinalBlock() を持っていて、それができると思っていましたが、...いいえ、同様に違いはありません。何か案は?試してみることはありますか?

4

3 に答える 3

0

コードに断続的なバグが潜んでいます...

暗号文にはSystem.Text.Encodingクラスを使用しないでください。断続的なエラーが発生します。Base64エンコーディングとSystem.Convertクラスメソッドを使用する必要があります。

  1. 暗号化されたbyte[]から暗号化された文字列を取得するには、次を使用する必要があります。

Convert.ToBase64String(byte[] bytes)

  1. 暗号化する文字列からrawbyte[]を取得するには、次を使用する必要があります。

Convert.FromBase64String(string data)

もう1つの注意点はFlushFinalBlock()、暗号化を行うときに必要になることです。そうしないと、正しくパディングされません。

詳細については、MSSecurityの第一人者であるShawnFanningの投稿(http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx )を参照してください。

于 2011-12-30T18:56:13.927 に答える
0

jerileyが示唆するように、これがどのように機能するかわかりません。復号化関数で行うためです

var encrypted = textToDecrypt.ToByteArray();

ここで、textToDecrypt は base64 文字列です。最初に base64 を通常のバイトに変換し、それを使用して復号化する必要があります。

于 2009-11-04T19:11:24.297 に答える
0

暗号化するときは、最初に に書き込みdatastream次に でラップstreamして、今度は暗号化を使用して再度CryptoStream書き込みます。dataなんで?最初に遭遇するのは暗号化されていないデータであるため、復号化は失敗します。

これを確認するために、base64 エンコードのに暗号文の値を出力します。平文に続いて、暗号文である gobbledygook が表示されるはずです。

また、初期化ベクトルをパスワードとして使用しています。それらは間違いなく同じものではなく、このように使用するとセキュリティが損なわれます。

于 2009-11-04T16:30:40.173 に答える