我有一个名为tdes的类,如下所示:
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Security.Cryptography
Imports System.IO
Namespace security
Public Class tdes
Private des As New TripleDESCryptoServiceProvider()
Private utf8 As New UTF8Encoding()
Private keyValue As Byte()
Private iVValue As Byte()
Public Property Key() As Byte()
Get
Return keyValue
End Get
Set(ByVal value As Byte())
keyValue = value
End Set
End Property
Public Property iV() As Byte()
Get
Return iVValue
End Get
Set(ByVal value As Byte())
iVValue = value
End Set
End Property
Public Sub New(ByVal key As Byte(), ByVal iV As Byte())
Me.keyValue = key
Me.iVValue = iV
End Sub
Public Function ByteDecrypt(ByVal bytes As Byte()) As String
Dim output As Byte()
output = Transform(bytes, des.CreateDecryptor(Me.keyValue, Me.iVValue))
'Return Convert.ToBase64String(output)
Return utf8.GetString(output)
End Function
Public Function ByteEncrypt(ByVal bytes As Byte()) As Byte()
Return Transform(bytes, des.CreateEncryptor(Me.keyValue, Me.iVValue))
End Function
Public Function StringDecrypt(ByVal text As String) As String
Dim input As Byte() = Convert.FromBase64String(text)
Dim output As Byte() = Transform(input, des.CreateDecryptor(Me.keyValue, Me.iVValue))
Return utf8.GetString(output)
End Function
Public Function StringEncrypt(ByVal text As String) As String
Dim input As Byte() = utf8.GetBytes(text)
Dim output As Byte() = Transform(input, des.CreateEncryptor(Me.keyValue, Me.iVValue))
Return Convert.ToBase64String(output)
End Function
Public Function StringEncryptByte(ByVal text As String) As Byte()
Dim input As Byte() = utf8.GetBytes(text)
Dim output As Byte() = Transform(input, des.CreateEncryptor(Me.keyValue, Me.iVValue))
'Return Convert.ToBase64String(output)
Return output
End Function
Private Function Transform(ByVal input As Byte(), ByVal cryptoTransform As ICryptoTransform) As Byte()
' Create the necessary streams
Dim memory As New MemoryStream()
Dim stream As New CryptoStream(memory, cryptoTransform, CryptoStreamMode.Write)
' Transform the bytes as requesed
stream.Write(input, 0, input.Length)
stream.FlushFinalBlock()
' Read the memory stream and convert it back into byte array
memory.Position = 0
Dim result As Byte() = New Byte(memory.Length - 1) {}
memory.Read(result, 0, result.Length)
' Clean up
memory.Close()
stream.Close()
' Return result
Return result
End Function
End Class
End Namespace
它可以很好地加密和解密事物。我想加密一个数据库表中的一些现有密码,所以我在它们上运行了一个小脚本,这样就加密了它们(为简洁起见,遗漏了很多):
Dim key As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
Dim iv As Byte() = {8, 7, 6, 5, 4, 3, 2, 1}
Dim enc As New security.tdes(key, iv)
Dim i As Integer = 0
Using oConn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("pitstopConnectionString").ConnectionString)
Using cmd As New SqlCommand("doUpdatePasswords", oConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@userid", userid)
cmd.Parameters.AddWithValue("@newpassword", enc.StringEncryptByte(currentPassword))
oConn.Open()
Try
i = cmd.ExecuteNonQuery()
Catch ex As Exception
Exit Sub
End Try
End Using
End Using
这已成功加密表格中所有记录的所有密码。现在,当我允许某人登录时,我想比较两个值(键入的内容,存储的密码是什么),我认为最好的方法是解密存储的并使用字符串进行比较?像这样:
If (enc.ByteDecrypt(pwdenc).ToString() = pitstop.doMakeSafeForSQL(txtPassword.Text.ToString.ToLower)) Then
然而,我得到了各种奇怪的错误;无法将类型为“System.String”的对象强制转换为“System.Byte []”。是一个,Base-64字符串中的无效字符。另一个是基于我在前面的SQLDataReader中调用密码的方式:
Using oConn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("pitstopConnectionString").ConnectionString)
Using cmd As New SqlCommand("doGetEncryptedForLogin", oConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@email", pitstop.doMakeSafeForSQL(txtEmail.Text.ToString.ToLower))
oConn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader()
If dr.HasRows() = True Then
While dr.Read()
pwdenc = dr("password_b")
End While
Else
pitstop.doLogIt("Denied login for [" & txtEmail.Text & "]")
litError.Text = "The details you have provided are incorrect. Please try again."
pnlDenied.Visible = True
Exit Sub
End If
dr.Close()
End Using
End Using
End Using
欢迎帮助或建议,因为我在这里难过......
答案 0 :(得分:0)
由于没有其他人似乎回答,我会给你我自己的两分钱。我记得三年多前我开始“玩”加密时经历了类似的情况;在我的情况下,问题与Base64转换有某种关系,虽然我现在不记得确切的细节。 我建议你经历一个平静和耐心的调试会话,跟踪字符串的所有值,加密和解密之前和之后的字节数组。 我知道这不是一个很好的帮助,但我希望至少能引导你朝着正确的方向前进。
答案 1 :(得分:0)
我通过用杰夫阿特伍德(www.codinghorror.com)奇妙的加密工具替换我的'加密'类来修复此错误。
我确实想要加密密码并存储盐,但是我没有时间来实现它,并且必须返回它。与此同时,我使用此代码作为我的加密和解密函数 - 我希望这对某些人有所帮助:
Dim key As String = System.Configuration.ConfigurationManager.AppSettings("key").ToString()
Dim salty As String = pitstop.doMakeSafeForSQL(txtEmail.Text.ToString().ToLower())
Dim p As Encryption.Symmetric.Provider = Encryption.Symmetric.Provider.TripleDES
Dim sym As New Encryption.Symmetric(p)
sym.Key.Text = key
Dim encryptedData As Encryption.Data
encryptedData = sym.Encrypt(New Encryption.Data(pitstop.doMakeSafeForSQL(txtPassword.Text.ToString().ToLower())))
解密:
Dim decryptedData As Encryption.Data
Dim pr As Encryption.Symmetric.Provider = Encryption.Symmetric.Provider.TripleDES
Dim sym2 As New Encryption.Symmetric(pr)
sym2.Key.Text = System.Configuration.ConfigurationManager.AppSettings("key").ToString()
Try
decryptedData = sym2.Decrypt(encryptedData)
Catch ex As Exception
// removed for brevity //
End Try
如果有人有关于如何创建,存储和检索盐渍密码的任何文章或建议,我很乐意看到它。
克里斯