使用 C# 和 SymmetricAlgorithm 进行非常简单的加密

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9031537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:41:08  来源:igfitidea点击:

Really simple encryption with C# and SymmetricAlgorithm

c#encryptionencryption-symmetricdes

提问by Ignacio Soler Garcia

I'm looking for a verysimple crypt / decrypt method. I will be using always the same static key. I'm aware of the risks of this approach. Currently I'm using the following code but it does not generate the same result after crypting and decripting the same string (there is some garbage in the middle of the string).

我正在寻找一种非常简单的加密/解密方法。我将始终使用相同的静态密钥。我知道这种方法的风险。目前我正在使用以下代码,但在加密和解密相同的字符串后它不会生成相同的结果(字符串中间有一些垃圾)。

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

I can change whatever is needed, no limits (but I want just to have on method to crypt and another one to decrypt without sharing variables between them).

我可以改变任何需要的东西,没有限制(但我只想拥有一种加密方法和另一种解密方法,而无需在它们之间共享变量)。

Thanks.

谢谢。

采纳答案by poupou

If you don't want to handle keys yourself then let the operating system do it for your. E.g. use Windows Data Protection(DPAPI).

如果您不想自己处理密钥,那么让操作系统为您处理。例如,使用Windows 数据保护(DPAPI)。

You can write your own, string-based, version of System.Security.Cryptography.ProtectedData.Protectand Unprotectmethods by using something like:

您可以使用以下内容编写自己的string基于版本的System.Security.Cryptography.ProtectedData.ProtectUnprotect方法:

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

public static string Derypt (this string text)
{
    return Encoding.Unicode.GetString (
        ProtectedData.Unprotect (
             Convert.FromBase64String (text) ) );
}

回答by Sani Singh Huttunen

You'll need to set the cipher mode to CipherMode.ECB or use an IV.

您需要将密码模式设置为 CipherMode.ECB 或使用 IV。

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

Another point is not to use Unicode encoding. Use Base64 instead. Unicode might "destroy" bytes that are not UTF-16.

还有一点是不要使用Unicode编码。请改用 Base64。Unicode 可能会“销毁”非 UTF-16 的字节。

回答by Sam Greenhalgh

How about something like this?

这样的事情怎么样?

Code

代码

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

Unit Test

单元测试

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


EDIT:

编辑:

To clarify: I am aware this is not good practice.

澄清一下:我知道这不是好的做法。

"I'm aware of the risks of this approach. "

“我知道这种方法的风险。”

Iv'e made the assumption that the OP is also aware and will make relevant code changes before considering using anything like this in a production environment.

我假设 OP 也知道并且会在考虑在生产环境中使用任何类似的东西之前进行相关的代码更改。

The question emphasizes simplicity over good practice.

这个问题强调简单而不是良好的实践。