一个 .NET MD5 类库
一个用于 .NET 的 MD5 类库,支持高级功能,例如嵌入在 MD5 哈希中的随机 Salt 值。
引言
本文档描述了如何使用我为 .NET 编写的 MD5 类库。 建议以以下方式实现 MD5:
加密
- 生成一个随机的 "Salt" 值
- 将要加密的字符串与 "Salt" 合并
- 对合并后的字符串进行 MD5 哈希
- 将 MD5 哈希保存在一个位置,并将 Salt 保存在另一个位置,通常是数据库管理系统 (DBMS) 中的一个单独的 "表" 中。
测试
- 找到保存的 "Salt"
- 将字符串和保存的 "Salt" 合并
- 对合并后的字符串进行 MD5 哈希
- 将新的 MD5 哈希与保存的哈希进行比较;如果匹配,则允许使用你所保护的内容
背景
我选择编写这个类库是因为我发现的所有文章和 MSDN 活动上的建议都推荐将此 Salt 存储在 DBMS 中。 我正在编写一个 ASP.NET 应用程序,我想使用 XML 文件来存储用户名和密码。 将 Salts 存储在同一个 XML 文件中不推荐,但我也不认为将它们以“纯文本”形式存储在任何 XML 文件中是安全的。 我决定编写一个类,该类将生成 Salt,将其与字符串合并,加密字符串,获取 Salt,并将其放置在哈希中的一个**随机**位置,然后保存哈希。 这允许我将哈希存储在 XML 文件中,并使 Salt 更加安全,因为首先必须在哈希字符串中找到它,这非常困难。 此外,由于哈希字符串看起来与常规 MD5 哈希字符串非常相似,因此很难确定何时实际使用此方法。
Using the Code
由于代码作为类库发布,因此非常易于使用。
使用此类库的步骤
- 下载软件包。
- 将其提取到你的硬盘上。
- 在 VS.NET IDE (解决方案资源管理器) 中右键单击“引用”并单击“添加引用”。
- 添加类似于下面的代码
Imports IST.DataHash
'Code was removed for simplicity
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim MD5 As New MD5
'Encrypts the specified string
lblEncString.Text = MD5.Encrypt(txtEncrypt.Text)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
Dim MD5 As New MD5
'Verifys the string matches the hash, returns True or False.
lblDecString.Text = MD5.Verify(txtEncrypt.Text, lblEncString.Text)
End Sub
该程序集也经过强名称签名,以便添加到 GAC。
源代码
Imports System.Security.Cryptography
Imports System.Text
Namespace DataHash
''' -----------------------------------------------------------------------------
''' Project : DataHash
''' Class : DataHash.MD5
'''
''' -----------------------------------------------------------------------------
''' <SUMMARY>
''' Provides advanced MD5 support for your applications
''' </SUMMARY>
''' <REMARKS>
''' </REMARKS>
''' <HISTORY>
''' [Frazell Thomas] 4/13/2004 Created
''' </HISTORY>
''' -----------------------------------------------------------------------------
Public Class MD5
Private EncStringBytes() As Byte
Private Encoder As New UTF8Encoding
Private MD5Hasher As New MD5CryptoServiceProvider
''' <SUMMARY>
''' Encryptes the specified string to MD5 with the Salt information embedded
''' </SUMMARY>
''' <REMARKS>
''' Accepts any non-array string type
''' </REMARKS>
''' <RETURNS>
''' Returns a string containing the MD5 HASH with embedded SALT
''' </RETURNS>
''' <EXAMPLE>
''' <CODE>
''' 'Generates a MD5 Hash for a string
''' Dim S as string
''' Dim MD5 as new IST.DataHash.MD5
''' s = "This is a string"
''' s = MD5.Encrypt(s)
''' </CODE>
''' </EXAMPLE>
'Encrptes the string in MD5 when passed as a string
Public Function Encrypt(ByVal EncString As String) As String
'Variable Declarations
Dim RanGen As New Random
Dim RanString As String = ""
Dim MD5String As String
Dim RanSaltLoc As String
'Generates a Random number of under 4 digits
While RanString.Length <= 3
RanString = RanString & RanGen.Next(0, 9)
End While
'Converts the String to bytes
EncStringBytes = Encoder.GetBytes(EncString & RanString)
'Generates the MD5 Byte Array
EncStringBytes = MD5Hasher.ComputeHash(EncStringBytes)
'Affixing Salt information into the MD5 hash
MD5String = BitConverter.ToString(EncStringBytes)
MD5String = MD5String.Replace("-", Nothing)
'Finds a random location in the string to sit the salt
RanSaltLoc = RanGen.Next(4, MD5String.Length)
'Shoves the salt in the location
MD5String = MD5String.Insert(RanSaltLoc, RanString)
'Adds 0 for values under 10 so we always occupy 2 charater spaces
If RanSaltLoc < 10 Then
RanSaltLoc = "0" & RanSaltLoc
End If
'Shoves the salt location in the string at position 3
MD5String = MD5String.Insert(3, RanSaltLoc)
'Returns the MD5 encrypted string to the calling object
Return MD5String
End Function
''' <SUMMARY>
''' Verifies a string against an MD5 Hash string.
''' </SUMMARY>
''' <REMARKS>
''' Accepts any non-array string type
''' </REMARKS>
''' <RETURNS>
''' Returns <C>True</C> or <C>False</C>
''' </RETURNS>
''' <EXAMPLE>
''' <CODE>
''' 'Test a string against an MD5 Hash
''' Dim S as string
''' Dim MD5String as string
''' Dim MD5 as new IST.DataHash.MD5
''' s = "This is a string"
''' MD5String = MD5.Encrypt(s)
''' 'Prints the test results on screen
''' console.write(MD5.Verify(s,MD5String))
''' </CODE>
''' </EXAMPLE>
'Verifies the String entered matches the MD5 Hash
Public Function Verify(ByVal S As String, ByVal Hash As String) As Boolean
'Variable Declarations
Dim SaltAddress As Double
Dim SaltID As String
Dim NewHash As String
'Finds the Salt Address and Removes the Salt Address from the string
SaltAddress = Hash.Substring(3, 2)
Hash = Hash.Remove(3, 2)
'Finds the SaltID and removes it from the string
SaltID = Hash.Substring(SaltAddress, 4)
Hash = Hash.Remove(SaltAddress, 4)
'Converts the string passed to us to Bytes
EncStringBytes = Encoder.GetBytes(S & SaltID)
'Encryptes the string passed to us with the salt
EncStringBytes = MD5Hasher.ComputeHash(EncStringBytes)
'Converts the Hash to a string
NewHash = BitConverter.ToString(EncStringBytes)
NewHash = NewHash.Replace("-", Nothing)
'Tests the new has against the one passed to us
If NewHash = Hash Then
Return True
ElseIf NewHash <> Hash Then
Return False
End If
End Function
End Class
End Namespace
关注点
各种 MD5 参考
历史
- 2006 年 3 月 7 日 - 由于大量需求以及 Infinity Squared Technologies, Inc. 的授权,发布了源代码。
- 2004 年 4 月 13 日 - 公开发布版本 1.0。