Invalid padding and cannot be deleted - AES is another

The code below is the last iteration in an attempt to create a simple encryption / decryption program for your own project. I hope it will be very stupid that I am just too far in the trench.

This is in .Net 4.7, and I tried to organize it so that I do not accidentally have different keys or options that occur during the process. The code must be on Linqpad.

Some of the things I tried are listed in TODOs, although I am not documenting all the modified options that I found today.

If someone else can run it on Linqpad or Visual studio 2017, I really want to find out what I don't see here.

Thanks for any advice!

'Linqpad version - should offer to import System.Security.Cryptography 'I'm on .net 4.7 in my main project hence the Tuple setup below. Dim Testphrase = "Whatever is happening, nothing I google works!" Sub Main Dim encrypted = EncryptString(Testphrase, "Password") Dim Decrypted = DecryptString(encrypted, "Password") Decrypted.Dump End Sub Private Shared AesManaged As AesManaged Private Shared password As Rfc2898DeriveBytes '''Makes sure that I use the same parameters both sides of the equation Private Shared Function GetCryptBits(passphrase As String) As (passwords As Rfc2898DeriveBytes, AesManaged As AesManaged) If AesManaged Isnot Nothing Then Return (password, AesManaged) 'TODO: Don't rebuild this if you've already got it. password = New Rfc2898DeriveBytes(passphrase, Encoding.UTF8.GetBytes("SaltBytes")) AesManaged = New AesManaged() With {.Mode = CipherMode.CBC, .Padding = PaddingMode.PKCS7, .BlockSize = 128, .KeySize = 256} 'TODO: I've tried all the padding choices here.TODO: Have tried RijndaelManaged AesManaged.IV = password.GetBytes(AesManaged.BlockSize / 8) AesManaged.Key = password.GetBytes(AesManaged.KeySize / 8) Return (password, AesManaged) End Function 'Encrypt Public Shared Function EncryptString(plainText As String, passPhrase As String) As String Dim B = GetCryptBits(passPhrase) With B Dim plainTextBytes As Byte() = Encoding.UTF8.GetBytes(plainText) 'TODO: Where you see UTF8 I've also tried with Unicode Dim encryptor As ICryptoTransform = B.AesManaged.CreateEncryptor(B.AesManaged.Key, B.AesManaged.IV) Using MemoryStream As New MemoryStream() Using CryptoStream As New CryptoStream(MemoryStream, encryptor, CryptoStreamMode.Write) CryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length) CryptoStream.FlushFinalBlock() Dim cipherTextBytes As Byte() = MemoryStream.ToArray() AesManaged.clear Return Convert.ToBase64String(cipherTextBytes) MemoryStream.Close() CryptoStream.Close() End Using End Using End With End Function 'Decrypt Public Shared Function DecryptString(cipherText As String, passPhrase As String) As String Dim B = GetCryptBits(passPhrase) With B Dim cipherTextBytes As Byte() = Convert.FromBase64String(cipherText) Dim decryptor As ICryptoTransform = B.AesManaged.CreateDecryptor(B.AesManaged.Key, B.AesManaged.IV) Using MemoryStream As New MemoryStream Using CryptoStream As New CryptoStream(MemoryStream, decryptor, CryptoStreamMode.Read) Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {} Dim decryptedByteCount As Integer = CryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length) 'TODO: Here I'm getting "Padding is invalid and cannot be removed." Return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount) End Using End Using End With End Function 
0
source share
1 answer

Below is the corrected version of your code. I am not a VB.Net programmer, so I am not saying that this is a pretty or better style, etc., but it works. Your problem was related to two things. First, you clear the AesManaged object in your encryption function, and then try to use it again in your decryption function. Another problem was how you decrypted. If you look back at my answer , in which you bring me here :), you will see the difference between your decryption and mine. In your case, you assumed that the decrypted bytes would be equal to the length of the encrypted bytes (this line of code here is Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {} ), but what you need to do is decrypt in a loop, read a block of bytes and add it to your output until more bytes are read.

Edit And as Hans Passant pointed out (and I forgot to mention), you need to initialize the decryption stream with actual data.

 Dim Testphrase = "Whatever is happening, nothing I google works!" Sub Main Dim encrypted = EncryptString(Testphrase, "Password") encrypted.Dump Dim Decrypted = DecryptString(encrypted, "Password") Decrypted.Dump End Sub Private Shared AesManaged As AesManaged Private Shared password As Rfc2898DeriveBytes '''Makes sure that I use the same parameters both sides of the equation Private Shared Function GetCryptBits(passphrase As String) As (passwords As Rfc2898DeriveBytes, AesManaged As AesManaged) If AesManaged Isnot Nothing Then Return (password, AesManaged) 'TODO: Don't rebuild this if you've already got it. password = New Rfc2898DeriveBytes(passphrase, Encoding.UTF8.GetBytes("SaltBytes")) AesManaged = New AesManaged() With {.Mode = CipherMode.CBC, .Padding = PaddingMode.PKCS7, .KeySize = 256} 'TODO: I've tried all the padding choices here.TODO: Have tried RijndaelManaged Dim iv As Byte() = password.GetBytes(AesManaged.BlockSize / 8) Dim key As Byte() = password.GetBytes(AesManaged.KeySize / 8) AesManaged.IV = iv AesManaged.Key = key Return (password, AesManaged) End Function 'Encrypt Public Shared Function EncryptString(plainText As String, passPhrase As String) As String Dim B = GetCryptBits(passPhrase) With B Dim plainTextBytes As Byte() = Encoding.UTF8.GetBytes(plainText) 'TODO: Where you see UTF8 I've also tried with Unicode Dim encryptor As ICryptoTransform = B.AesManaged.CreateEncryptor(B.AesManaged.Key, B.AesManaged.IV) Using MemoryStream As New MemoryStream() Using CryptoStream As New CryptoStream(MemoryStream, encryptor, CryptoStreamMode.Write) CryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length) CryptoStream.FlushFinalBlock() Dim cipherTextBytes As Byte() = MemoryStream.ToArray() Return Convert.ToBase64String(cipherTextBytes) MemoryStream.Close() CryptoStream.Close() End Using End Using End With End Function 'Decrypt Public Shared Function DecryptString(cipherText As String, passPhrase As String) As String Dim B = GetCryptBits(passPhrase) With B Dim cipherTextBytes As Byte() = Convert.FromBase64String(cipherText) Dim decryptor As ICryptoTransform = B.AesManaged.CreateDecryptor(B.AesManaged.Key, B.AesManaged.IV) Using MemoryStream As New MemoryStream(cipherTextBytes) Using OutputStream As New MemoryStream() Using CryptoStream As New CryptoStream(MemoryStream, decryptor, CryptoStreamMode.Read) Dim plainTextBytes As Byte() = New Byte(1024) {} Dim read As Integer = CryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length) While read > 0 OutputStream.Write(plainTextBytes,0, read) read = CryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length) End While Return Encoding.UTF8.GetString(OutputStream.ToArray()) End Using End Using End Using End With End Function 
+3
source

Source: https://habr.com/ru/post/1401658/


All Articles