2011-03-31 96 views
0

建議多一點背景信息: 我是一個Intranet CMS網絡應用程序,我必須使用產品API(基於ASP.NET)的finsihing。由於時間限制和Windows認證問題,我需要另一種方法來確保員工在訪問網站時不需要重新登錄即可查看個性化內容。它的工作方式是,一旦用戶登錄(用戶名/密碼),就會生成存儲新的不同安全上下文值的會話ID,用於顯示個性化內容。所調用的API登錄方法使用用戶名和密碼作爲參數。我認爲下次員工訪問網站時自動登錄的唯一方法是將密碼存儲在已加密的Cookie中,並檢查訪問該網站時的現有密碼,然後使用用戶名和解密密碼調用API登錄方法cookie值。解密時C#加密代碼出錯!

任何其他想法作爲替代歡迎。

嗨, 我使用的是網絡上找到一些代碼來加密和解密的密碼字符串。它加密罰款,但當它調用下面的代碼來解密字符串時,它會拋出錯誤「解密數據的長度無效」我該如何解決?

在此先感謝。

System.Text.Encoding enc = System.Text.Encoding.ASCII; 
      byte[] myByteArray = enc.GetBytes(_pword); 


      SymmetricAlgorithm sa = DES.Create(); 
      MemoryStream msDecrypt = new MemoryStream(myByteArray); 
      CryptoStream csDecrypt = new CryptoStream(msDecrypt, sa.CreateDecryptor(), CryptoStreamMode.Read); 
      byte[] decryptedTextBytes = new Byte[myByteArray.Length]; 
      csDecrypt.Read(decryptedTextBytes, 0, myByteArray.Length); 
      csDecrypt.Close(); 
      msDecrypt.Close(); 

      string decryptedTextString = (new UnicodeEncoding()).GetString(decryptedTextBytes); 

回答

0

其實我已經收到這個錯誤,我花了3天,以找出解決方案。問題在於,您需要解密的機器密鑰需要在您的機器上註冊。

完全瞭解DES加密,它可以通過應用程序密鑰和機器級密鑰進行工作。您得到的錯誤可能是因爲機器密鑰丟失。

0

將用於創建_pword字符串(在加密方法中)的字節與使用GetBytes檢索的字節進行比較。可能你會發現那裏的數據發生了變化。

要存儲加密字節,我認爲你應該使用Convert.ToBase64String和Convert.FromBase64String將加密密碼轉換爲/從一個字符串。

我也沒有看到你設置密鑰和IV的代碼。所以我猜你正在使用不同的密鑰來加密和解密密碼。

如果當前的關鍵屬性爲null, 的GenerateKey方法被調用來 創建一個新的隨機密鑰。如果當前IV屬性爲空,則調用 GenerateIV方法來創建 新的隨機IV。

3

幾件事情在這裏......

  1. 你不應該通常對密碼進行加密。你應該hash他們。

如果您決定繼續加密的道路..

  1. 您正在使用DES算法。這被認爲是不安全的和有缺陷的。我建議看一下AES算法。
  2. 根據您使用的數據量有多少,CryptoStream可能會矯枉過正。
  3. 使用ASCII編碼可能會導致不是ASCII的數據丟失,如西裏爾字母。推薦的解決方法是使用其他的東西,比如UTF8。

下面是一個例子:

string text = "Hello"; 
using (var aes = new AesManaged()) 
{ 
    var bytes = System.Text.Encoding.UTF8.GetBytes(text); 
    byte[] encryptedBytes; 
    using (var encrypt = aes.CreateEncryptor()) 
    { 
     encryptedBytes = encrypt.TransformFinalBlock(bytes, 0, bytes.Length); 
    } 
    byte[] decryptedBytes; 
    using (var decrypt = aes.CreateDecryptor()) 
    { 
     decryptedBytes = decrypt.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); 
    } 
    var decryptedText = System.Text.Encoding.UTF8.GetString(decryptedBytes); 
    Console.Out.WriteLine("decryptedText = {0}", decryptedText); 
} 

這將使用一個隨機密鑰每次。您可能需要加密一些數據,然後再解密。當您創建AesManaged對象時,可以存儲KeyIV屬性。如果您願意,可以重複使用相同的密鑰,但不同的數據應始終使用不同的IV(初始化向量)加密。你存放鑰匙的地方取決於你。這就是爲什麼散列可能是更好的選擇:沒有密鑰,也不需要擔心安全地存儲密鑰。

如果你想下去散列路線,這裏是一個小例子:

var textToHash = "hello"; 
using (SHA1 sha = new SHA1Managed()) 
{ 
    var bytesToHash = System.Text.Encoding.UTF8.GetBytes(textToHash); 
    var hash = sha.ComputeHash(bytesToHash); 
    string base64hash = Convert.ToBase64String(hash); 
} 

這使用SHA1算法,它應該可以正常工作了密碼,但是你可能要考慮SHA256

這個概念很簡單:散列會爲輸入產生(大部分)唯一輸出,但輸出不能轉換回輸入 - 這是破壞性的。無論何時你想檢查一個用戶是否應該被認證,檢查他們給你的密碼,並檢查它是否與正確密碼的散列相對應。這樣你就不會儲存任何敏感的東西。

+0

密碼將用於內部Web應用程序。我想我可能會去哈希路線。任何指向我可以找到例子的地方? – mjakda 2011-03-31 12:35:19

+0

@mjakda:答覆已更新。 – vcsjones 2011-03-31 12:41:26

+0

但是,如果用戶在新訪問中沒有輸入密碼進行比較,那麼哈希算法會起作用嗎? – mjakda 2011-03-31 12:57:47

0

DES是基於塊的密碼 - 只有特定長度的緩衝區纔有效。如果我沒有記錯,DES的塊大小是64位,所以你需要確保你的字節數組是8個字節長的倍數。 (這應該可以解決你的直接問題,但是我會在這裏引用其他人的建議 - 對於任何新代碼,你真的不應該使用DES,而對於密碼,通常更適合散列而不是加密)。