locked
Length of Data to Decrypt Is Invalid RRS feed

  • 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....

    http://converter.telerik.com/

    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