Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General String Encryption

I am looking for a general string encryption class in .NET. (Not to be confused with the 'SecureString' class.)

I have started to come up with my own class, but thought there must be a .NET class that already allows you to encrypt/decrypt strings of any encoding with any Cryptographic Service Provider.

Public Class SecureString

        Private key() As Byte
        Private iv() As Byte
        Private m_SecureString As String

        Public ReadOnly Property Encrypted() As String
            Get
                Return m_SecureString
            End Get
        End Property

        Public ReadOnly Property Decrypted() As String
            Get
                Return Decrypt(m_SecureString)
            End Get
        End Property

        Public Sub New(ByVal StringToSecure As String)
            If StringToSecure Is Nothing Then StringToSecure = ""
            m_SecureString = Encrypt(StringToSecure)
        End Sub

        Private Function Encrypt(ByVal StringToEncrypt As String) As String

            Dim result As String = ""
            Dim bytes() As Byte = Text.Encoding.UTF8.GetBytes(StringToEncrypt)

            Using provider As New AesCryptoServiceProvider()

                With provider
                    .Mode = CipherMode.CBC                  
                    .GenerateKey()
                    .GenerateIV()
                    key = .Key
                    iv = .IV
                End With

                Using ms As New IO.MemoryStream
                    Using cs As New CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write)
                        cs.Write(bytes, 0, bytes.Length)
                        cs.FlushFinalBlock()
                    End Using
                    result = Convert.ToBase64String(ms.ToArray())
                End Using

            End Using

            Return result

        End Function

        Private Function Decrypt(ByVal StringToDecrypt As String) As String

            Dim result As String = ""
            Dim bytes() As Byte = Convert.FromBase64String(StringToDecrypt)

            Using provider As New AesCryptoServiceProvider()

                Using ms As New IO.MemoryStream
                    Using cs As New CryptoStream(ms, provider.CreateDecryptor(key, iv), CryptoStreamMode.Write)
                        cs.Write(bytes, 0, bytes.Length)
                        cs.FlushFinalBlock()
                    End Using
                    result = Text.Encoding.UTF8.GetString(ms.ToArray())
                End Using

            End Using

            Return result

        End Function

    End Class
like image 279
user111370 Avatar asked May 23 '09 01:05

user111370


2 Answers

The AES algorithm for symmetric encryption is generally the way to go for generic encryption of strings. However, I'm afraid that the .NET BCL doesn't simplify things any further for you the providing the basic encryption/decryption classes and functions.

You can find a good example of how to use the crypographic classes specifically for string encryption on this page. It appears to be very complete and well commented indeed - you may even find that you can use it without any further modifications. Note: Rijndael is the same algorithm as AES. (Technically, the former refers to the algorithm's real name, and the latter the Advanced Encryption Standard.)

like image 193
Noldorin Avatar answered Oct 25 '22 15:10

Noldorin


If you are trying to achieve the same goal as .NET's SecureString, then your example really doesn't solve the problem. (I could be misunderstanding your goals, in which case I apologize.)

The idea of .NET's SecureString is that it stores the string data encrypted in a non-managed chunk of memory, is immutable once created, and can not be read in .NET using a normal string variable. This protects the string from anyone trying to probe your memory space (i.e. malware, worm, Trojan, whatever), and must be explicitly cleaned up by you. The reasons for this involve how .NET treats strings, and the fact that data in memory is only cleaned up at the whim of the GC.

Even though your SecureString class encrypts the string into a private variable, the original string that was passed in is still insecure. It can also stick around for a while before the GC collects it, or, if that string was interned, it will live for the duration of the process it resides within. Interned strings are stored in a table, which makes them easier to find, too.

On the other side of things...if you Decrypt your SecureString, your getting a new string variable that could run into the same problems as the input string...it is only cleaned up when the GC decides to...and it also may end up interned and live for the duration of the process.

To compound problems, every time you Decrypt, you are getting another copy of your encrypted string. This could build up a surplus of decrypted versions of your secure string, increasing the chances that some piece of malware that is probing for, say, credit card numbers...will actually find one.

I have tried many times to create a better, more .NET like version of .NET 2.0's SecureString, but have never been able to produce something that is truly secure. You could get a pointer to the string variable that was decrypted, wipe it, set each character to nil, etc. However this could be very problematic in the even that something is still referencing that string, causing disappearing text, corrupted reads, etc. If the string is interned, which generally means it is being used by many things for a long duration of time, wiping it wipes the only version, and affects all use of it. Even if you managed to successfully wipe a copy of your secure string, there is no guarantee that it wasn't copied by other code before you wiped it (i.e. you send your string off to some web service...it now lives in more than one process space, quite possibly in different physical locations around the world.)

Its definitely a complicated issue, and only really provides security in the event that your application's memory space has been compromised by malware of some sort.

like image 3
jrista Avatar answered Oct 25 '22 13:10

jrista