HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Vulnerability of Encryption class using AES + HMAC

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
encryptionvulnerabilityaeshmacusingclass

Problem

I've written an encryption-decryption class that is to be used in my companies commercial web application that will handle sensitive information. The encrypted data will be passed over the internet via HTTPS but even so it needs to be internally secure.

I've tried to follow best practices but I'm limited in that I only have a password available to use as a key. I found what appears to be a good solution here (the second answer) which I've used as a base for this class:

```
'''
''' Class that provides encryption using AES with HMAC for authentication.
'''
'''
Public NotInheritable Class AESHMACEncryption

'See https://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string/10366194#10366194
'and http://dotnetslackers.com/articles/security/hashing_macs_and_digital_signatures_in_net.aspx

'''
''' Encrypt the given text using the given password and create an authenticated message that can be decrypted by AESHMAC.Decrypt.
'''
''' String
''' String
''' String
''' AES encryption with HMAC.
Shared Function Encrypt(cleartext As String, password As String) As String

'Sanity checks
If password.Length
''' Decrypt a message encrypted using AESHMAC.Encrypt.
'''
''' String
''' String
''' String
''' AES encryption with HMAC.
Public Shared Function Decrypt(encrypted As String, password As String) As String

'Sanity checks
If password.Length 0 Then Throw New Exception("Message does not pass authentication.")

Using cryptoProvider As New AesCryptoServiceProvider() With {
.KeySize = EncryptionSettings.KeyBitSize,
.BlockSize = EncryptionSettings.BlockBitSize,
.Mode = CipherMode.CBC,
.Padding = PaddingMode.PKCS7
}

'Grab IV from message
Dim iv = New Byte(ivLength - 1) {}
Array.Copy(encryptedMessage, SaltsLength, iv, 0, iv.Length)

Solution

This isn't anything huge or anything,

you can actually get rid of

Dim plaintext As String


This variable is only used to return a value, and you don't need to assign the value to this variable before you return it. by creating a variable you are assigning memory that could be used for other things. Encryption applications can get heavy while a couple of empty variables worth of memory may not wipe out the available memory, it is a good habit to break.

Don't create variables that you don't have to.

The value can be returned directly from inside the using statements.

right here

Using decrypter As ICryptoTransform = cryptoProvider.CreateDecryptor(kspCrypt.Key, iv)
    Using plainTextStream As New MemoryStream()
        Using decrypterStream As New CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write)
            Using binaryWriter As New BinaryWriter(decrypterStream)
                'Decrypt Cipher Text from Message
                binaryWriter.Write(encryptedMessage, SaltsLength + iv.Length, encryptedMessage.Length - SaltsLength - iv.Length - sentTag.Length)
            End Using
        End Using
        'Return Plain Text
        plaintext = Encoding.UTF8.GetString(plainTextStream.ToArray())
    End Using
End Using


just change it to this instead

Using decrypter As ICryptoTransform = cryptoProvider.CreateDecryptor(kspCrypt.Key, iv)
     Using plainTextStream As New MemoryStream()
         Using decrypterStream As New CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write)
             Using binaryWriter As New BinaryWriter(decrypterStream)
                 'Decrypt Cipher Text from Message
                 binaryWriter.Write(encryptedMessage, SaltsLength + iv.Length, encryptedMessage.Length - SaltsLength - iv.Length - sentTag.Length)
             End Using
         End Using
         'Return Plain Text
         return Encoding.UTF8.GetString(plainTextStream.ToArray())
     End Using
 End Using


just

return Encoding.UTF8.GetString(plainTextStream.ToArray())


Same with this

Dim encryptedtext As String = Convert.ToBase64String(signed)
Return encryptedtext


you can do this inside the using statement in a single return statement

just like this

return Convert.ToBase64String(encryptedStream.ToArray())


then you get rid of 2 more variables

Dim signed As Byte()


And

Dim encryptedtext As String = Convert.ToBase64String(signed)

Code Snippets

Dim plaintext As String
Using decrypter As ICryptoTransform = cryptoProvider.CreateDecryptor(kspCrypt.Key, iv)
    Using plainTextStream As New MemoryStream()
        Using decrypterStream As New CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write)
            Using binaryWriter As New BinaryWriter(decrypterStream)
                'Decrypt Cipher Text from Message
                binaryWriter.Write(encryptedMessage, SaltsLength + iv.Length, encryptedMessage.Length - SaltsLength - iv.Length - sentTag.Length)
            End Using
        End Using
        'Return Plain Text
        plaintext = Encoding.UTF8.GetString(plainTextStream.ToArray())
    End Using
End Using
Using decrypter As ICryptoTransform = cryptoProvider.CreateDecryptor(kspCrypt.Key, iv)
     Using plainTextStream As New MemoryStream()
         Using decrypterStream As New CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write)
             Using binaryWriter As New BinaryWriter(decrypterStream)
                 'Decrypt Cipher Text from Message
                 binaryWriter.Write(encryptedMessage, SaltsLength + iv.Length, encryptedMessage.Length - SaltsLength - iv.Length - sentTag.Length)
             End Using
         End Using
         'Return Plain Text
         return Encoding.UTF8.GetString(plainTextStream.ToArray())
     End Using
 End Using
return Encoding.UTF8.GetString(plainTextStream.ToArray())
Dim encryptedtext As String = Convert.ToBase64String(signed)
Return encryptedtext

Context

StackExchange Code Review Q#91143, answer score: 3

Revisions (0)

No revisions yet.