简体   繁体   English

Azure网站上的数据保护/加密?

[英]Data protection / encryption on Azure websites?

I'm trying to encrypt some data to store in a user cookie from a website deployed on Azure. 我正在尝试加密一些数据以存储在Azure上部署的网站的用户cookie中。

I tried looking at the DataProtection APIs in System.Security but they all seem to need a machine or user scope, which doesn't work when deployed to Azure. 我尝试查看System.Security中的DataProtection API,但它们似乎都需要一个机器或用户范围,这在部署到Azure时不起作用。

Then I tried using the AesCryptoServiceProvider and storing the key in my Web.config, but I get this error: 然后我尝试使用AesCryptoServiceProvider并将密钥存储在我的Web.config中,但是我收到此错误:

CryptographicException: The data protection operation was unsuccessful. CryptographicException:数据保护操作失败。 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. 这可能是由于没有为当前线程的用户上下文加载用户配置文件引起的,这可能是线程模拟时的情况。

I was reading up on the error and apparently you need to tweak an IIS setting, which doesn't work for Azure. 我正在阅读错误,显然你需要调整一个IIS设置,这对Azure不起作用。

I also tried looking at the DataProtection Asp.NET Core package but it brought in a whole lot of new packages and the docs mentioned needing to store crypto information in a local folder; 我也尝试过查看DataProtection Asp.NET Core软件包,但它引入了大量新软件包,并且提到了需要在本地文件夹中存储加密信息的文档。 which again doesn't seem like it would work on Azure without a dedicated machine. 如果没有专用机器,它似乎不会在Azure上运行。

What's the right way to protect/unprotect data on an Azure website? 在Azure网站上保护/取消保护数据的正确方法是什么?

Turns out it was only the DataProtection API that was throwing the error. 事实证明只有DataProtection API才引发错误。 AesManaged and AesCryptoServiceProvider both still work in Azure. AesManagedAesCryptoServiceProvider都可以在Azure中使用。 Here is what I ended up using: 以下是我最终使用的内容:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM