Encrypt/Decrypt data in Vb.net and SQL Server - vb.net

I currently use two functions, in a VB.net application, to encrypt/decrypt sensitive data (e.g. SSNs). I then store the encrypted data in a SQL Server database. Then, when reading data from SQL Server, the application decrypts it for display. This works just fine.
The problem with this solution is that it makes it impossible to write simple SQL queries that include those encrypted fields as the data that comes back is encrypted. I want to be able to run queries that return the data that was stored in encrypted format, in its original format (i.e. the actual, unencrypted data).
What is the best practice for accomplishing this? Should I not be using functions in the VB.net application, but rather using functions in SQL Server, for example? Or, do I need to create a DLL or something that has the two aforementioned functions that I then need to "install" somehow, so that they can be called from SQL Server? I am using SQL Server 2008 and Visual Studio 2017.
In case it's relevant, I have included the code for the functions.
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Public Function Decrypt(ByVal sStringToDecrypt As String, _
ByVal sEncryptionKey As String) As String
Dim inputByteArray(sStringToDecrypt.Length) As Byte
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
inputByteArray = Convert.FromBase64String(sStringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function
Public Function Encrypt(ByVal sStringToEncrypt As String, _
ByVal SEncryptionKey As String) As String
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
sStringToEncrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function

Related

OutOfMemoryException while using CryptoStream with large Strings in VB.NET

my program runs into a OutOfMemoryException when I use large Strings with the following method.
Public Function EncryptData(ByVal plaintext As String) As String
Dim plaintextBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext)
Dim ms As New System.IO.MemoryStream
Dim encStream As New CryptoStream(ms, TripleDes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
encStream.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray)
End Function
The following Line is causing the exception:
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
How can I fix this problem? My method works fine with short strings.

Can't read an XML in Stream

I have a little problem with an XML file and a Stream. I create and save an XML file in a Stream, encrypt the Stream and then save it to a normal file.
I want to read this XML, however I can only do this if I use a FileStream and write a decrypted file to disk.
Is there a way to decrypt and keep this file in memory?
This is my code:
XMLDecriptato = New MemoryStream()
Using stream_readerX As New StreamReader(XMLDecriptato, Text.Encoding.UTF8)
XMLDecriptato.SetLength(0)
Dim FStreamCrypted As FileStream = File.Open(varTitolo, FileMode.Open, FileAccess.Read)
FStreamCrypted.Seek(0, SeekOrigin.Begin)
CryptStream(Pass, FStreamCrypted, XMLDecriptato, Type.Decrypt)
'try to read the stream
Dim xDocumentX As New XmlDocument()
xDocumentX.Load(stream_readerX) 'here is the error
End Using
It keeps saying that the Stream is closed. I have tried also another way. The only one that works is to write the stream to the hard disk with a FileStream.
And that is the Encrypt/Decrypt Sub:
Public Sub CryptStream(ByVal Psw As String, ByVal IN_Stream As Stream, ByVal OUT_Stream As Stream, ByVal CrtType As CryptType)
Dim AES_Provider As New AesCryptoServiceProvider()
Dim Key_Size_Bits As Integer = 0
For i As Integer = 1024 To 1 Step -1
If (aes_provider.ValidKeySize(i)) Then
Key_Size_Bits = i
Exit For
End If
Next i
Dim Block_Size_Bits As Integer = AES_Provider.BlockSize
Dim Key() As Byte = Nothing
Dim IV() As Byte = Nothing
Dim Salt() As Byte = "//my salt//"
MakeKeyAndIV(Psw, Salt, Key_Size_Bits, Block_Size_Bits, Key, IV)
Dim Crypto_Transform As ICryptoTransform = Nothing
Select Case CrtType
Case CryptType.Encrypt
Crypto_Transform = AES_Provider.CreateEncryptor(key, iv)
Case CryptType.Decrypt
Crypto_Transform = AES_Provider.CreateDecryptor(key, iv)
End Select
If Crypto_Transform Is Nothing Then Exit Sub
Try
Using Crypto_Stream As New CryptoStream(OUT_Stream, Crypto_Transform, CryptoStreamMode.Write)
Const Block_Size As Integer = 1024
Dim Buffer(Block_Size) As Byte
Dim Bytes_Read As Integer
Do
Bytes_Read = IN_Stream.Read(Buffer, 0, Block_Size)
If (Bytes_Read = 0) Then Exit Do
Crypto_Stream.Write(Buffer, 0, Bytes_Read)
Loop
End Using
Catch ex As Exception
End Try
Crypto_Transform.Dispose()
End Sub
It turns out that when CryptoStream.Dispose() is called by the Using/End Using block, the CryptoStream also disposes the underlying stream (in this case your MemoryStream). This behaviour can be confirmed by checking Microsoft's Reference Source.
Since the CryptoStream doesn't have a LeaveOpen flag like the StreamReader does since .NET 4.5 and up, I removed the Using block and wrote the necessary calls on my own for your method.
The changes:
Public Sub CryptStream(ByVal Psw As String, ByVal IN_Stream As Stream, ByVal OUT_Stream As Stream, ByVal CrtType As CryptType, Optional ByVal LeaveOpen As Boolean = False)
...code...
Try
Dim Crypto_Stream As New CryptoStream(OUT_Stream, Crypto_Transform, CryptoStreamMode.Write)
Const Block_Size As Integer = 1024
Dim Buffer(Block_Size) As Byte
Dim Bytes_Read As Integer
Do
Bytes_Read = IN_Stream.Read(Buffer, 0, Block_Size)
If (Bytes_Read = 0) Then Exit Do
Crypto_Stream.Write(Buffer, 0, Bytes_Read)
Loop
If Crypto_Stream.HasFlushedFinalBlock = False Then Crypto_Stream.FlushFinalBlock()
If LeaveOpen = False Then
Crypto_Stream.Dispose()
End If
Catch ex As Exception
End Try
...code...
End Sub
And since data will be fed into the MemoryStream its position will have changed, so you have to reset that too before loading the XML document:
XMLDecriptato = New MemoryStream()
Using stream_readerX As New StreamReader(XMLDecriptato, System.Text.Encoding.UTF8)
Dim FStreamCrypted As FileStream = File.Open(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
CryptStream(Pass, FStreamCrypted, XMLDecriptato, CryptType.Decrypt, True) 'True = Leave the underlying stream open.
XMLDecriptato.Seek(0, SeekOrigin.Begin) 'Reset the MemoryStream's position.
Dim xDocumentX As New XmlDocument()
xDocumentX.Load(stream_readerX)
End Using
As you might have noticed I removed the FStreamCrypted.Seek(0, SeekOrigin.Begin) line. This was because you've just opened the stream and done nothing with it, so the position will already be at 0.
Hope this helps!

SqlFileStream writing in separate thread not working

Learning and testing using Sql FILESTREAM for a web app. A client uploads a large file form the web page which takes 'X' time and when fully uploaded shows 100% complete. However, very large files also take time for SqlFileStream to write to the file system so I want to spin off a thread to complete that part. The code I've got seems to work fine but no data ends up in the filestream file.
I'm wrapping the initial record creation in it's own transaction scope and using a separate transaction scope in the thread. In the threaded routine I have the appropriate PathName() and TransactionContext but I assume I'm missing something while using a thread.
I've commented out the normal SqlFileStream call which works fine. Can you see anything wrong with what I'm doing here?
Public Function StoreFileStream()
Dim json As New Dictionary(Of String, Object)
Dim parms As New FileStreamThreadParameters
If HttpContext.Current.Request.Files.Count > 0 Then
Dim file As HttpPostedFile = HttpContext.Current.Request.Files(0)
If "contentType" <> String.Empty Then
Dim fs As Stream = file.InputStream
Dim br As New BinaryReader(fs)
Dim noBytes As New Byte()
Try
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Dim baseFileId As Integer
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsConnStr)
Using dbCmd As New SqlCommand("ADD_FileStreamFile", dbConn)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
baseFileId = dbRdr("BaseFileID")
End If
dbRdr.Close()
End Using
' Code below writes to file, but trying to offload this to a separate thread so user is not waiting
'Using dest As New SqlFileStream(filePath, trxContext, FileAccess.Write)
' fs.CopyTo(dest, 4096)
' dest.Close()
'End Using
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using ' transaction commits here, not in line above
parms.baseFileId = baseFileId
parms.fs = New MemoryStream
fs.CopyTo(parms.fs)
Dim fileUpdateThread As New Threading.Thread(Sub()
UpdateFileStreamThreaded(parms)
End Sub)
fileUpdateThread.Start()
json.Add("status", "success")
Catch ex As Exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
json.Add("status", "failure")
json.Add("msg", ex.Message)
json.Add("procedure", System.Reflection.MethodBase.GetCurrentMethod.Name)
End Try
Else
json.Add("status", "failure")
json.Add("msg", "Invalid file type")
json.Add("procedure", System.Reflection.MethodBase.GetCurrentMethod.Name)
End If
End If
Return json
End Function
Public Class FileStreamThreadParameters
Public Property baseFileId As Integer
Public fs As Stream
End Class
Private Sub UpdateFileStreamThreaded(parms As FileStreamThreadParameters)
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Try
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsConnStr)
Using dbCmd As New SqlCommand("SELECT FileBytes.PathName() 'Path', GET_FILESTREAM_TRANSACTION_CONTEXT() 'TrxContext' FROM FileStreamFile WHERE Id = " & parms.baseFileId, dbConn)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
End If
dbRdr.Close()
Using dest As New SqlFileStream(filePath, trxContext, FileAccess.Write)
parms.fs.CopyTo(dest, 4096)
dest.Close()
End Using
End Using
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using
Catch ex As Exception
'Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
End Try
End Sub
Obviously this is a complex issue. I actually got it to work with the code below. However I eventually abandoned using SQL FILESTREAM altogether due to too much complexity in getting it all set up.
This is an existing web application with the sql server on a different box. After I got the filestreaming to work the next hurdle was authentication setup. Filestream requires Integrated Security on your connection string. Even with windows authentication on our Intranet app, I could not get the web app to use the windows credentials when connecting to the database. It always seemed to use the computer name or the app pool service. I tried many many examples I found on the net and here to no avail. Even if I got that to work then I would want to use and Active Directory group over individual logins which looked to be another hurdle.
This app stores documents in a varbinary column so that full text search can be enabled at some point. The issue was with large files which are generally pictures or videos. Since you can't search text on those anyway the strategy now is to store those on the file system and all other searchable docs (.docx, .pptx, etc) will still be stored in the varbinary. I'm actually sad that I could not get filestream to work as it seems like the ideal solution. I'll come back to it some day but it really should not be so frickin complicated. :-(
The code I got working is:
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Dim baseFileId As Integer
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsFSConnStr)
Using dbCmd As New SqlCommand("NEW_FileStreamBaseFile", dbConn)
dbCmd.CommandType = CommandType.StoredProcedure
dbCmd.Parameters.AddWithValue("#Title", fileDesc)
dbCmd.Parameters.AddWithValue("#Summary", summary)
dbCmd.Parameters.AddWithValue("#Comments", comments)
dbCmd.Parameters.AddWithValue("#FileName", uploadedFileName)
dbCmd.Parameters.AddWithValue("#ContentType", contentType)
dbCmd.Parameters.AddWithValue("#FileExt", ext)
'dbCmd.Parameters.AddWithValue("#FileBytes", noBytes) ' now that were offloading the file byte storage to a thread
dbCmd.Parameters.AddWithValue("#UploadedByResourceID", uploadedByResourceID)
dbCmd.Parameters.AddWithValue("#UploadedByShortName", uploadedByShortName)
dbCmd.Parameters.AddWithValue("#FileAuthor", fileAuthor)
dbCmd.Parameters.AddWithValue("#TagRecID", tagRecID)
dbCmd.Parameters.AddWithValue("#UserID", samAccountName)
dbCmd.Parameters.AddWithValue("#FileDate", fileDate)
dbCmd.Parameters.AddWithValue("#FileType", fileType)
dbCmd.Parameters.AddWithValue("#FileTypeRecID", fileTypeRecId)
' Save to file system too for xod conversion
file.SaveAs(HttpContext.Current.Server.MapPath("~/files/uploaded/") & uploadedFileName)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
json.Add("baseFileId", dbRdr("BaseFileID"))
virtualFileRecId = dbRdr("VirtualFileRecID")
dbStatus = dbRdr("status")
If dbStatus = "failure" Then
json.Add("msg", dbRdr("msg"))
End If
End If
dbRdr.Close()
End Using
' Prepare and start Task thread to write the file
If dbStatus = "success" Then
bytes = br.ReadBytes(fs.Length)
Dim task As New System.Threading.Tasks.Task(
Sub()
UpdateNewFileStreamBytes(virtualFileRecId, bytes)
End Sub)
task.Start()
json.Add("status", "success")
Else
json.Add("status", "failure")
End If
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using ' transaction commits here, not in line above
With the task procedure of:
Private Sub UpdateNewFileStreamBytes(virtualFileRecId As Integer, fileBytes As Byte())
Dim filePath As String = ""
Dim trxContext As Byte() = {}
Try
Using trxScope As New TransactionScope
Using dbConn As New SqlConnection(DigsFSConnStr)
Using dbCmd As New SqlCommand("UPD_FileStreamBaseFile", dbConn)
dbCmd.CommandType = CommandType.StoredProcedure
dbCmd.Parameters.AddWithValue("#VirtualFileRecID", virtualFileRecId)
dbConn.Open()
Using dbRdr As SqlDataReader = dbCmd.ExecuteReader(CommandBehavior.SingleRow)
dbRdr.Read()
If dbRdr.HasRows Then
filePath = dbRdr("Path")
trxContext = dbRdr("TrxContext")
End If
dbRdr.Close()
Using dest As New SqlFileStream(filePath, trxContext, FileAccess.Write)
dest.Write(fileBytes, 0, fileBytes.Length)
dest.Close()
End Using
End Using
End Using
dbConn.Close()
End Using
trxScope.Complete()
End Using
Catch ex As Exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
End Try

Standard library for AES encryption for VB.NET?

Is there a standard library to use for AES encryption for VB.NET? I want to encrypt a string with a static private key.
I googled and found a lot of variations. I don't really know how to determine which algorithms are secure or not.
The System.Security.Cryptography namespace contains all the classes you need to perform most standard encryption tasks. Unfortunately, since encryption is a rather complicated topic, the classes are somewhat difficult to work with--especially for beginners. It's sometimes difficult to find a simple working example to start with. But, since I'm nice, I'll provide you with a simple example that you can play with and improve upon :)
The class you probably want to use is called RijndaelManaged. That is the class that implements the typical AES encryption. Here's a sample class that uses that to convert between plain text strings and byte arrays:
Public Class Aes256Encrypter
Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As Byte()
Dim encryptedPassword As Byte()
Using outputStream As MemoryStream = New MemoryStream()
Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
cryptoStream.FlushFinalBlock()
encryptedPassword = outputStream.ToArray()
End Using
End Using
Return encryptedPassword
End Function
Public Function Decrypt(ByVal encryptedBytes As Byte(), ByVal secretKey As String) As String
Dim plainText As String = Nothing
Using inputStream As MemoryStream = New MemoryStream(encryptedBytes)
Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
End Using
End Using
Return plainText
End Function
Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
Const salt As String = "put your salt here"
Const keySize As Integer = 256
Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
Dim algorithm As RijndaelManaged = New RijndaelManaged()
algorithm.KeySize = keySize
algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
algorithm.Padding = PaddingMode.PKCS7
Return algorithm
End Function
End Class
You should change the salt constant to something else. Ideally, it wouldn't even be a constant, since, to make it as secure as possible, you should use a different salt each time you perform the encryption, but that's a whole other topic.
If you want to have the encrypted value returned as a string instead of as a byte array, you can use Base-64 encoding to convert the byte array to, and from, strings, like this:
Public Class Aes256Base64Encrypter
Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As String
Dim encryptedPassword As String = Nothing
Using outputStream As MemoryStream = New MemoryStream()
Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
cryptoStream.FlushFinalBlock()
encryptedPassword = Convert.ToBase64String(outputStream.ToArray())
End Using
End Using
Return encryptedPassword
End Function
Public Function Decrypt(ByVal encryptedBytes As String, ByVal secretKey As String) As String
Dim plainText As String = Nothing
Using inputStream As MemoryStream = New MemoryStream(Convert.FromBase64String(encryptedBytes))
Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
End Using
End Using
Return plainText
End Function
Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
Const salt As String = "put your salt here"
Const keySize As Integer = 256
Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
Dim algorithm As RijndaelManaged = New RijndaelManaged()
algorithm.KeySize = keySize
algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
algorithm.Padding = PaddingMode.PKCS7
Return algorithm
End Function
End Class
If you are storing the encrypted value in a text file, XML file, or even a database, it's often easier to just use Base-64, like that.
There exist high-level encryption libraries that handle the subtle details of encryption so you don't make those mistakes, Keyczar, Nacl, GPGME.
I ported Keyczar to .net and it uses AES for it's default symmetric encryption.
You use a command line program to create a key set with a random AES key.
:> KeyczarTool.exe create --location=path_to_key_set --purpose=crypt
:> KeyczarTool.exe addkey --location=path_to_key_set --status=primary
In your project to encrypt,
Using encrypter As New Encrypter("path_to_key_set")
Return encrypter.Encrypt(plaintext)
End Using
And then to decrypt
Using crypter As new Crypter("path_to_key_set")
Return crypter.Decrypt(ciphertext)
End Using

Encryption of email address in vb.net

I would like to know how I can encrypt an email address via vb.net code.
I found one sample which doesn't quite work with special characters and I am getting this error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.
Here is the code I am trying:
'The function used to encrypt the text
Private Function Encrypt(ByVal strText As String, ByVal strEncrKey _
As String) As String
Dim byKey() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Try
byKey = System.Text.Encoding.UTF8.GetBytes(Left(strEncrKey, 8))
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(strText)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function
What do you guys think? What am I doing wrong?
Thanks, Laziale
UPDATE: Full Stack trace:
System.FormatException was caught
Message=The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.
Source=mscorlib
StackTrace:
at System.Convert.FromBase64String(String s)
at WEbsite.Login.Decrypt(String strText, String sDecrKey) in D:\Website\Account\Login.aspx.vb:line 213
InnerException:
UPDATE 2:
Encryption method added:
'The function used to decrypt the text
Private Function Decrypt(ByVal strText As String, ByVal sDecrKey _
As String) As String
Dim byKey() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim inputByteArray(strText.Length) As Byte
Try
byKey = System.Text.Encoding.UTF8.GetBytes(Left(sDecrKey, 8))
Dim des As New DESCryptoServiceProvider()
inputByteArray = Convert.FromBase64String(strText)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function
I have tried your Decrypt using, as input, the encrypted text and the same key.
It works as expected. The only change I have made to your code is the use of the Substring method instead of Left as in
byKey = System.Text.Encoding.UTF8.GetBytes(strDecrKey.Substring(0, 8))
I call the two methods in this way:
Dim result as String = Encrypt("test#gmail.com", "ABCD9876")
Dim decrypted = Decrypt(result, "ABCD9876")
I get back "test#gmail.com".
-Buon Weekend anche a te-
Use an String Builder instead of string as the parameter with the special characters.
Best regards.