CryptographicException: Bad PKCS7 padding. Invalid length 109 - c#

Hey everyone im working on a game project and im getting the CryptographicException: Bad PKCS7 padding. Invalid length 109.
Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (System.Security.Cryptography.PaddingMode padding, System.Int32 length, System.Int32 position) (at :0) error.
Can someone please guide with a solution
/// <summary>
/// Simple AES decryption
/// </summary>
/// <param name="cipherText"></param>
/// <returns></returns>
public static string Decrypt(string cipherText)
{
if (string.IsNullOrEmpty(cipherText))
{
return string.Empty;
}
string EncryptionKey = bl_LoginProDataBase.Instance.SecretKey;
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {
0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
});
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}

Related

Encrypting a string in .net and decrypting it in python

I'm trying to encrypt password using system.Security.Cryptography which is working properly
This is the code (.Net)
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
And this is decryption code in python which is not working properly
def Decryptstr(self, text):
try:
EncryptionKey = "****"
if text is None:
return
else:
cipherbytes = base64.b64decode(text)
salt = '\0x49\0x76\0x61\0x6e\0x20\0x4d\0x65\0x64\0x76\0x65\0x64\0x65\0x76'
key_bytes = KDF.PBKDF2(EncryptionKey, salt, dkLen=32)
iv = KDF.PBKDF2(EncryptionKey, salt,dkLen=16)
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-16')
print(password)
return password
except Exception as err:
print(err)
following is the output of the above code for the encrypted string ('eet123')
䏺꧴퐄妯৞軸힡薟
Any help will be appreciated.
It seems that your PBKDF2HMAC key extraction in python side is incorrect. You need to pass correct parameters and get a 48 bytes key. Then use first 32 bytes as Key and last 16 bytes as IV (in your design).
Here is a working C#/Python code pair. First C# part:
static string encrypt(string clearText = "")
{
if (clearText == null)
{
clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Mode = CipherMode.CBC;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
About this C# code:
By default Rfc2898DeriveBytes uses SHA1 and only 1000 rounds. My suggestion is that you should use at least 100,000. I have seen code apps that use 1,000,000 rounds. You can change hash too if you like, but number of rounds is more important.
Specify mode too. Even though it uses CBC by default, I think it is better to specify it.
Since C# uses key length to select AES algorithm, this code uses AES-256.
Now Python part:
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
def Decryptstr(self, text):
try:
if text is None:
return
else:
backend = default_backend()
EncryptionKey = "****"
salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
key_bytes = kdf.derive(bytes(EncryptionKey, 'utf-8'))
key = key_bytes[0:32]
iv = key_bytes[32:]
cipherbytes = base64.b64decode(text)
cipher = AES.new(key, AES.MODE_CBC, iv)
password = cipher.decrypt(cipherbytes).decode('utf-8')
print(password)
return password
except Exception as err:
print(err)
As you see, I used another PBKDF2HMAC library. I used it to create 48 bytes and used first 32 as Key and last 16 bytes as IV.

Error "The input data is not a complete block" while Decrypt in MVC

public string Decrypt(string cipherText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
"The input data is not a complete block" error when i try to decrypt
.Error evoke at cs.close();
and below is encryption which is work fine
public string encrypt(string clearText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
Encryption working fine it encrypt string correctly but when i want to decrpt it evokes error

when i change the encryption key i get error in line "while ((data = cs.ReadByte()) != -1)"

I make a desktop application wpf and i need to encrypt some files(images,audio),i found this solution but it works just with the encryptionkey provided.so when i try to change the encryption key ,the encryption works well but on the decryption i got this error "le remplissage n'est pas valide et ne peut pas supprimé"
public void Encrypt(string inputFilePath, string outputfilePath)
{
string EncryptionKey = "MAKV2SPBNI99212";
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (FileStream fsOutput = new FileStream(outputfilePath, FileMode.Create))
{
using (CryptoStream cs = new CryptoStream(fsOutput, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
using (FileStream fsInput = new FileStream(inputFilePath, FileMode.Open))
{
int data;
while ((data = fsInput.ReadByte()) != -1)
{
cs.WriteByte((byte)data);
}
cs.Close();
fsInput.Close();
}
fsOutput.Close();
}
}
}
}
public void Decrypt(string inputFilePath, string outputfilePath)
{
string EncryptionKey = "MAKV2SPBNI99212";
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (FileStream fsInput = new FileStream(inputFilePath, FileMode.Open))
{
using (CryptoStream cs = new CryptoStream(fsInput, encryptor.CreateDecryptor(), CryptoStreamMode.Read))
{
using (FileStream fsOutput = new FileStream(outputfilePath, FileMode.Create))
{
int data;
while ((data = cs.ReadByte()) != -1)
{
fsOutput.WriteByte((byte)data);
}
}
}
}
}
}
That error in English is "the padding is invalid and cannot be removed". It indicates that either the key or the (end of the ciphertext) has changed. It is exactly the error you should be expecting when the encryption key is not the same as the decryption key (or, in your case, if the password, salt or iteration count are incorrect).
The bad thing about CBC encryption / decryption is that you may not get this error - just the wrong plaintext. You could use authenticated encryption such as GCM mode encryption to avoid this.

Converting c# Rfc2898DeriveBytes encryption to PHP

Is there any functions in PHP that is equivalent to c# Rijndael AES encryption/decryption? I have include the c# code below. Please advise.
protected string Encrypt(string clearText)
{
string EncryptionKey = "test";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}

Corresponding T-SQL to perform same encryption/decryption as C# code

Could anyone provide an example of performing exactly the same encryption/decryption as the C# code below, but with T-SQL?
The below functions are used to encrypt/decrypt given strings for later storage in a database. But I'm just curious to know whether there is a T-SQL-way of doing the exact same thing.
Note: The value of the string variable "EncryptionKey" is made up for this specific purpose
private string Encrypt(string clearText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
private string Decrypt(string cipherText)
{
string EncryptionKey = "MAKV2SPBNI99212";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}

Categories

Resources