有关加密的建议

时间:2009-05-12 11:35:53

标签: asp.net vb.net encryption

我有一个名为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

欢迎帮助或建议,因为我在这里难过......

2 个答案:

答案 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

如果有人有关于如何创建,存储和检索盐渍密码的任何文章或建议,我很乐意看到它。

克里斯