【问题标题】:Generate a 128-bit string in C#在 C# 中生成一个 128 位的字符串
【发布时间】:2013-05-15 20:44:57
【问题描述】:

我正在用 C# 开发一个加密用户和管理员密码的类项目。加密我使用TripleDESCryptoServiceProvider

在配置应用程序中,用户输入用于加密和解密密码的密钥。我想要一个按钮来生成一个密钥来帮助用户,但我不知道如何随机生成 128 位。如何生成 128 位的密钥?

【问题讨论】:

  • 立即回复是RNGCryptoServiceProvider。但你可能做错了什么。也许您需要散列,也许您需要 AES,并且很可能您使用了错误的加密模式。
  • 一种方法不是加密密码,而是散列密码。这背后的好理论是它们永远不会“解密”,而是您比较哈希值而不实际泄露密码。
  • 您可以做的一件事是使用当前日期和时间并将其作为种子输入随机数生成器。然后生成一个介于 1000,2500 之类的范围之间的数字,并循环该随机数次,直到循环结束。最后生成的随机数将被转换为字节数组。只需确保限制生成的第二个数字,以确保它在从数字转换为字节数组时创建 128 位。
  • @SASS_Shooter 听起来是个糟糕的主意。当前时间没有足够的熵,编写加密强度 PRNG 并非易事。
  • @SASS_Shooter Don't roll your own crypto,以正确的方式使用正确的工具。您推荐的方式是非常糟糕的加密,有人可以通过知道随机数是在一天中的什么时间生成的,然后尝试该时间附近的所有组合,直到找到解密消息的密钥,就可以很容易地找出随机数是什么。

标签: c# encryption password-encryption


【解决方案1】:

要生成用于加密的随机值,您应该使用RNGCryptoServiceProvider

byte[] bytes = new byte[16];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(bytes);

要将此字节序列转换为字符串,您可以使用十六进制 (BitConverter.ToString) 或 Base64 (Convert.ToBase64String)。


但是这里有一些奇怪的地方:

  • 3DES 使用 168 位密钥
  • 如果您想使用对称加密,您可能应该使用 AES。 3DES 并没有完全损坏,但它几乎只能用于传统用途。
  • 请注意您选择的Block cipher mode of operation。您通常需要适当的 IV、MAC 和安全链接模式
  • 通常您实际上应该散列密码而不是加密它们。详情请见How to securely hash passwords? on security.SE

【讨论】:

  • 感谢您的回答,我正在使用您对密码进行散列的建议。感谢您的快速回答
【解决方案2】:

我完全理解你想要什么而不是使用 htttp 传递 url: //mydomain.com? Id = 123,你想传递一个加密的值。而当有人点击这个带有加密 id 的 url 时,你想解密 url 的值。

有两个过程:

在加密中: 1 - 将“ID”(通常是整数)转换为字符串。示例 var NewId = Convert.ToString ((ID); 2 - 使用短语随机加密。示例:“我爱巧克力”(如果你有的话,这个短语可以从你的参数数据库中找到......)

在解密中: 1 - 使用相同的阻止短语来解读。 2 - 使用 Convert.ToInt32 (Shuffled Variable Above) 再次将解密的内容转换为整数

您将必须实现 2 个功能:

加密函数:

private string Encrypt(string clearText)
    {
        string EncryptionKey = "I love chocolate";
        byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
        return clearText;
    }

解密函数:

private string Decrypt(string cipherText)
    {
        string EncryptionKey = "I love chocolate";
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = System.Text.Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }

将 ID 加密为 ID = "123" 时,ID = "B8 + iXv5 / 8BUQEbHt8 // fGA =="。

当你解密 ID 值 "B8 + iXv5 / 8BUQEbHt8 // fGA ==" 你会再次得到 "123"。

C# 示例:

  var OriginalId = 123;
          var EncrypetedId = Encrypt(Convert.ToString(OriginalId));
          //for recovering original value
          var OriginalID = Convert.ToInt32(Decrypt(EncrypetedId));

希望对你有帮助。

【讨论】:

    【解决方案3】:

    看看RNGCryptoServiceProvider 类,特别是GetNonZeroBytes 方法。您可以通过 base64 编码运行该字节字符串以使其易于阅读。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 2013-05-05
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      相关资源
      最近更新 更多