2012-01-27 47 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