【发布时间】:2017-11-04 16:19:52
【问题描述】:
我需要在写入数据库之前加密一些数据并在从数据库读取时解密。
我在这里使用了本指南中提供的代码:Encrypting and Decrypting data in an Universal Windows App
当我尝试解密时,我得到了错误:
数据错误(循环冗余校验)。 (HRESULT 异常:0x80070017)
我认为这是因为密钥不同,因为我实例化了 SymmetricEncryptionHelper 对象一次进行加密,然后再次进行解密。为了解决这个问题,我将类更改为单例,但我仍然遇到同样的错误:
public class SymmetricEncryptionHelper
{
private readonly IBuffer randomBuffer;
private readonly IBuffer randomBufferCBC;
private readonly CryptographicKey cryptographicKey;
private readonly string algorithmName;
private readonly SymmetricKeyAlgorithmProvider cryptingProvider;
private static SymmetricEncryptionHelper _instance;
public static SymmetricEncryptionHelper Instance
{
get
{
if (_instance == null)
{
_instance = new SymmetricEncryptionHelper();
}
return _instance;
}
}
/// <summary>
/// Instantiate with a random generated buffer (not an option if
/// you want to persist the encryption to disk)
/// </summary>
private SymmetricEncryptionHelper()
{
algorithmName = SymmetricAlgorithmNames.AesEcbPkcs7;
cryptingProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
randomBuffer = CryptographicBuffer.GenerateRandom(cryptingProvider.BlockLength);
randomBufferCBC = null;
cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer);
}
/// <summary>
/// Instantiate with a custom generated buffer (good for
/// persisting the encryption to disk)
/// </summary>
/// <param name="randomBuffer">The custom generated buffer</param>
private SymmetricEncryptionHelper(IBuffer randomBuffer)
: this()
{
this.randomBuffer = randomBuffer;
cryptographicKey = cryptingProvider.CreateSymmetricKey(randomBuffer);
}
/// <summary>
/// Instantiate with a custom generated buffer (good for
/// persisting the encryption to disk) and with a custom
/// generated CBC buffer (is using CBC algorithms)
/// </summary>
/// <param name="randomBuffer">The custom generated buffer</param>
/// <param name="randomBufferCBC">The custom generated CBC buffer</param>
private SymmetricEncryptionHelper(IBuffer randomBuffer, IBuffer randomBufferCBC)
: this(randomBuffer)
{
this.randomBufferCBC = randomBufferCBC;
}
private bool IsMultipleOfBlockLength(IBuffer binaryData)
{
return (binaryData.Length % cryptingProvider.BlockLength) != 0;
}
/// <summary>
/// Encrypts a given string
/// </summary>
/// <param name="data">Data to be encrypted</param>
/// <returns>An encrypted string in Unicode</returns>
public string Encrypt(string data)
{
if (string.IsNullOrEmpty(data))
{
return data;
}
var binaryData = Encoding.Unicode.GetBytes(data).AsBuffer();
if (!algorithmName.Contains("PKCS7") && IsMultipleOfBlockLength(binaryData))
throw new Exception("Message buffer length must be multiple of block length !!");
var encryptedBinaryData = CryptographicEngine.Encrypt(cryptographicKey, binaryData, randomBufferCBC);
return Encoding.Unicode.GetString(encryptedBinaryData.ToArray());
}
/// <summary>
/// Decrypts a string in Unicode
/// </summary>
/// <param name="encryptedData">An encrypted string in Unicode</param>
/// <returns>The decrypted string in Unicode</returns>
public string Decrypt(string encryptedData)
{
if (string.IsNullOrEmpty(encryptedData))
{
return encryptedData;
}
try
{
var encryptedBinaryData = Encoding.Unicode.GetBytes(encryptedData).AsBuffer();
var decryptedData = CryptographicEngine.Decrypt(cryptographicKey, encryptedBinaryData, randomBufferCBC);
return Encoding.Unicode.GetString(decryptedData.ToArray());
}
catch (Exception ex)
{
return null;
}
}
}
任何人都可以看到我哪里出错了 - 我用谷歌搜索了错误,但似乎找不到适合我的答案。
此外 - 一旦应用程序关闭,我就会丢失密钥,那么这里的最佳做法是什么?我应该将密钥保存在 PasswordVault 中吗?
【问题讨论】:
-
不要使用 ECB 模式,它不安全,请参阅ECB mode,向下滚动到企鹅。
标签: c# encryption uwp windows-10-mobile