2016-11-23 1 views
1

저는 Azure에 배포 된 웹 사이트의 사용자 쿠키에 저장할 데이터를 암호화하려고합니다.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 Core 패키지를 살펴 보았지만 로컬 패키지에 암호화 정보를 저장해야하는 언급이 많은 새 패키지와 문서가 필요했습니다. 이것은 Azure에서 전용 기계 없이는 작동하지 않는 것처럼 보입니다.

Azure 웹 사이트에서 데이터를 보호/보호 해제하는 올바른 방법은 무엇입니까?

+0

web.config에서 연결 문자열을 보호하기 위해서만 ** 사용 하시겠습니까? –

+0

@LeiYang 아니, 나는 web.config에서 아무 것도 말하고 있지 않다. VSTS에서 OAuth 액세스 토큰을 보호하고이를 쿠키로 저장하려고합니다. – RandomEngy

+0

왜 web.config가 ** 위험한 **, IIS 및 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. 그것은 정말로 공정한 점입니다. 그냥 토큰을 사용하여 어느 시점에서 사용자의 유효성을 검사 할 수 있다고 생각했습니다. –

관련 문제