【问题标题】:String encrypt / decrypt with password c# Metro Style字符串加密/解密密码 c# Metro Style
【发布时间】:2016-01-26 02:24:47
【问题描述】:

我想用密码加密和解密字符串。我使用 C# 和 WinRT (MetroStyle)。有人上加密/解密课程吗?

【问题讨论】:

  • 好吧,也许你错过了理解我,我只想知道如何在 WinRT 中做到这一点。它必须不是很高的安全性。很简单,但足够安全,可以在其中存储个人数据

标签: c# windows-8 microsoft-metro encryption


【解决方案1】:

Metro 中不存在正常的 .Net System.Security.Cryptography 命名空间。您可以改用 Windows.Security.Cryptography.Core 命名空间中的 CryptographicEngine 类。

如果密码只是被验证/认证,不要加密它。相反,请使用以下内容:

using Windows.Security.Cryptography.Core;
using Windows.Security.Cryptography;
using Windows.Storage.Streams;

...
// Use Password Based Key Derivation Function 2 (PBKDF2 or RFC2898)
KeyDerivationAlgorithmProvider pbkdf2 = 
    KeyDerivationAlgorithmProvider.OpenAlgorithm(
        KeyDerivationAlgorithmNames.Pbkdf2Sha256);

// Do not store passwords in strings if you can avoid them. The
// password may be retained in memory until it is garbage collected.
// Crashing the application and looking at the memory dump may 
// reveal it.
IBuffer passwordBuffer = 
     CryptographicBuffer.ConvertStringToBinary("password", 
         BinaryStringEncoding.Utf8);
CryptographicKey key = pbkdf2.CreateKey(passwordBuffer);

// Use random salt and 10,000 iterations. Store the salt along with 
// the derviedBytes (see below).
IBuffer salt = CryptographicBuffer.GenerateRandom(32);
KeyDerivationParameters parameters = 
    KeyDerivationParameters.BuildForPbkdf2(salt, 10000);

// Store the returned 32 bytes along with the salt for later verification
byte[] derviedBytes = 
    CryptographicEngine.DeriveKeyMaterial(key, parameters, 32).ToArray();

当提供密码时,使用相同的盐运行相同的过程并比较派生字节。像存储加密密钥一样存储秘密。

如果将使用密码,例如连接到另一个服务:

// Use AES, CBC mode with PKCS#7 padding (good default choice)
SymmetricKeyAlgorithmProvider aesCbcPkcs7 = 
    SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

// Create an AES 128-bit (16 byte) key
CryptographicKey key = 
    aesCbcPkcs7.CreateSymmetricKey(CryptographicBuffer.GenerateRandom(16));

// Creata a 16 byte initialization vector
IBuffer iv = CryptographicBuffer.GenerateRandom(aesCbcPkcs7.BlockLength);

// Encrypt the data
byte[] plainText = Encoding.UTF8.GetBytes("Hello, world!"); // Data to encrypt
byte[] cipherText = CryptographicEngine.Encrypt(
    key, plainText.AsBuffer(), iv).ToArray();

// Decrypt the data
string newPlainText = new string(
    Encoding.UTF8.GetChars(CryptographicEngine.Decrypt(
        key, cipherText.AsBuffer(), iv).ToArray()));

// newPlainText contains "Hello, world!"

与任何密码学一样,请确保妥善保护您的密钥并遵循最佳实践。链接的文档还提供了示例。

【讨论】:

  • @Michael 我正在写一篇文章。当我确定它有效时,我会在大约 5 分钟内更新我的答案。
  • @Michael 它只是 .Net 4.5 的一部分 (msdn.microsoft.com/en-us/library/hh598393)。您使用的是旧版本的 .Net 吗?
  • 为了理解:如果我想稍后检查保存为密文的密码是否是密码框中的密码,我还需要密钥和iv?还是只是钥匙?我应该在哪里保存密钥(?和iv?)。 key 和 iv 应该是预定义的还是随机的?
  • @Michael 要检查它,您将需要密钥和 IV。但是,如果您唯一要做的就是检查密码,请考虑使用 CryptographicEngine.DeriveKeyMaterial 方法。请参阅msdn.microsoft.com/en-us/library/windows/apps/… 获取帮助和示例。
  • 我想检查密码是否正确,如果正确,我会加密一些字符串。所以也许你可以给我正确的输入如何处理密钥,IV。 (密码)提前致谢!