我对编码和加密都不熟悉,所以我问的问题可能太基础了。我需要加密提供给我的值并将加密值以及用于加密的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是一个不错的选择,还是有另一种更好的方法来做我想做的事。
提前感谢您的帮助!
答案 0 :(得分:4)
所以你的代码变成了:
byte[] ciphertext = iv + Encrypt(key, m);
byte[] ciphertextWithMAC = ciphertext + HMAC(key, ciphertext)
string encodedCiphertext = Base64Encode(cipherText)
答案 1 :(得分:0)
虽然我有些疑惑,但是存储单个字节的加密是否是个好主意, 对于暴力攻击来说,表示的形式对我来说是显而易见的:使用数据类型hexBinary(所以“ABC”将类似于“414243”)。这使加密值的长度加倍,但由于XML开销,这不太重要。优点是:不需要特殊的字符处理,清晰可见且有些可读。