I am new to encryption concept. Am trying to use AES encryption to encrypt a file which seems to be working fine. But when I use the decryption, I get no errors but the data is not decrypted. The decryption code is below
public static string DecryptData(string sFileInPath, byte[] Key, byte[] IV)
{
String data = null;
byte[] file = File.ReadAllBytes(sFileInPath);
if (!File.Exists(sFileInPath))
throw new ArgumentNullException("FilenotExists");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
try
{
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Padding = PaddingMode.None;
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Mode = CipherMode.CBC;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
MemoryStream ms = new MemoryStream();
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
{
cs.Write(file, 0, file.Length);
cs.Close();
}
data = Encoding.Unicode.GetString(ms.ToArray());
msDecrypt.Close();
}
return data;
}
catch (Exception ex)
{
string status = string.Format("{0}: {1}", statustype.Failed.ToString(), ex.ToString());
return status;
}
}
Call to the decrypt method is
AesCryptoServiceProvider oAes = new AesCryptoServiceProvider();
string xml = Utility.DecryptData_AES(sfile,oAes.Key,oAes.IV);
Encryption method:
public static byte[] EncryptData(AlertEnvelope alertenvelope, byte[] Key, byte[] IV)
{
if (alertenvelope == null)
throw new ArgumentNullException("alertenvelope");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
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(alertenvelope);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
I will appreciate if someone can help me understand why the data is not being decrypted
Related
I'm encrypting a string in .Net C#, sending it over using HttpRequest and decrypting it in .Net CF 3.5. Encrypting goes ok, but I get an error when decrypting the string.
Encrypting code:
public string Encrypt(string s)
{
byte[] encrypted;
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
//myRijndael.GenerateKey();
myRijndael.Mode = CipherMode.ECB;
myRijndael.KeySize = 256;
myRijndael.Key = Encoding.ASCII.GetBytes(keystring);
//myRijndael.GenerateIV();
myRijndael.IV = Encoding.ASCII.GetBytes(IVstring);
encrypted = EncryptStringToBytes(s, myRijndael.Key, myRijndael.IV);
string x = Encoding.UTF8.GetString(encrypted);
}
return Encoding.UTF8.GetString(encrypted);
}
private byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
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;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
Decrypting code in CF 3.5:
public string Decrypt(string toDecrypt)
{
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(keystring);
byte[] keyIV = UTF8Encoding.UTF8.GetBytes(IVstring);
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.KeySize = 256;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Encoding.ASCII.GetString(resultArray, 0, resultArray.Length);
}
The line byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); throws error : base {System.SystemException} = {"Length of the data to decrypt is invalid."}
I tried playing around with Padding etc, but to no avail. Thanks for your input.
EDIT
As suggested, I tried to use CryptoStream, but to no avail.
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
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");
string plaintext = null;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.ECB;
rijAlg.KeySize = 256;
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
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;
}
Now I get error:
base {System.ArgumentException} = {"Value can not be null.\r\nParameter name: inputBuffer"} at line plaintext = srDecrypt.ReadToEnd();
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;
}
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.
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.
I am banging my head to the wall.
I have the following Perl code, and I am trying to do this in .NET without success:
my $cipher = Crypt::CBC->new(
-iv => $iv,
-literal_key => 1,
-key => $key,
-cipher => "Crypt::OpenSSL::AES",
-blocksize => length($iv),
-keysize => length($key),
-header => "none"
);
my .net code is:
byte[] iv = new byte[] { 0x01,..... };
byte[] key = new byte[] { 0x01..... };
RijndaelManaged aes = new RijndaelManaged();
aes.Key = key;
aes.IV = iv;
encryptStringToBytes_AES("bla bla bla", aes.KEY, aes.IV)
...
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");
// Declare the stream used to encrypt to an in memory
// array of bytes.
MemoryStream msEncrypt = null;
// Declare the RijndaelManaged object
// used to encrypt the data.
RijndaelManaged aesAlg = null;
try
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
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.
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);
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}
// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}
What am i doing wrong???
Thanks!
Try with this:
UnicodeEncoding UE = new UnicodeEncoding();
byte[] bfr;
byte[] pwdBits = UE.GetBytes(plainText);
byte[] result;
int extends = (1 + (pwdBits.Length / 16)) * 16;
bfr = new byte[extends];
pwdBits.CopyTo(bfr, 0);
using (MemoryStream msCrypt = new MemoryStream())
{
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Padding = PaddingMode.PKCS7;
using (ICryptoTransform encriptor = RMCrypto.CreateEncryptor(Key, IV))
{
using (CryptoStream cs = new CryptoStream(msCrypt, encriptor, CryptoStreamMode.Write))
{
cs.Write(bfr, 0, bfr.Length);
cs.FlushFinalBlock();
result = msCrypt.ToArray();
cs.Close();
}
msCrypt.Close();
}
}
return result;