Asked by:
Length of Data to Decrypt Is Invalid

Question
-
User-786564416 posted
I have the following code to handle encryption and decryption
Public Shared Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte() Dim sha1 As New SHA1CryptoServiceProvider ' Hash the key. Dim keyBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(key) Dim hash() As Byte = sha1.ComputeHash(keyBytes) ' Truncate or pad the hash. ReDim Preserve hash(length - 1) Return hash End Function Public Shared Function EncryptData(ByVal plaintext As String) As String Dim TripleDes As New TripleDESCryptoServiceProvider Dim EncryptionKey As String = "MAKV2SPBNI99212" ' Initialize the crypto provider. TripleDes.Key = TruncateHash(EncryptionKey, TripleDes.KeySize \ 8) TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8) ' Convert the plaintext string to a byte array. Dim plaintextBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(plaintext) ' Create the stream. Dim ms As New System.IO.MemoryStream ' Create the encoder to write to the stream. Dim encStream As New CryptoStream(ms, TripleDes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write) ' Use the crypto stream to write the byte array to the stream. encStream.Write(plaintextBytes, 0, plaintextBytes.Length) encStream.FlushFinalBlock() ' Convert the encrypted stream to a printable string. Return Convert.ToBase64String(ms.ToArray) End Function Public Shared Function DecryptData(ByVal encryptedtext As String) As String Dim TripleDes As New TripleDESCryptoServiceProvider Dim DecryptionKey As String = "MAKV2SPBNI99212" ' Initialize the crypto provider. TripleDes.Key = TruncateHash(DecryptionKey, TripleDes.KeySize \ 8) TripleDes.IV = TruncateHash("", TripleDes.BlockSize \ 8) ' Convert the encrypted text string to a byte array. Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext) ' Create the stream. Dim ms As New System.IO.MemoryStream ' Create the decoder to write to the stream. Dim decStream As New CryptoStream(ms, TripleDes.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write) ' Use the crypto stream to write the byte array to the stream. decStream.Write(encryptedBytes, 0, encryptedBytes.Length) decStream.FlushFinalBlock() ' Convert the plaintext stream to a string. Return System.Text.Encoding.Unicode.GetString(ms.ToArray) End Function
The Encryption works fine. The decryption works fine mostly, however, for some cases of decryption, I got the error: Length of data to decrypt is invalid. I got this error when executing the statement:
decStream.FlushFinalBlock() on the DecryptData function when process the parameter encryptedtext with value: "D05837338A74F607B928FF7E30190798D9AC71D3"
So why the DecryptData functioning ok with some parameters but for the mentioned parameter it gives the length of the data to decrypt is invalid?
Tuesday, October 23, 2018 9:35 AM
All replies
-
User409696431 posted
Is that a valid key? This algorithm supports key lengths from 128 bits to 192 bits in increments of 64 bits. (See https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.tripledescryptoserviceprovider?view=netframework-4.7.2)
This:
String = "MAKV2SPBNI99212" is 128 bits.
This:
String = "D05837338A74F607B928FF7E30190798D9AC71D3" is too big.Does the error only occur using keys that don't meet the requirements?
If you are manipulating that key to use it (your truncate function?) does it return a valid key?
Tuesday, October 23, 2018 9:55 AM -
User-786564416 posted
Sorry KathyW I didn't understand your question.
The key is as following:
Dim DecryptionKey As String = "MAKV2SPBNI99212"
STRINGS THAT SUCCESSFULLY DECRYPTED:
FNeQdjPs4b2SJCfVqIXkAkDoZn8s3tQKdDvBn9PAIzpESQT7Lpn9yPL1y/OPnkSI aDy+cQJzsHvyFk+C6XCyY5bAQEZ7xiCAJFGN1NK6WOjZCdWrzvGawbbbsTk/vP7Am86XVwN1proU3cNaWAOcBXCJTDFEFTw7nz5CNqr+cJekRO966Mmt8WYIUML8zwYgLf3j4z6vK3m1SEqs14ZuWkm3s/3U76hBHZvxVcJmTOnLMaYGCXjLag== HC/j9FGngCWJmvlbUlrPN/vFkgs/svSXzihleh8mipadznssfHwumDtkIRYQrII4tF9IsetOnK9zHHubvtuteN8tvtcmNpj1 CqAxgtWN9xWSOnScD2XNbq3XNEASt/0Q/GdIWPRnOZw= CqAxgtWN9xWSOnScD2XNbgvhqewyGJzqqysII9rFCq42Cx1BuJpHYi3IaDwWbKfr CqAxgtWN9xWSOnScD2XNbkwKExTsPyA6C+zlNBw0D9mycrGFhZ56F5RgPRWs8hkT CqAxgtWN9xWSOnScD2XNbkwKExTsPyA6C+zlNBw0D9kG+nBQ+tHnwDgsAK30o2qnGDCcZDZAXxcg+O1yP/19+g== CqAxgtWN9xWSOnScD2XNbsYRQdH5tYRwQI6uOsWWkFXFqO8bMT8OxLM4gG3Pf3W5+EkfmMscMsCtL32aqNsRRA== N19w3n1qYK1JJbSEK7qQTp14lSsCHy9ZWBvAJwO6ZdsVEciTzEtygS+d+8+9r8UHPZijKZ/2Mun0q1e/5vHIOz5zMD/jgKpRf+iTf2tMG3jArgIqQKNomQ== l7wv9vjmtlvhn+cihnTZsWsluG8vARMF3TOQCoZUFic= MWxquUSlHMWNrsRyu7Oj6A== 3btvvKOV+BSRqcybF+3w7LWR1Gd0KVz+hvfyCY6HtbMpgfI7wU/NsaE9VC00dsPQlDHYClSBv4Q= mSGQL1DcWR4qL/VlymVDWRiDPrgIPlgcu3Y1L+kXzvQ= AlcNOHwTIvNcH3qMQRTEuILHsIeq4/G3nXbw2fiKPI+j74yrJn0HeNrcaVzJ1rfV XLp5dJuV9hsyGRl0WvsdtuM1E69RJ40EdJnDm+7BeKMDWIohfN+2zrcFMFVsdudr CqAxgtWN9xWZYVSdmXQe4dQLOYhWBO7uk7NbFJblzeE= oxx0VkP6o8CZ2N+QGE5hBCTbZKZ7rEgTjGpnqZPA/wNBRDaumY3UbZROxtktfJ7Re0crOrwfY/SkmrRhI+Ttjg== ud5+D6YENmnTgG+BHjPGWeLykM6xfv6WIWefzV6eNQU= HOW THE KEY SHOULD BE? WOULD YOU PLEASE SHOW ME EXAMPLES OF KEYS THAT COULD BE USED SO I UNDERSTAND DECRYPTION KEY REQUIREMENTS?
Tuesday, October 23, 2018 10:02 AM -
User409696431 posted
What key are you passing to the encryption / decryption algorithm? You call that "DecryptionKey" but it looks like you process it before you actually use it. Look at the result of your processing and see what you actually pass as the TripleDESCryptoServiceProvider key. Does it meet the requirements: a length from 128 bits to 192 bits in increments of 64 bits?
If you look at the link I provided you'll see code examples. (You'll also see that you don't have to create your own key. One is created when you create a new TripleDESCryptoServiceProvider, and you can use that.)
You'll also see a recommendation to use a newer method, the AesCryptoServiceProvider with a link to examples for it: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aescryptoserviceprovider?view=netframework-4.7.2
Tuesday, October 23, 2018 11:09 AM -
User-786564416 posted
using System; using System.IO; using System.Security.Cryptography; namespace Aes_Example { class AesExample { public static void Main() { try { string original = "Here is some data to encrypt!"; // Create a new instance of the AesCryptoServiceProvider // class. This generates a new key and initialization // vector (IV). using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider()) { // Encrypt the string to an array of bytes. byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV); // Decrypt the bytes to a string. string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV); //Display the original data and the decrypted data. Console.WriteLine("Original: {0}", original); Console.WriteLine("Round Trip: {0}", roundtrip); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); } } static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); byte[] encrypted; // Create an AesCryptoServiceProvider object // with the specified key and IV. using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create an encryptor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; } static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an AesCryptoServiceProvider object // with the specified key and IV. using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decryptor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; } } }
Thanks Kathy. I will be highly appreciative, if you would please convert the code shown in C# into the vb.net?
Tuesday, October 23, 2018 11:57 AM -
User475983607 posted
I will be highly appreciative, if you would please convert the code shown in C# into the vb.net?Use a C# to VB.NET converter....
Imports System Imports System.IO Imports System.Security.Cryptography Namespace Aes_Example Class AesExample 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 Private 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 Private 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 End Class End Namespace
However, I recommend that you try converting yourself so you have a better understanding of how the code works besides it is just syntax....
Tuesday, October 23, 2018 12:56 PM -
User-786564416 posted
Suppose that I have the plaintext variable "Subject". I want to encrypt it now. how to use the aesexample class to encrypt the plain text.
After that how to decrypt the encrypted value and get it back.
Tuesday, October 23, 2018 7:09 PM -
User475983607 posted
Suppose that I have the plaintext variable "Subject". I want to encrypt it now. how to use the aesexample class to encrypt the plain text.
After that how to decrypt the encrypted value and get it back.
That's exactly what the code posted above is doing. Replace "Here is some data to encrypt!" with "Subject".
Tuesday, October 23, 2018 7:22 PM