【问题标题】:Encode password to MD5 using keys使用密钥将密码编码为 MD5
【发布时间】:2016-02-02 04:37:01
【问题描述】:

目前我这样做:

    public static class Crypto
    {
        public static string Encode(string original)
        {
            var md5 = new MD5CryptoServiceProvider();
            var originalBytes = Encoding.Default.GetBytes(original);
            var encodedBytes = md5.ComputeHash(originalBytes);

            return BitConverter.ToString(encodedBytes);
        }
    }

我听说我应该使用一些密钥来编码东西。我是不是该?这里需要吗?这个怎么做?


我最终这样做了http://encrypto.codeplex.com/(sha1managed + 随机盐)

【问题讨论】:

  • 我很高兴您没有说“将密码加密为 MD5”。 :)
  • @Adam Paynter :) md5 有那么糟糕吗?
  • 没有。只是人们有时会混淆“加密”这个词。有人认为“加密”的意思是“把有用的数据变成垃圾”(即有人认为MD5加密数据)。

标签: c# .net hash


【解决方案1】:

您所说的称为“盐”,这是您附加到原始纯文本字符串的随机数据序列。这通常用于密码,防止彩虹表/字典攻击。

阅读此内容:http://en.wikipedia.org/wiki/Salt_%28cryptography%29

对于 C#,有一篇很好的文章:http://www.aspheute.com/english/20040105.asp

【讨论】:

  • @Douglas,这是一个强项,还不知道。应该是一个单独的答案。
  • @chic - 它包含在我的答案的链接中。
【解决方案2】:

您应该使用 Base64 编码进行表示。即:

StringBuilder hash = new StringBuilder();

for (int i = 0; i < encodedBytes.Length; i++)
{
    hash.Append(encodedBytes[i].ToString("X2"));
}

这表示一个字符串,而不是使用位转换器,它是字节的字符串直接表示(并且不能轻易反转回位)。

几点说明(请阅读):

  • MD5 是一种不可逆的散列函数(并不是一个很好的散列函数)
  • 如果您确实想要使用基于密钥的加密(例如 AES)来加密密码,不要。使用散列方法,但使用更强的方法。在此处发送look at this answer 以获取有关加强密码的更多信息。

另外注意,在您的实现中,您可以访问IDisposable 接口,即:

public static string Encode(string original)
{
    byte[] encodedBytes;

    using (var md5 = new MD5CryptoServiceProvider())
    {
        var originalBytes = Encoding.Default.GetBytes(original);
        encodedBytes = md5.ComputeHash(originalBytes);
    }

    return Convert.ToBase64String(encodedBytes);
}

【讨论】:

  • 关于 base64 编码的好点,但您的示例使用 base16 或十六进制编码。
【解决方案3】:

由于 SHA 被认为比 MD5 更安全,我建议使用它。

byte[] data = new byte[SALT_SIZE+DATA_SIZE];
byte[] result;
SHA256 shaM = new SHA256Managed();
result = shaM.ComputeHash(salt+data);

【讨论】:

    【解决方案4】:

    MD5 不是加密算法,而是散列算法,因此不需要密钥。这也意味着您无法反转(/去散列)该过程。散列仅以一种方式起作用,并且当您必须将原始(未散列)数据与散列进行比较时很有用。

    编辑:如果您确实想以可逆方式真正加密您的数据。例如,尝试研究 AES 加密。

    【讨论】:

    • 我认为他是在谈论关于标题“将密码编码为 md5”的密码散列虽然不是很清楚:)
    • 请不要推荐像 AES 这样的密码。
    • 为什么要加密密码?
    • -1:您的第一个陈述具有误导性,因为它表明不使用盐就足够安全,这就是问题的重点。另见雪橇的答案。
    • @above:这个问题的作者显然不知道哈希和加密之间的区别。您根本不能在单词的加密意义上对 MD5 密码进行加盐(最多您可以在其上附加一些额外的字符,但这并不能使其本身更安全)。因此,了解其中的区别很重要,我试图解释这一点。 AES btw 只是一个例子。我没有说这是最安全的选择。
    【解决方案5】:

    我在对 sled 的回答的评论中发布了此链接,但值得单独发布。

    http://codahale.com/how-to-safely-store-a-password/

    听起来好像有人建议您对密码哈希值加盐(我认为您将加盐称为“密钥”)。这比单纯的哈希要好,因为它使彩虹表无用。彩虹表采用各种可能的密码(例如,一系列密码,就像彩虹有多种颜色一样)并预先计算它们的 md5 哈希值。然后,要反转 md5,只需在表中查找 md5。

    但是,建议很快就会过时。硬件现在足够快,不需要彩虹表:您可以非常快速地计算哈希,它足够快,每次都从头开始暴力破解密码,特别是如果您知道盐。因此,解决方案是使用计算量更大的哈希,这将使蛮力变得更慢。

    执行此操作的黄金标准工具是bcrypt

    【讨论】:

      【解决方案6】:

      这里有几点可以扩展@Kyle Rozendo 的回答。

      1. 您应该避免使用默认编码Encoding.Default。除非您有充分的理由不这样做,否则请始终使用 UTF-8 编码/解码。使用 .NET System.Text 命名空间很容易做到这一点。
      2. MD5 输出是不受约束的二进制数据,不能可靠地直接转换为字符串。您必须使用一种特殊编码,旨在将二进制输出转换为有效字符串并返回。 @Kyle Rozendo 展示了一种方法;您也可以使用System.Convert 类中的方法。

      【讨论】:

        【解决方案7】:

        类示例:

        using System.Security.Cryptography;
        using System.Text;
        
        private static string MD5(string Metin)
        {
            MD5CryptoServiceProvider MD5Code = new MD5CryptoServiceProvider();
            byte[] byteDizisi = Encoding.UTF8.GetBytes(Metin);
            byteDizisi = MD5Code.ComputeHash(byteDizisi);
            StringBuilder sb = new StringBuilder();
            foreach (byte ba in byteDizisi)
            {
                sb.Append(ba.ToString("x2").ToLower());
            }
            return sb.ToString();
        }
        
        MessageBox.Show(MD5("isa")); // 165a1761634db1e9bd304ea6f3ffcf2b
        

        【讨论】:

          猜你喜欢
          • 2010-12-02
          • 2016-10-15
          • 1970-01-01
          • 2015-01-13
          • 2020-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-12
          相关资源
          最近更新 更多