2012-03-12 46 views
2

我只是需要一些建議在這裏。我需要保護一些列數據,所以我一直在使用Google搜索C#4.0/Sql server 2008(不是R2)。C#4.0/Sql Server 2008:業務層加密/解密

這可能是我所需要的:

"When the data must be protected from sysadmins. Practically, in this scenario it would be best not to use SQL Server internal encryption and far better to rely exclusively on the middle tier to perform encryption and decryption. It would be very difficult to protect your data from a determined sysadmin if your keys are stored in SQL Server." Source: msdn

什麼是正確的做法?

我試圖將使用Rijndael加密的數據保存到數據庫。

我得到錯誤:Length of the data to decrypt is invalid

我還沒有這一派還。

我應該繼續與此結合還是應該嘗試用CLR或什麼來解決這個問題? 我只是找不到教程,告訴我如何在業務層中加密/解密。

有什麼建議嗎?

謝謝

編輯:

確定這是我到目前爲止所。 數據用Rinjdael加密,如前所示。 它存儲在列

TestCrypt (varbinary(255), null) 

我看起來像這樣在數據庫中:

0xF6CA99F5B6BFA1D9A0BD2381177E049E02F381078966195B68A54A5BEC4C 

它與一個SP檢索,如:

SELECT cast(s.TestCrypt AS varbinary) AS TestCrypt 

而在數據訪問層:

while (reader.Read()) 
{ 
    data.TestCrypt = (byte[])reader["TestCrypt"]; 
} 

誤差在DecryptStringFromBytes在這行

plaintext = srDecrypt.ReadToEnd(); 

錯誤發現:數據的長度來解密是無效的。

+0

如果您發佈加密/解密代碼,那麼也許我們可以用錯誤的幫助。這應該不是非常困難。 – Paddy 2012-03-12 10:04:59

回答

0

由於使用業務層加密和解密遠,我更喜歡使用以下加密和解密方法:

#region Encryption Decription 
public class CryptorEngine 
{ 
/// <summary> 
/// Encrypt a string using dual encryption method. Return a encrypted cipher Text 
/// </summary> 
/// <param name="toEncrypt">string to be encrypted</param> 
/// <param name="useHashing">use hashing? send to for extra security</param> 
/// <returns></returns> 
public static string Encrypt(string toEncrypt, bool useHashing) 
{ 
    try 
    { 
     byte[] keyArray; 
     byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); 

     System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); 
     // Get the key from config file 
     string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); 
     //System.Windows.Forms.MessageBox.Show(key); 
     if (useHashing) 
     { 
      MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
      keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); 
      hashmd5.Clear(); 
     } 
     else 
      keyArray = UTF8Encoding.UTF8.GetBytes(key); 

     TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 
     tdes.Key = keyArray; 
     tdes.Mode = CipherMode.ECB; 
     tdes.Padding = PaddingMode.PKCS7; 

     ICryptoTransform cTransform = tdes.CreateEncryptor(); 
     byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
     tdes.Clear(); 
     return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    } 
    catch (Exception ex) 
    { 
     return "Invalid"; 
    } 
} 
/// <summary> 
/// DeCrypt a string using dual encryption method. Return a DeCrypted clear string 
/// </summary> 
/// <param name="cipherString">encrypted string</param> 
/// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param> 
/// <returns></returns> 
public static string Decrypt(string cipherString, bool useHashing) 
{ 
    try 
    { 
     if (string.IsNullOrEmpty(cipherString)) 
      return ""; 
     byte[] keyArray; 
     byte[] toEncryptArray = Convert.FromBase64String(cipherString); 

     System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); 
     //Get your key from config file to open the lock! 
     string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); 

     if (useHashing) 
     { 
      MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
      keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); 
      hashmd5.Clear(); 
     } 
     else 
      keyArray = UTF8Encoding.UTF8.GetBytes(key); 

     TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 
     tdes.Key = keyArray; 
     tdes.Mode = CipherMode.ECB; 
     tdes.Padding = PaddingMode.PKCS7; 

     ICryptoTransform cTransform = tdes.CreateDecryptor(); 
     byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 

     tdes.Clear(); 
     return UTF8Encoding.UTF8.GetString(resultArray); 
    } 
    catch (Exception ex) 
    { 
     return "Invalid"; 
    } 
} 
} 
#endregion 
+0

是的,但是你可以返回任何東西,例如Invalid或InCorrecrt從excepton塊...... ... – 2012-03-12 10:34:30

+0

(刪除原來的評論添加)如何甚至與MS編譯器編譯? catch(Exception ex){}' - 如果引發異常,函數永遠不會返回定義的值。我不認爲'try/catch {do nothing}'(或'return String.Empty')在這裏是有效的:讓* an *異常轉義會好得多,以免有人使用像'parameters.AddWithValue (「@OldValue」,CryptorEngine.Encrypt(oldValue))' - 如果在加密過程中出現問題,您將存儲一個空值。這可能不是你想要的。 – 2012-03-12 10:36:28

+0

是的,我曾經從異常塊返回「無效」的字符串,所以,每當我使用這種加密/解密方法,我用來檢查返回值.... – 2012-03-12 10:39:53

0

使用您喜歡的任何加密提供程序在.net中加密數據,並將其存儲在列的數據類型爲VARBINARY,長度正確。

其餘數據與其他所有數據一樣。

0
SELECT cast(s.TestCrypt AS varbinary) AS TestCrypt 

那行truncates the value of TestCrypt to 30 bytes

When n is not specified in a data definition or variable declaration statement, the default length is 1. When nis not specified with the CAST function, the default length is 30.

嘗試:

SELECT cast(s.TestCrypt AS varbinary(255)) AS TestCrypt 
+0

謝謝。現在我又遇到了一個Im掙扎的錯誤: 填充無效,無法刪除。 – 2012-03-13 08:37:55

+0

@CliffSmith http://stackoverflow.com/questions/604210/padding-is-invalid-and-cannot-be-removed-using-aesmanaged – 2012-03-13 10:01:30

+0

謝謝ta.speot。 – 2012-03-13 11:47:38