Совет относительно шифрования - PullRequest
0 голосов
/ 12 мая 2009

У меня есть класс с именем 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 голосов
/ 15 мая 2009

Я исправил эту ошибку, заменив мой класс шифрования на фантастические инструменты шифрования Джеффа Этвуда (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

Если у кого-нибудь есть какие-либо статьи или советы о том, как создавать, хранить и извлекать соленые пароли, я бы хотел их увидеть.

Chris

0 голосов
/ 12 мая 2009

Так как никто больше не отвечает, я дам вам свои два цента. Я помню похожую ситуацию, когда я начал «играть» с шифрованием более трех лет назад; в моем случае проблема была как-то связана с преобразованием Base64, хотя сейчас я не могу вспомнить точные детали. Я предлагаю вам пройти спокойную и терпеливую сессию отладки, отслеживая все значения строк, байтовых массивов до и после шифрования и дешифрования. Я понимаю, что это не очень помогает, но я надеюсь, что по крайней мере может направить вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...