2012-01-27 234 views
17

我在找一个非常简单的加密/解密方法。我将始终使用相同的静态键。我意识到这种方法的风险。目前我正在使用下面的代码,但在加密和描述相同的字符串(字符串中间有一些垃圾)之后它不会生成相同的结果。用C#和SymmetricAlgorithm加密非常简单

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

我可以改变什么是必要的,没有限制(但我想只是对方法隐窝和另一个没有它们之间共享变量解密)。

谢谢。

+0

要么垫你的数据加密的块大小的倍数或使用流算法代替一个块算法。 – 2012-01-27 10:01:23

回答

35

如果您不想自己处理密钥,请让操作系统为您处理。例如。使用Windows Data Protection(DPAPI)。

您可以通过使用像写自己,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))); 
} 
+3

我喜欢当框架做你的一切。谢谢 – 2012-01-29 09:35:46

+25

请注意,不能在任何其他计算机上或在同一台计算机上使用不同的配置文件解密已加密的字符串。只适用于非常本地存储的东西。 – 2013-02-01 13:33:37

+3

@JonathanDeMarks,基础类库** DO **的最新版本允许** CurrentUser **以及** LocalMachine **对其进行加密/解密。加密的签名如下:'public static byte [] Protect(byte [] userData,byte [] optionalEntropy,DataProtectionScope scope)'where scope'可以是'DataProtectionScope.CurrentUser'或'DataProtectionScope.LocalMachine' – 2014-06-04 12:54:53

6

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

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

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

+0

无论如何,我得到了损坏的字符串的开始。 – 2012-01-27 10:11:04

+0

+1。另一种方法是仅仅返回(然后使用)原始字节而不是字符串,但是无论哪种方式,问题是'Encoding.Unicode.GetString'将会捕获和“修复”加密字节不是有效的UTF-16,这破坏了计划。 – 2012-01-27 10:13:39

+0

Greeeeeeeat。现在,它的工作,谢谢!(当你需要处理那些你不明白的东西而你不想理解的东西时很难;)再次感谢。 – 2012-01-27 10:24:21

-2

重写方法Crypt和Decrypt检索字节数组输入参数。 检查正确加密和解​​密的字节。

18

这样的事情呢?

代码

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

编辑:

为了澄清:我知道这是不是咕d练习。

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

Iv'e做出的假设OP也意识到在使用这样的事,然后才考虑将相关的代码更改一个生产环境。

该问题强调简单而非良好的做法。

+1

IV应该是随机的并且与消息一起存储。 – CodesInChaos 2012-01-27 10:39:53

+0

在应用程序中有一个静态键是不好的 – poupou 2012-01-27 13:46:46

+0

服务它的目的,我的小项目就好了,谢谢:) – JARRRRG 2014-05-21 05:27:34