Asked by:
When Decrypting Data, "The Input Data is Not A Complete Block"

Question
-
User-786564416 posted
For encrypting database fields, I tried the following:
Public Shared Sub Main() Try Dim original As String = "Here is some data to encrypt!" Using myAes As AesCryptoServiceProvider = New AesCryptoServiceProvider() Dim encrypted As Byte() = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV) Dim roundtrip As String = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV) Console.WriteLine("Original: {0}", original) Console.WriteLine("Round Trip: {0}", roundtrip) End Using Catch e As Exception Console.WriteLine("Error: {0}", e.Message) End Try End Sub Public Shared Function EncryptStringToBytes_Aes(ByVal plainText As String, ByVal Key As Byte(), ByVal IV As Byte()) As Byte() If plainText Is Nothing OrElse plainText.Length <= 0 Then Throw New ArgumentNullException("plainText") If Key Is Nothing OrElse Key.Length <= 0 Then Throw New ArgumentNullException("Key") If IV Is Nothing OrElse IV.Length <= 0 Then Throw New ArgumentNullException("IV") Dim encrypted As Byte() Using aesAlg As AesCryptoServiceProvider = New AesCryptoServiceProvider() aesAlg.Key = Key aesAlg.IV = IV Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV) Using msEncrypt As MemoryStream = New MemoryStream() Using csEncrypt As CryptoStream = New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write) Using swEncrypt As StreamWriter = New StreamWriter(csEncrypt) swEncrypt.Write(plainText) End Using encrypted = msEncrypt.ToArray() End Using End Using End Using Return encrypted End Function Public Shared Function DecryptStringFromBytes_Aes(ByVal cipherText As Byte(), ByVal Key As Byte(), ByVal IV As Byte()) As String If cipherText Is Nothing OrElse cipherText.Length <= 0 Then Throw New ArgumentNullException("cipherText") If Key Is Nothing OrElse Key.Length <= 0 Then Throw New ArgumentNullException("Key") If IV Is Nothing OrElse IV.Length <= 0 Then Throw New ArgumentNullException("IV") Dim plaintext As String = Nothing Using aesAlg As AesCryptoServiceProvider = New AesCryptoServiceProvider() aesAlg.Key = Key aesAlg.IV = IV Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV) Using msDecrypt As MemoryStream = New MemoryStream(cipherText) Using csDecrypt As CryptoStream = New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read) Using srDecrypt As StreamReader = New StreamReader(csDecrypt) plaintext = srDecrypt.ReadToEnd() End Using End Using End Using End Using Return plaintext End Function
It works fine for some records. However, for some of the other records, when calling the function DecryptStringFromBytes_Aes , I got the error: "The Input Data is Not A Complete Block"
Where is the problem?
Wednesday, October 24, 2018 2:50 PM
All replies
-
User475983607 posted
It works fine for some records. However, for some of the other records, when calling the function DecryptStringFromBytes_Aes , I got the error: "The Input Data is Not A Complete Block"
Where is the problem?
My best guess is you have a bug in the code that fetches the encrypted content and/or converts the content to a byte array.
Wednesday, October 24, 2018 3:16 PM -
User-786564416 posted
We have a string variable ThisComments. we want to upload its encrypted value into database field EncryptedComments of type varbinary.
Imports System.Security.Cryptography Dim ThisComments As String Dim LetterID As String Dim DecryptedComments As String Public Shared Function EncryptStringToBytes_Aes(ByVal plainText As String, ByVal Key As Byte(), ByVal IV As Byte()) As Byte() If plainText Is Nothing OrElse plainText.Length <= 0 Then Throw New ArgumentNullException("plainText") If Key Is Nothing OrElse Key.Length <= 0 Then Throw New ArgumentNullException("Key") If IV Is Nothing OrElse IV.Length <= 0 Then Throw New ArgumentNullException("IV") Dim encrypted As Byte() Using aesAlg As AesCryptoServiceProvider = New AesCryptoServiceProvider() aesAlg.Key = Key aesAlg.IV = IV Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV) Using msEncrypt As MemoryStream = New MemoryStream() Using csEncrypt As CryptoStream = New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write) Using swEncrypt As StreamWriter = New StreamWriter(csEncrypt) swEncrypt.Write(plainText) End Using encrypted = msEncrypt.ToArray() End Using End Using End Using Return encrypted End Function Public Shared Function DecryptStringFromBytes_Aes(ByVal cipherText As Byte(), ByVal Key As Byte(), ByVal IV As Byte()) As String If cipherText Is Nothing OrElse cipherText.Length <= 0 Then Throw New ArgumentNullException("cipherText") If Key Is Nothing OrElse Key.Length <= 0 Then Throw New ArgumentNullException("Key") If IV Is Nothing OrElse IV.Length <= 0 Then Throw New ArgumentNullException("IV") Dim plaintext As String = Nothing Using aesAlg As AesCryptoServiceProvider = New AesCryptoServiceProvider() aesAlg.Key = Key aesAlg.IV = IV Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV) Using msDecrypt As MemoryStream = New MemoryStream(cipherText) Using csDecrypt As CryptoStream = New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read) Using srDecrypt As StreamReader = New StreamReader(csDecrypt) plaintext = srDecrypt.ReadToEnd() End Using End Using End Using End Using Return plaintext End Function
- First, we get ThisComments encrypted value using the function EncryptStringToBytes_Aes. and load it into myencrypted byte array variable.
Using myAes As AesCryptoServiceProvider = New AesCryptoServiceProvider() Dim myencrypted As Byte() = EncryptStringToBytes_Aes(ThisComments, myAes.Key, myAes.IV)
- Store the encrypted value into SQL Server database field of type varbinary:
queryString = "UPDATE Postings SET EncryptedComments=@ECom WHERE (LetterID=@LID)" Dim PlugEncryption As New SqlCommand(queryString, connection) PlugEncryption.Parameters.Add("@ECom", SqlDbType.VarBinary) PlugEncryption.Parameters("@ECom").Value = myencrypted PlugEncryption.Parameters.Add("@LID", SqlDbType.NVarChar) PlugEncryption.Parameters("@LID").Value = LetterID PlugEncryption.ExecuteNonQuery()
- Now, we want to retrieve the encrypted value and load it into byte array variable
Dim EncryptedComments As Byte() queryString = "SELECT EncryptedComments FROM Postings WHERE (LetterID=@LID)" Dim GetStoredEncryption As New SqlCommand(queryString, connection) GetStoredEncryption.Parameters.Add("@LID", SqlDbType.NVarChar) GetStoredEncryption.Parameters("@LID").Value = MyRowView("LetterID") EncryptedComments = GetStoredEncryption.ExecuteScalar() If EncryptedComments.Length > 0 Then ThisComments = DecryptStringFromBytes_Aes(EncryptedComments, myAes.Key, myAes.IV) Else ThisComments = "" End If
End UsingThat's my code. How can I make sure that I made the proper storing of the byte array into varbinary SQL Server database field, and Load it properly from database back from varbinary database field type into byte array variable?
Thursday, October 25, 2018 8:17 PM -
User475983607 posted
alihusain_77
How can I make sure that I made the proper storing of the byte array into varbinary SQL Server database field, and Load it properly from database back from varbinary database field type into byte array variable?Man, unit test the code and/or run the code through the VS debugger! Do some troubleshooting and explain what you have done up to this point rather than just dumping code on the forum and making us guess.
Have you tried comparing the data at each step of the processes? That's where I would start and you only need the debugger and notepad. Are you passing special characters and need to encode first? Is the database field large enough to hold the content? Can you post sample code that reproduces the behavior? Does the byte array coming out of the database match the data that went in? Does ExecuteScalar return content?
This should be very easy to troubleshoot if you create a few unit tests.
Anyway, look into the encryption that comes with SQL server if all you need is to encrypt data at rest.
Thursday, October 25, 2018 8:55 PM -
User-786564416 posted
If there is a byte array. How to save all of its parts completely into the database, and what is the best database field type to store the byte array? Is it varbinary? Then how to retrieve the varbinary and load it into Byte array? I think the problem is here. The problem with me happened only with a Byte array with a big length. That's why I get Input data is not complete block when try decrypting as the passed encrypted variable of Byte array to the Decryption function.
Now, I want to know how to Store Byte array variable into database field and then, How to retrieve it from database field of varbinary type into Byte array variable.
Thursday, October 25, 2018 9:07 PM