2016-11-23 52 views
1

我試圖加密一些數據以存儲在部署在Azure上的網站的用戶cookie中。Azure網站上的數據保護/加密?

我試着在System.Security中查看DataProtection API,但它們似乎都需要一個機器或用戶範圍,這在部署到Azure時不起作用。

然後我嘗試使用AesCryptoServiceProvider和儲存在我的web.config的關鍵,但我得到這個錯誤:

CryptographicException: The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

我的錯誤讀了,顯然你需要調整的IIS設置,這對Azure不起作用。

我也試過看DataProtection Asp.NET核心包,但它帶來了很多新的軟件包和文件提到需要存儲加密信息在本地文件夾;如果沒有專用的機器,它似乎不再適用於Azure。

在Azure網站上保護/取消保護數據的正確方法是什麼?

+0

你的意思是**只**保護web.config中的連接字符串? –

+0

@LeiYang不,我不是在討論web.config中的任何內容。我想保護來自VSTS的OAuth訪問令牌並將其存儲爲cookie。 – RandomEngy

+0

爲什麼你認爲web.config在**,甚至在Azure中都是**危險的? –

回答

0

原來只有DataProtection API拋出錯誤。 AesManagedAesCryptoServiceProvider兩者仍然在Azure中運行。這是我最終使用的:

private const string AesKey = "206283c07cbfda1c0c126ef56d78ba9a0aeb53a06cd65f10bd3a9cb9a68e3fe1"; 

public static byte[] Encrypt(byte[] toEncrypt) 
{ 
    byte[] encrypted; 

    var aes = new AesCryptoServiceProvider(); 
    aes.Key = StringToByteArray(AesKey); 

    // Create a new IV for each item to encrypt 
    aes.GenerateIV(); 
    byte[] iv = aes.IV; 

    using (var encrypter = aes.CreateEncryptor(aes.Key, iv)) 
    using (var cipherStream = new MemoryStream()) 
    { 
     using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) 
     using (var binaryWriter = new BinaryWriter(cryptoStream)) 
     { 
      // Prepend unencrypted IV to data 
      cipherStream.Write(iv, 0, iv.Length); 
      binaryWriter.Write(toEncrypt); 
      cryptoStream.FlushFinalBlock(); 
     } 

     encrypted = cipherStream.ToArray(); 
    } 

    return encrypted; 
} 

public static byte[] EncryptFromString(string toEncrypt) 
{ 
    return Encrypt(Encoding.UTF8.GetBytes(toEncrypt)); 
} 

public static byte[] Decrypt(byte[] toDecrypt) 
{ 
    var aes = new AesCryptoServiceProvider(); 
    aes.Key = StringToByteArray(AesKey); 

    // Pull out the unencrypted IV first 
    byte[] iv = new byte[16]; 
    Array.Copy(toDecrypt, 0, iv, 0, iv.Length); 

    using (var encryptedMemoryStream = new MemoryStream()) 
    { 
     using (var cryptoStream = new CryptoStream(encryptedMemoryStream, aes.CreateDecryptor(aes.Key, iv), CryptoStreamMode.Write)) 
     using (var binaryWriter = new BinaryWriter(cryptoStream)) 
     { 
      // Decrypt Cipher Text from Message 
      binaryWriter.Write(
       toDecrypt, 
       iv.Length, 
       toDecrypt.Length - iv.Length 
      ); 
     } 

     return encryptedMemoryStream.ToArray(); 
    } 
} 

public static string DecryptToString(byte[] toDecrypt) 
{ 
    return Encoding.UTF8.GetString(Decrypt(toDecrypt)); 
} 

public static string ByteArrayToString(byte[] array) 
{ 
    StringBuilder hex = new StringBuilder(array.Length * 2); 
    foreach (byte b in array) 
    { 
     hex.AppendFormat("{0:x2}", b); 
    } 

    return hex.ToString(); 
} 

public static byte[] StringToByteArray(string hex) 
{ 
    int charCount = hex.Length; 
    byte[] bytes = new byte[charCount/2]; 
    for (int i = 0; i < charCount; i += 2) 
    { 
     bytes[i/2] = Convert.ToByte(hex.Substring(i, 2), 16); 
    } 

    return bytes; 
} 
+1

你沒有辦法在這裏驗證密文。您應該交換使用GCM模式或添加HMAC。 –

+0

@LukePark在我的情況下,我不在乎用戶是否試圖篡改數據。它所要做的就是腐蝕它們的標誌。雖然如果你在乎GCM或HMAC的補充,我會投入你的方式。 :) – RandomEngy

+0

Nah。這真是一個公平點。只是認爲你可能會在某個時候使用令牌來驗證用戶。 –