1
\$\begingroup\$

How secure is this encryption? Secondly, is there something I could do to "turn it up a notch" and make it 'more' secure?

Imports System.Security.Cryptography

Public Class clsCrypt
Private TripleDES As New TripleDESCryptoServiceProvider

'create and return the key and initialization vector hash
Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()

    Dim sha1 As New SHA1CryptoServiceProvider

    ' Hash the key. 
    Dim keyBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(key)
    Dim hash() As Byte = sha1.ComputeHash(keyBytes)

    ' Truncate or pad the hash. 
    ReDim Preserve hash(length - 1)
    Return hash

End Function

'initialize the class
Sub New(ByVal key As String)

    ' Initialize the crypto provider.
    TripleDES.Key = TruncateHash(key, TripleDES.KeySize \ 8)
    TripleDES.IV = TruncateHash("", TripleDES.BlockSize \ 8)

End Sub

'encrypt the passed text
Public Function EncryptData(ByVal plaintext As String) As String

    ' Convert the plaintext string to a byte array. 
    Dim plaintextBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext)

    ' Create the stream. 
    Dim ms As New System.IO.MemoryStream

    ' Create the encoder to write to the stream. 
    Dim encStream As New CryptoStream(ms, TripleDES.CreateEncryptor(),
                                      System.Security.Cryptography.CryptoStreamMode.Write)

    ' Use the crypto stream to write the byte array to the stream.
    encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
    encStream.FlushFinalBlock()

    ' Convert the encrypted stream to a printable string. 
    Return Convert.ToBase64String(ms.ToArray)

End Function

'decrypt passed text
Public Function DecryptData(ByVal encryptedtext As String) As String

    ' Convert the encrypted text string to a byte array. 
    Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext)

    ' Create the stream. 
    Dim ms As New System.IO.MemoryStream

    ' Create the decoder to write to the stream. 
    Dim decStream As New CryptoStream(ms, TripleDES.CreateDecryptor(),
                                      System.Security.Cryptography.CryptoStreamMode.Write)

    ' Use the crypto stream to write the byte array to the stream.
    decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
    decStream.FlushFinalBlock()

    ' Convert the plaintext stream to a string. 
    Return System.Text.Encoding.Unicode.GetString(ms.ToArray)

End Function
End Class

Lastly, would this encryption class function the same if I passed in a different key in different Subs? Example:

Private Sub EmployeeFrm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    Dim strKey As String = "Key1" 'encryption Key
    Dim clsEncrypt As clsCrypt         'Assigns a variable to clsCrypt class
    clsEncrypt = New clsCrypt(strKey)   ' creates a new isntance of the clsCrypt class

And also:

Private Sub InsertBtn_Click(sender As System.Object, e As System.EventArgs) Handles InsertBtn.Click

    Dim strKey As String = "Strong3rKeY!" 'encryption Key
    Dim clsEncrypt As clsCrypt         'Assigns a variable to clsCrypt class
    clsEncrypt = New clsCrypt(strKey)   ' creates a new isntance of the clsCrypt class

Both are in the same form, just during different events.

Is this even a good way to utilize encryption? I am using it to encrypt specific strings and insert them into the database.

\$\endgroup\$
2
\$\begingroup\$

Some issues:

  1. No MAC => say hello to padding oracles. This is fatal flaw that allows decryption of the message in many usage scenarios (when there is an active attacker).
  2. You use CBC mode with constant IV. A new IV must be chosen for each message. It should be unpredictable and random.
  3. Your keying is only secure with really strong passwords (over 100 bits of entropy). I recommend using an actual binary key drawn from a secure CSPRNG encoded with Base64 instead of a password.

    A related stylistic problem is that you don't clearly distinguish between keys (which should be uniformly random) and passwords.

  4. Does the key ever leave the trusted systems? It looks like you're hardcoding a key into a client, which might run on an untrusted machine. Even if it stays on the server, put it in a config file, not the code.

    Your program should be secure even if the whole code is known. Logistically it's also much easier to keep a config file secure, since it doesn't need to be checked into version control.

  5. Why would you choose 3DES over AES in new code? AES is faster and stronger. It also has 128 bit blocks instead of 64 bit blocks, so it doesn't weaken once you encrypt a couple of gigabytes using the same key.

  6. All those streams are unnecessarily complicated. Simply call encryptor.TransformFinalBlock on a byte array instead.
\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply! I am really quite new (typical response) so I don't know all the 'ins and outs' of what you're saying. For example, MAC, CBC mode, #6. The Key is being hardcoded in because I'm not sure how else to pass it into the Encryption Class. Referring to your suggestion, if I put the key in a config file, how do I utilize it? Or is that just for storing? Feel free to edit my OP as you deem necessary, if you'd like to elaborate on some of my areas in which I lack knowledge. Thanks! \$\endgroup\$ – Mark Feb 28 '14 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.