36

非常に単純な暗号化/復号化方法を探しています。常に同じ静的キーを使用します。私はこのアプローチのリスクを認識しています。現在、私は次のコードを使用していますが、同じ文字列を暗号化および復号化した後、同じ結果を生成しません (文字列の途中にゴミがあります)。

public static string Crypt(this string text)
{
    string result = null;

    if (!String.IsNullOrEmpty(text))
    {
        byte[] plaintextBytes = Encoding.Unicode.GetBytes(text);

        SymmetricAlgorithm symmetricAlgorithm = DES.Create();
        symmetricAlgorithm.Key = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};
        using (MemoryStream memoryStream = new MemoryStream())
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cryptoStream.Write(plaintextBytes, 0, plaintextBytes.Length);
            }

            result = Encoding.Unicode.GetString(memoryStream.ToArray());
        }
    }

    return result;
}

public static string Decrypt(this string text)
{
    string result = null;

    if (!String.IsNullOrEmpty(text))
    {
        byte[] encryptedBytes = Encoding.Unicode.GetBytes(text);

        SymmetricAlgorithm symmetricAlgorithm = DES.Create();
        symmetricAlgorithm.Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        using (MemoryStream memoryStream = new MemoryStream(encryptedBytes))
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateDecryptor(), CryptoStreamMode.Read))
            {
                byte[] decryptedBytes = new byte[encryptedBytes.Length];
                cryptoStream.Read(decryptedBytes, 0, decryptedBytes.Length);
                result = Encoding.Unicode.GetString(decryptedBytes);
            }
        }
    }

    return result;
}

必要なものは何でも変更できますが、制限はありません(ただし、変数を共有せずに暗号化する方法と別の方法で復号化する方法が必要です)。

ありがとう。

4

3 に答える 3

66

キーを自分で処理したくない場合は、オペレーティング システムに任せてください。たとえば、Windows データ保護(DPAPI) を使用します。

string次のようなものを使用して、独自のバージョンのSystem.Security.Cryptography.ProtectedData.ProtectおよびUnprotectメソッドを作成できます。

public static string Crypt (this string text)
{
    return Convert.ToBase64String (
        ProtectedData.Protect (
            Encoding.Unicode.GetBytes (text) ) );
}

public static string Decrypt (this string text)
{
    return Encoding.Unicode.GetString (
        ProtectedData.Unprotect (
             Convert.FromBase64String (text) ) );
}
于 2012-01-27T13:54:00.113 に答える
55

このようなものはどうですか?

コード

using System;
using System.Security.Cryptography;
using System.Text;

public static class StringUtil
{
    private static byte[] key = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};
    private static byte[] iv = new byte[8] {1, 2, 3, 4, 5, 6, 7, 8};

    public static string Crypt(this string text)
    {
        SymmetricAlgorithm algorithm = DES.Create();
        ICryptoTransform transform = algorithm.CreateEncryptor(key, iv);
        byte[] inputbuffer = Encoding.Unicode.GetBytes(text);
        byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
        return Convert.ToBase64String(outputBuffer);
    }

    public static string Decrypt(this string text)
    {
        SymmetricAlgorithm algorithm = DES.Create();
        ICryptoTransform transform = algorithm.CreateDecryptor(key, iv);
        byte[] inputbuffer = Convert.FromBase64String(text);
        byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
        return Encoding.Unicode.GetString(outputBuffer);
    }
}

単体テスト

[Test]
public void Test()
{
    string expected = "this is my test string";
    string a = expected.Crypt();
    Debug.WriteLine(a);
    string actual = a.Decrypt();
    Assert.AreEqual(expected, actual);
}

編集:

明確にするために:これは良い習慣ではないことを認識しています。

「私はこのアプローチのリスクを認識しています。」

私は、OPも認識しており、本番環境でこのようなものを使用することを検討する前に、関連するコードの変更を行うと仮定しました。

この質問は、優れた実践よりも単純さを強調しています。

于 2012-01-27T10:27:20.597 に答える
11

暗号モードを CipherMode.ECB に設定するか、IV を使用する必要があります。

SymmetricAlgorithm symmetricAlgorithm = DES.Create();
symmetricAlgorithm.Key = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
symmetricAlgorithm.Mode = CipherMode.ECB;
...

もう 1 つのポイントは、Unicode エンコーディングを使用しないことです。代わりに Base64 を使用してください。Unicode は、UTF-16 ではないバイトを「破棄」する可能性があります。

于 2012-01-27T10:03:38.407 に答える