CryptoStream does not decrypt properly [duplicate] - c#

I am trying to decode an AES cipher in C#. If I use the same AES object as when I encode them, everything is fine. But as soon as I create a different instance of AES, it does not work:
string original = "username,password,companyID";
byte[] encrypted;
using (Aes myAes1 = Aes.Create()) {
encrypted = EncryptStringToBytes_Aes(original, GetBytes("password"), myAes1.IV);
//test1
string test1 = DecryptStringFromBytes_Aes(encrypted, GetBytes("password"), myAes1.IV);
}
using (Aes myAes2 = Aes.Create()) {
//test2
string test2 = DecryptStringFromBytes_Aes(encrypted, GetBytes("password"), myAes2.IV);
}
So in this code, test1 uses myAes1 and it works out fine because the encryption also used myAes1. However test2 uses myAes2 and it doesn't work, here is the output:
test1 = username,password,companyID
test2 = t0�V�e]��Ԅ��yd,companyID
what am I doing wrong?
Here are the supporting functions, which I copied from online:
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("Key");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create()) {
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor 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("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create()) {
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor 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)) {
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
static byte[] GetBytes(string str) {
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}

If you don't specify an IV, then one is randomly generated. You are using 2 different IV values when decrypting, which is why you are seeing different results.

Related

How to use "Cryptography.Aes" create string without special character?

I call this function EncryptStringToBytes_Aes to encrypt ID, when I convert to Base64 string, it looks like that: "Zr3EChQwtq1Wl/XLhBGSIZnHI098DKJaeujDmFfS25s="; "rGp5t04HgiKSkM10ImhOEwXZTc/eawOwlZTySRp6ZMk=", how to create string without "/" or "=", later I have to decrypt the ID.
string original = "IDNumber";
// Create a new instance of the AesCryptoServiceProvider
// class. This generates a new key and initialization
// vector (IV).
using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider())
{
Console.WriteLine("Original: {0} \n", original);
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
Console.WriteLine("Encrypted: {0} \n", Convert.ToBase64String(encrypted));
}
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 a decrytor 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 decrytor 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;
}
Thank you "Progman", you are smart, fixed my problem.
Now use class Base64UrlEncoder from namespace Microsoft.IdentityModel.Tokens
const string StringToEncode = "Zr3EChQwtq1Wl/XLhBGSIZnHI098DKJaeujDmFfS25s=";
var encodedStr = Base64UrlEncoder.Encode(StringToEncode);
var decodedStr = Base64UrlEncoder.Decode(encodedStr);

AES256 encription Without RijndaelManaged in .Net core 1.1

I want to do AES256 Encryption in .net core 1.1. RijndaelManaged is not supporting with the .net core 1.1. So I'm using here AES aes = new AES.create()
This part of code create the random private key for the encryption
public string GenaratePassPharse()
{
RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create();
byte[] randomBytes = new byte[KEY_SIZE];
rngCryptoServiceProvider.GetBytes(randomBytes);
string plainPassPharse = Convert.ToBase64String(randomBytes);
return plainPassPharse;
}
and here the AES() encryption method. What I want to do is pass my generated key (which is return from above method)instead of the aesAlg.Key as an encryption key.
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 Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.BlockSize = 128;
aesAlg.KeySize = 128;
// 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;
}
And any another way to use AES256 Encryption algorithms?
The full code should be:
public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv = null)
{
// Check arguments.
if (plainText == null)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length == 0)
{
throw new ArgumentNullException("Key");
}
// Create an Aes object
// with the specified key and IV.
using (Aes aes = Aes.Create())
{
aes.Key = key;
if (iv == null)
{
iv = new byte[aes.BlockSize / 8];
using (RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create())
{
rngCryptoServiceProvider.GetBytes(iv);
}
}
// Note that we are setting IV, Mode, Padding
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Create an encryptor to perform the stream transform.
using (ICryptoTransform encryptor = aes.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
// Prepend the IV
cs.Write(iv, 0, iv.Length);
// Here we are setting the Encoding
using (StreamWriter sw = new StreamWriter(cs, Encoding.UTF8))
{
// Write all data to the stream.
sw.Write(plainText);
}
byte[] encrypted = ms.ToArray();
return encrypted;
}
}
}
public static string DecryptBytesToString_Aes(byte[] encrypted, byte[] key)
{
// Check arguments.
if (encrypted == null || encrypted.Length == 0)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length == 0)
{
throw new ArgumentNullException("Key");
}
// Create an Aes object
// with the specified key and IV.
using (Aes aes = Aes.Create())
{
aes.Key = key;
using (MemoryStream ms = new MemoryStream(encrypted))
{
// Read the prepended IV
var iv = new byte[aes.BlockSize / 8];
ms.Read(iv, 0, iv.Length);
// Note that we are setting IV, Mode, Padding
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Create an encryptor to perform the stream transform.
using (ICryptoTransform decrytor = aes.CreateDecryptor())
using (CryptoStream cs = new CryptoStream(ms, decrytor, CryptoStreamMode.Read))
// Here we are setting the Encoding
using (StreamReader sr = new StreamReader(cs, Encoding.UTF8))
{
// Read all data from the stream.
string plainText = sr.ReadToEnd();
return plainText;
}
}
}
}
public static byte[] GenerateAesKey(int bits)
{
using (RandomNumberGenerator rngCryptoServiceProvider = RandomNumberGenerator.Create())
{
byte[] key = new byte[bits / 8];
rngCryptoServiceProvider.GetBytes(key);
return key;
}
}
public static void Main()
{
var key = GenerateAesKey(256);
var encrypted = EncryptStringToBytes_Aes("Hello", key);
var decrypted = DecryptBytesToString_Aes(encrypted, key);
}
This code prepend a random IV to the encrypted stream, and the recovers it from the encrypted stream to decrypt the stream.
It is very important that when you speak of encryption you set everything that can be setted. There must be no questions open. The encryption Mode, the Padding, the Encoding the plaintext must be encoded. Everything!

padding is invalid and cannot be removed while decrypt AES

I am facing strange issue with AES encryption and getting error while decryption.
Error while decrypt:
padding is invalid and cannot be removed
Encrypt Method:
private static string Encrypt(string plainText, byte[] key)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes("SharedPassword", key);
aesAlg.Key = deriveBytes.GetBytes(aesAlg.KeySize/8);
//aesAlg.IV = iv;
aesAlg.GenerateIV();
// Create a decrytor 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 Convert.ToBase64String(encrypted);
}
Decrypt Method:
private static string Decrypt(string token, byte[] key)
{
byte[] cipherText = Convert.FromBase64String(token);
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes("SharedPassword", key);
aesAlg.Key = deriveBytes.GetBytes(aesAlg.KeySize / 8);
aesAlg.GenerateIV();
// Create a decrytor 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(); // Error here
}
}
}
}
return plaintext;
}
I have tried many work around as mention below but none of them works.
AES decrypt fails with "Padding is invalid and cannot be removed"
C#: AES error: Padding is invalid and cannot be removed. Same key and everything, help
I don't get what is issue with code.

how to get bytes as output after decryption in c#

I need byte array as output after decryption byte array in C#. I am using below code. but i am getting "padding error". Is this below method is correct or i need to make any changes.
static byte[] DecryptBytesToBytes(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("Key");
// Declare the string used to hold
// the decrypted text.
byte[] encrypted = null;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
//aesAlg.Key = Key;
//aesAlg.IV = IV;
aesAlg.KeySize = 128;
aesAlg.BlockSize = 128;
aesAlg.Key = Key;
aesAlg.IV = Key;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Padding = PaddingMode.PKCS7;
// Create a decrytor 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))
{
string encrypted_text = srDecrypt.ReadToEnd();
encrypted = new byte[encrypted_text.Length * sizeof(char)];
System.Buffer.BlockCopy(encrypted_text.ToCharArray(), 0, encrypted, 0, encrypted.Length);
}
}
}
}
return encrypted;
}

AES decode error when using a different AES instance

I am trying to decode an AES cipher in C#. If I use the same AES object as when I encode them, everything is fine. But as soon as I create a different instance of AES, it does not work:
string original = "username,password,companyID";
byte[] encrypted;
using (Aes myAes1 = Aes.Create()) {
encrypted = EncryptStringToBytes_Aes(original, GetBytes("password"), myAes1.IV);
//test1
string test1 = DecryptStringFromBytes_Aes(encrypted, GetBytes("password"), myAes1.IV);
}
using (Aes myAes2 = Aes.Create()) {
//test2
string test2 = DecryptStringFromBytes_Aes(encrypted, GetBytes("password"), myAes2.IV);
}
So in this code, test1 uses myAes1 and it works out fine because the encryption also used myAes1. However test2 uses myAes2 and it doesn't work, here is the output:
test1 = username,password,companyID
test2 = t0�V�e]��Ԅ��yd,companyID
what am I doing wrong?
Here are the supporting functions, which I copied from online:
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("Key");
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create()) {
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor 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("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create()) {
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor 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)) {
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
static byte[] GetBytes(string str) {
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
If you don't specify an IV, then one is randomly generated. You are using 2 different IV values when decrypting, which is why you are seeing different results.

Categories

Resources