【问题标题】:Data protection / encryption on Azure websites?Azure 网站上的数据保护/加密?
【发布时间】:2016-11-23 01:22:49
【问题描述】:

我正在尝试加密一些数据以存储在 Azure 上部署的网站的用户 cookie 中。

我尝试查看 System.Security 中的 DataProtection API,但它们似乎都需要机器或用户范围,这在部署到 Azure 时不起作用。

然后我尝试使用 AesCryptoServiceProvider 并将密钥存储在我的 Web.config 中,但出现此错误:

CryptographicException:数据保护操作是 不成功。这可能是由于没有用户配置文件造成的 为当前线程的用户上下文加载,可能是这种情况 当线程正在模拟时。

我正在阅读该错误,显然您需要调整 IIS 设置,该设置不适用于 Azure。

我还尝试查看 DataProtection Asp.NET Core 包,但它带来了很多新包和提到需要将加密信息存储在本地文件夹中的文档;如果没有专用机器,它似乎也无法在 Azure 上运行。

在 Azure 网站上保护/取消保护数据的正确方法是什么?

【问题讨论】:

  • 你的意思是来保护web.config中的连接字符串吗?
  • @LeiYang 不,我不是在谈论 web.config 中的任何内容。我想保护 VSTS 的 OAuth 访问令牌并将其存储为 cookie。
  • 为什么你认为 web.config 在 IIS 甚至 Azure 中是危险的
  • 我也不太了解这个问题的反对意见。您是否有理由不能直接在代码中使用AESManaged 来加密令牌?如果需要,将密钥存储在您的代码中。
  • @RandomEngy 对于专门将数据加密到 cookie 中,您可以使用与默认表单身份验证相同的方法,例如 FormsAuthentication.Encrypt / FormsAuthentication.Decrypt;这将使用您无法在 web.config 中指定的机器密钥(因此将使用由 azure 生成的机器密钥)或可以在 web.config 中指定,然后您将需要解决加密 web.config 问题(这里我不有什么好的答案)

标签: c# asp.net azure encryption


【解决方案1】:

原来只有 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;
}

【讨论】:

  • 这里无法验证密文。您应该换成使用 GCM 模式或添加 HMAC。
  • @LukePark 就我而言,我不在乎用户是否试图篡改数据。它所能做的就是破坏他们的令牌。虽然如果你想用添加的 GCM 或 HMAC 来回答,我会为你投赞成票。 :)
  • 不。这确实是一个公平的观点。只是觉得您可能会在某个时候使用令牌自己验证用户。
猜你喜欢
  • 2014-05-24
  • 2012-12-13
  • 2013-03-02
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
相关资源
最近更新 更多