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
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With