使用密钥将密码编码为MD5

3

目前我正在做这个:

    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
@Adam Paynter :) md5 算法不好吗? - Omu
不是的。有些人有时会混淆“加密”这个词。有些人认为“加密”意味着“将有用的数据变成垃圾”(也就是说,有些人认为MD5“加密”数据)。 - Adam Paynter
7个回答

7

@Douglas,这是一个很有力的观点,我之前还不知道。应该单独作为一个回答。 - chiccodoro
@chic - 在我的回答链接中已经包含了它。 - Kyle Rosendo

3

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

StringBuilder hash = new StringBuilder();

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

这代表一个字符串,而不是使用位转换器,它是字节的字符串表示形式(不能轻松地反向转换为位)。

一些注意事项(请阅读):

  • MD5是不可逆的哈希函数(而且并不好)
  • 如果您真正想要使用基于密钥的加密(如AES)来加密密码,请不要。使用哈希方法,但使用更强的方法。在这里查看此答案以获取有关加强密码的更多信息。

另一个注意事项,在您的实现中,您可以访问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或十六进制编码。 - President James K. Polk

2

由于SHA比MD5更安全,我建议使用SHA。

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

1

MD5不是一种加密算法,而是一种哈希算法,因此不需要密钥。这也意味着您无法反向(/取消哈希)该过程。哈希只能单向工作,并且在必须将哈希与原始(未散列)数据进行比较时非常有用。

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


1
我认为他在谈论关于标题“将密码编码为MD5”的哈希密码,尽管不是非常清楚 :) - sled
请不要为密码推荐 AES 等加密方式。 - Jonas Elfström
为什么你会想要加密密码呢? - sled
1
-1:你的第一句话有误导性,因为它暗示了不使用盐也足够安全,而这正是问题的关键。请参考sled的答案。 - chiccodoro
@以上:显然,这个问题的提问者并不知道哈希和加密之间的区别。在加密意义上,你根本不能给MD5密码加盐(最多只能在其后附加一些额外字符,但这并不能使其更安全)。因此,了解区别非常重要,我正在尝试解释。顺便说一句,AES只是一个例子。我没有说它是最安全的选项。 - Laurens Ruijtenberg

0

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

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

听起来你已经得到了关于加盐密码哈希的建议(我认为你称之为“密钥”)。这比仅使用哈希更好,因为它使彩虹表无用。彩虹表会提前计算出各种可能的密码(例如,一系列密码,就像彩虹有一系列颜色),并计算它们的md5哈希值。然后,要反转一个md5,只需在表中查找该md5。

然而,这个建议正在迅速过时。现在硬件足够快,彩虹表已经不再必要:您可以非常快地计算哈希,每次从头开始暴力破解密码都足够快,特别是如果您知道盐。因此,解决方案是使用更耗费计算资源的哈希,这将使暴力破解变得非常缓慢。

实现这一点的黄金标准工具是bcrypt


0

以下是对@Kyle Rozendo答案中提到的几点的进一步解释:

  1. 应避免使用默认编码Encoding.Default。除非有充分的理由,否则始终使用UTF-8进行编码和解码。在.NET的System.Text命名空间中很容易实现。
  2. MD5输出是无约束的二进制数据,不能直接可靠地转换为字符串。您必须使用专门设计用于将二进制输出转换为有效字符串的特殊编码,并进行相反的转换。@Kyle Rozendo展示了一种方法;您还可以使用System.Convert类中的方法。

0

类的例子:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接