QuestionSolvedEncrypting Text

Posts 31–39 of 39 · Page 3 of 3
Quote Originally Posted by Jason View Post


If each user has their own local "database", what's the point?
It's just so it can start the game faster.. It logs into the site and starts the game.

Also, your code, I'm still a bit confused. Lets say you have this

Code:
Dim aHash As String = HashProvider.Hash("a", "fde3")
Along with b, c, d, etc. Now, you want to save it in a text file. How exactly would you do that?

Code:
My.Computer.FileSystem.WriteAllText("C:\Program Files\text.txt, TextBox1.Text, True)
(Using this method)
I modified the class slightly last night to avoid using crappy reflection.

Code:
Imports System
Imports System****
Imports System.Text
Imports System.Linq
Imports System.Collections.Generic
Imports System.Security.Cryptography
Imports System.Runtime.InteropServices
Imports System.Runtime.Serialization.Formatters.Binary

Public Class HashProvider
    Public Enum Algorithm
        MD5
        SHA1
        SHA256
        SHA384
        SHA512
        MD160
    End Enum

    Private Shared _hashset As Dictionary(Of Algorithm, HashAlgorithm)

    Shared Sub New()
        _hashset = New Dictionary(Of Algorithm, HashAlgorithm)
        _hashset.Add(Algorithm.MD5, New MD5CryptoServiceProvider())
        _hashset.Add(Algorithm.SHA1, New SHA1CryptoServiceProvider())
        _hashset.Add(Algorithm.SHA256, New SHA256CryptoServiceProvider())
        _hashset.Add(Algorithm.SHA384, New SHA384CryptoServiceProvider())
        _hashset.Add(Algorithm.SHA512, New SHA512CryptoServiceProvider())
        _hashset.Add(Algorithm.MD160, New RIPEMD160Managed())
    End Sub

    Public Shared Function Hash(ByVal dataStream As Stream, ByVal algorithm As Algorithm) As String
        If _hashset.ContainsKey(algorithm) Then
            Return _hashset(algorithm).ComputeHash(dataStream).Aggregate(New StringBuilder(128), Function(sb, b) sb.Append(b.ToString("x"))).ToString()
        End If
        Throw New ArgumentOutOfRangeException("Hashing algorithm is not supported")
    End Function

    Public Shared Function Hash(ByVal data As Byte(), ByVal offset As Integer, ByVal count As Integer, ByVal algorithm As Algorithm) As String
        If _hashset.ContainsKey(algorithm) Then
            Return _hashset(algorithm).ComputeHash(data, offset, count).Aggregate(New StringBuilder(128), Function(sb, b) sb.Append(b.ToString("x"))).ToString()
        End If
        Throw New NotSupportedException("Hashing algorithm is not supported")
    End Function

    Public Shared Function Hash(ByVal data As Byte(), ByVal algorithm As Algorithm) As String
        Return Hash(data, 0, data.Length, algorithm)
    End Function

    Public Shared Function Hash(ByVal data As String, ByVal algorithm As Algorithm) As String
        Return Hash(Encoding.ASCII.GetBytes(data), algorithm)
    End Function

    Public Shared Function HashObject(Of TSource)(ByVal data As TSource, ByVal algorithm As Algorithm) As String
        If GetType(TSource).IsSerializable OrElse Attribute.IsDefined(GetType(TSource), GetType(SerializableAttribute)) Then
            Dim formatter = New BinaryFormatter()
            Using memory = New MemoryStream()
                formatter.Serialize(memory, data)
                Return Hash(memory, algorithm)
            End Using
        ElseIf GetType(TSource).IsValueType Then
            Dim gc = GCHandle.Alloc(data)
            Try
                Dim size As Integer = Marshal.SizeOf(GetType(TSource))
                Dim serialized = New Byte(size - 1) {}
                Marshal.Copy(GCHandle.ToIntPtr(gc), serialized, 0, serialized.Length)
                Return Hash(serialized, algorithm)
            Finally
                If gc.IsAllocated Then
                    gc.Free()
                End If
            End Try
        Else
            Throw New ArgumentException("data is not serializable", "data")
        End If
    End Function
End Class
To write it to a text file you'd use any one of the I/O functions. However this encryption is forward only, meaning you can't get the password back out of the text file.

Code:
MessageBox.Show(HashProvider.Hash("hello world", HashProvider.Algorithm.MD5))
Quote Originally Posted by Jason View Post
I modified the class slightly last night to avoid using crappy reflection.
To write it to a text file you'd use any one of the I/O functions. However this encryption is forward only, meaning you can't get the password back out of the text file.
Thanks but.. The whole point of doing this was so I could get the text back out of the file...
Quote Originally Posted by Cryptonic View Post


Thanks but.. The whole point of doing this was so I could get the text back out of the file...
So use Rijndael encryption and store the key somewhere in your program. I have a library for this at home, but I'm working at the moment, I'll post it tonight.
Lol?
Code:
'Writing the md5 crap?
dim dimmm as string = HashProvider.Hash("hello pinecone", HashProvider.Algorithm.MD5)
My.Computer.FileSystem.WriteAllText("C:\password.txtyderp, dimmm, True)
@Hassan
his point moreso is there's no way included in the code to unhash text. and he wants to be able to read, as well as write encrypted stuffs.
Alright here's a really quick symmetrical encryption version using Rijndael. This will require slightly more work on your part, but not a lot.

Code:
Public Class SimpleRijndael
    ' Notes about the function:
    ' 1. the initVector parameter MUST BE 16 BYTES. No more, no less.
    ' 2. keySize can ONLY take the values 128, 192 or 256. Anything else will break.
    ' 3. salt should be 8 characters or longer, but the function will allocate more characters for you if needs be.
    Public Shared Function Encrypt(ByVal data As Byte(), ByVal password As String, ByVal salt As String, ByVal initVector As Byte(), Optional ByVal keySize As Integer = 128) As Byte()
        salt = salt.PadRight(8, "+"c)

        Dim bSalt As Byte() = Encoding.ASCII.GetBytes(salt)
        Dim derivedPassword As New Rfc2898DeriveBytes(password, bSalt, 2)
        Dim bKey As Byte() = derivedPassword.GetBytes(keySize / 8)

        Using rijndael = New RijndaelManaged() With {.Mode = CipherMode.CBC}
            Using encryptor = rijndael.CreateEncryptor(bKey, initVector)
                Using bufferStream = New MemoryStream()
                    Using cryptoStream = New CryptoStream(bufferStream, encryptor, CryptoStreamMode.Write)
                        cryptoStream.Write(data, 0, data.Length)
                        cryptoStream.FlushFinalBlock()

                        Return bufferStream.ToArray()
                    End Using
                End Using
            End Using
        End Using
    End Function

    ' Notes about the function
    ' Same as Encrypt. Vector must be exactly 16 bytes, salt.Length should be >= 8 and keysize should be 128, 192 or 256.
    Public Shared Function Decrypt(ByVal data As Byte(), ByVal password As String, ByVal salt As String, ByVal initVector As Byte(), Optional ByVal keySize As Integer = 128) As Byte()
        salt = salt.PadRight(8, "+"c)

        Dim bSalt As Byte() = Encoding.ASCII.GetBytes(salt)
        Dim derivedPassword As New Rfc2898DeriveBytes(password, bSalt, 2)
        Dim bKey As Byte() = derivedPassword.GetBytes(keySize / 8)

        Using rijndael = New RijndaelManaged() With {.Mode = CipherMode.CBC}
            Using decryptor = rijndael.CreateDecryptor(bKey, initVector)
                Using bufferStream = New MemoryStream(data)
                    Using decryptoStream = New CryptoStream(bufferStream, decryptor, CryptoStreamMode.Read)
                        Dim buffer(data.Length - 1) As Byte
                        Dim read As Integer = decryptoStream.Read(buffer, 0, buffer.Length)
                        Dim decrypted(read - 1) As Byte

                        Array.Copy(buffer, decrypted, read)
                        Return decrypted
                    End Using
                End Using
            End Using
        End Using
    End Function

    ' A few functional versions for ease-of-use encrypting string data
    Public Shared Function EncryptString(ByVal data As String, ByVal password As String, ByVal salt As String, ByVal initVector As Byte(), Optional ByVal keySize As Integer = 128, Optional ByVal stringEncoding As Encoding = Nothing) As Byte()
        If stringEncoding Is Nothing Then stringEncoding = Encoding.ASCII
        Return Encrypt(stringEncoding.GetBytes(data), password, salt, initVector, keySize)
    End Function

    Public Shared Function DecryptString(ByVal data As Byte(), ByVal password As String, ByVal salt As String, ByVal initVector As Byte(), Optional ByVal keySize As Integer = 128, Optional ByVal stringEncoding As Encoding = Nothing) As String
        If stringEncoding Is Nothing Then stringEncoding = Encoding.ASCII
        Return stringEncoding.GetString(Decrypt(data, password, salt, initVector, keySize))
    End Function
End Class
Now to use it you need a few bits of information:

Code:
        Dim password As String = "password123" 'password
        Dim salt As String = "salty" 'extra protection for the password
        Dim initVector As Byte() = Encoding.ASCII.GetBytes(New String("*"c, 16)) '16-byte init vector.

        Dim phrase As String = "this is some piece of text, it is quite nice" 'data to be encrypted.

        Dim encrypted As Byte() = SimpleRijndael.EncryptString(phrase, password, salt, initVector) 'encrypted data.
        Dim decrypted As String = SimpleRijndael.DecryptString(encrypted, password, salt, initVector) 'decrypted data.

        MessageBox.Show(decrypted)
Thanks a lot, but I have never done encryption/decryption before. So it's a little confusing... So lets explain this a bit.

First, we have the password to be encrypted, which for me would be a textbox.
Second, we have extra protection for the password. (Which I assume can be anything, not just 'salty')
Third, we have the vector.
Fourth, we have more data to be encrypted.. which I assume is extra data? I only need to encrypt the password.
Fifth, we have the encrypted byte, which holds the phrase, password, salt, and initvector.
Sixth, we have the decrypted string, which holds the encrypted, password, salt, and initvector.
Lastly, we can show the decrypted data, which I will use when the forum starts to put the password in the textbox.

I put the password and the phrase as the textbox(password), which seems to work fine.
But, I cannot save the encrypted, which I assume because it's a byte.. Using the method -
Code:
My.Computer.FileSystem.WriteAllText("C:\program files\pw.txt", encrypted, True)
Even using a message box trying to show the encrypted data, nothing happens, no errors.

Also, in the notes you say

the initVector parameter MUST BE 16 BYTES. No more, no less. - Not too sure what it does, but apparently it Holds the initialization vector for chain-mode encryption.
keySize can ONLY take the values 128, 192 or 256. Anything else will break. - Not too sure what it does, but apparently it Determines the set of valid key sizes for the symmetric cryptographic algorithms.
salt should be 8 characters or longer, but the function will allocate more characters for you if needs be. - The salt, as stated above, is extra protection for the password.
I'm pretty confused on that too.. Honestly, I just don't want to C+P, I want to know how this works.
Quote Originally Posted by Cryptonic View Post
Thanks a lot, but I have never done encryption/decryption before. So it's a little confusing... So lets explain this a bit.

First, we have the password to be encrypted, which for me would be a textbox.
Second, we have extra protection for the password. (Which I assume can be anything, not just 'salty')
Third, we have the vector.
Fourth, we have more data to be encrypted.. which I assume is extra data? I only need to encrypt the password.
Fifth, we have the encrypted byte, which holds the phrase, password, salt, and initvector.
Sixth, we have the decrypted string, which holds the encrypted, password, salt, and initvector.
Lastly, we can show the decrypted data, which I will use when the forum starts to put the password in the textbox.

I put the password and the phrase as the textbox(password), which seems to work fine.
But, I cannot save the encrypted, which I assume because it's a byte.. Using the method -
Code:
My.Computer.FileSystem.WriteAllText("C:\program files\pw.txt", encrypted, True)
Even using a message box trying to show the encrypted data, nothing happens, no errors.

Also, in the notes you say



I'm pretty confused on that too.. Honestly, I just don't want to C+P, I want to know how this works.
Okay, "password" isn't the password you want to encrypt. The fact that you want to encrypt a password is purely coincidental.
Bear in mind that this class wasn't written for your exact case, it's just a simple implementation of the Rijndael encryption algorithm.

The password is your "key" to decrypt the data again. Typically you'd set the key once, and use that to encrypt/decrypt all your passwords.
The "salt" is just an extra bit of data that ties in with the above "password" field for more unique key generation. This can be anything you want.

I found an answer on stack overflow that further abstracts this down to something really simple that you can use:

Code:
Imports System****
Imports System.Security.Cryptography
Imports System.Text

Public Class SimpleCrypto
    Private Shared ReadOnly AES_SALT As Byte() = Encoding.ASCII.GetBytes("x78%Ef21")

    Public Shared Function EncryptStringAES(ByVal plainText As String, ByVal secretKey As String) As String
        If String.IsNullOrEmpty(plainText) Then
            Throw New ArgumentNullException("plainText")
        End If
        If String.IsNullOrEmpty(secretKey) Then
            Throw New ArgumentNullException("sharedSecret")
        End If


        Dim data As Byte() = Encoding.ASCII.GetBytes(plainText)
        Dim key As New Rfc2898DeriveBytes(secretKey, AES_SALT)

        Using aesAlg = New RijndaelManaged()
            aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8)
            Using encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
                Using msEncrypt = New MemoryStream()
                    msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, 4)
                    msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length)
                    Using csEncrypt = New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                        csEncrypt.Write(data, 0, data.Length)
                        csEncrypt.FlushFinalBlock()
                        Return Convert.ToBase64String(msEncrypt.ToArray())
                    End Using
                End Using
            End Using
        End Using

    End Function

    Public Shared Function DecryptStringAES(ByVal cipherText As String, ByVal sharedSecret As String) As String
        If String.IsNullOrEmpty(cipherText) Then
            Throw New ArgumentNullException("cipherText")
        End If
        If String.IsNullOrEmpty(sharedSecret) Then
            Throw New ArgumentNullException("sharedSecret")
        End If

        Dim key As New Rfc2898DeriveBytes(sharedSecret, AES_SALT)
        Dim bytes As Byte() = Convert.FromBase64String(cipherText)

        Using aesAlg = New RijndaelManaged()
            Using msDecrypt As New MemoryStream(bytes)
                aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8)
                aesAlg.IV = RetrieveIV(msDecrypt)
                Using decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)
                    Using csDecrypt = New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
                        Return New StreamReader(csDecrypt).ReadToEnd()
                    End Using
                End Using
            End Using
        End Using
    End Function

    Private Shared Function RetrieveIV(ByVal s As Stream) As Byte()
        Dim rawLength As Byte() = New Byte(4 - 1) {}
        If s.Read(rawLength, 0, rawLength.Length) <> rawLength.Length Then
            Throw New SystemException("Stream did not contain properly formatted byte array")
        End If

        Dim buffer As Byte() = New Byte(BitConverter.ToInt32(rawLength, 0) - 1) {}
        If s.Read(buffer, 0, buffer.Length) <> buffer.Length Then
            Throw New SystemException("Did not read byte array properly")
        End If

        Return buffer
    End Function
End Class
And here's my example:

Code:
       Dim password As String = "secretpassword123" 'this is the user's password to encrypt.
        Dim secret As String = "supersecretawesomehappyfuntime789" 'this is the key you will use to encrypt/decrypt the passwords. It must match the secret key you used when encrypting.

        Dim enryptedPassword As String = SimpleCrypto.EncryptStringAES(password, secret) 'you can now write this value to a file or something.
        Dim decryptedPassword As String = SimpleCrypto.DecryptStringAES(enryptedPassword, secret) 'just showing you how to reverse the process.

        Console.WriteLine(decryptedPassword) 'omg it sais "secretpassword123"!!!!!!
        Console.Read()
Should be easier to use now.
EDIT: I realized that the Secret won't be the same.. OHHHH. I fail. Nvm, I fixed it.. Just noticed the secret could be anything...

Thanks a lot for your help, Jason.
Posts 31–39 of 39 · Page 3 of 3

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?