【问题标题】:Best way to store an AES-encrypted byte and IV to an XML?将 AES 加密的字节和 IV 存储到 XML 的最佳方法?
【发布时间】:2013-01-24 11:03:26
【问题描述】:

我对编码和密码学都是新手,所以我问的问题可能太基本了。我需要加密提供给我的值并将加密值以及用于加密的 IV 存储在文档中。加密是使用存储在其他地方的主密钥完成的。我使用AES加密,加密代码如下:

 private EncryptedData EncryptValue(string value, byte[] encryptedMasterKey)
        {
            byte[] encryptedValue = new byte[0];
            AesCryptoServiceProvider aesCryptoServiceProvider = null;

            //decrypt the master key
            encryptedMasterKey = DecryptMasterKey(encryptedMasterKey);

            // Create an AesCryptoServiceProvider object
            // with the specified key and IV.                   
            using (aesCryptoServiceProvider = new AesCryptoServiceProvider())
            {
                aesCryptoServiceProvider.Key = encryptedMasterKey;

                // Create an encryptor to perform the stream transform.
                ICryptoTransform encryptor = aesCryptoServiceProvider.CreateEncryptor(
                    aesCryptoServiceProvider.Key, aesCryptoServiceProvider.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Write all data to the stream.
                            swEncrypt.Write(value);
                        }
                        encryptedValue = msEncrypt.ToArray();
                    }
                }
            }

            EncryptedData encryptedData = new EncryptedData(encryptedValue, aesCryptoServiceProvider.IV);
            return encryptedData;
        }

将数据写入 XML 的代码如下所示:

public void WriteData(string id, EncryptedData encryptedData)
    {

        XDocument document = GetValidDocument();
        XElement[] encryptedDataElements = null;
        XElement encryptedDataElement;
        encryptedDataElements = (from element in document.Descendants(EncryptedDataElementName)
                                 where element.Element(IdElementName).Value.ToUpper() == id.ToUpper()
                                 select element).ToArray();
        if (encryptedDataElements.Count() != 0)
        {
            encryptedDataElement = encryptedDataElements.First();
            encryptedDataElement.Remove();
        }
        encryptedDataElement = new XElement(EncryptedDataElementName);
        XElement idElement = new XElement(IdElementName, id);
        encryptedDataElement.Add(idElement);
        XElement encryptedValueElement = new XElement(EncryptedValueElementName);
        encryptedValueElement.SetValue(Encoding.UTF8.GetString(encryptedData.EncryptedValue));
        XElement saltElement = new XElement(SaltElementName, Encoding.UTF8.GetString(encryptedData.Salt));
        encryptedDataElement.Add(encryptedValueElement);
        encryptedDataElement.Add(saltElement);
        document.Element(StoreElementName).Add(encryptedDataElement);
        IXmlService xmlService = GlueRegistry.Instance.GetService<IXmlService>();
        xmlService.SaveXmlDocument(document, filePath);
    }

我认为最好保存为 UTF8 编码的字符串并将值作为 UTF8 编码的字节数组返回。序列化不是一个选项,因为数据是一个一个写入的。问题出在使用 Encoding.UTF8.GetString 的 SetValue 方法中。我也明白我可能应该使用 XElement.Parse。我使用了它,但我得到一个异常,说该值无效。我现在想知道 UTF8 是否是一个不错的选择,或者是否有另一种更好的方法来做我想做的事情。

提前感谢您的帮助!

【问题讨论】:

    标签: xml linq c#-4.0 encoding cryptography


    【解决方案1】:
    1. 对于编码,我推荐 Base64。 Utf8 旨在将文本转换为字节。它不能将任意二进制数据转换为文本。
    2. 我建议使用经过身份验证的加密/添加 MAC。未经身份验证的加密会引发主动攻击,例如填充预言。

    所以你的代码变成这样:

    byte[] ciphertext = iv + Encrypt(key, m);
    byte[] ciphertextWithMAC = ciphertext + HMAC(key, ciphertext)
    string encodedCiphertext = Base64Encode(cipherText)
    

    【讨论】:

    • 我非常同意使用经过身份验证的加密。没有它,许多攻击都是可能的。
    【解决方案2】:

    虽然我有一些疑问,存储单个字节的加密是否是一个好主意, 这乞求蛮力攻击,表示形式对我来说很明显:使用数据类型 hexBinary (所以“ABC”将类似于“414243”)。这使加密值的长度加倍,但由于 XML 开销,这不太重要。优点是:不需要特殊的字符处理,清晰可见且有些可读性。

    【讨论】:

    • 没有理由说明单个加密字节比多个加密字节更容易受到攻击。
    • @CodesinChaos:尝试 256 种不同的输入对我来说似乎更容易受到攻击?!
    • @guidot 你怎么知道哪个输入是正确的?一般来说,拥有更多的明文/密文不利于安全性,因为要测试的内容更多。当然,如果您的协议设计得很好,那仍然无关紧要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 2011-10-10
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多