Reputation: 11
I recently converted a previous encryption program from Java to C#. The decryption function works fine (as tested using the Java encrypted string), but the encryption produces a result that neither the Java program or the C# program can decode. The code and unit test is included below, along with the output. GetKey() function is my own salt generated key that correctly produces the same key for a given input (tested in Java and C#).
The encrypt and decrypt functions are exact duals. I can't understand why one works and the other does not.
I have reduced all texts to base64 to avoid the sign pitfall between java and C#. inserted the Java encrypted string (via debugger) in the decrypt function and it worked fine. The encrypted string fails to decode both in the decrypt and in its Java version with the same error
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
namespace Krypto
{
class Program
{
static void Main(string[] args)
{
string text;
string key;
string encrypText;
string decryptText;
Console.Write("Plese enter text to encrypt:");
text = Console.ReadLine();
Console.WriteLine("");
Console.Write("Plese enter Key:");
key = Console.ReadLine();
Console.WriteLine("");
encrypText = EncryptString(text, key);
Console.WriteLine("The encrypted string is: "+ encrypText);
decryptText = Decrypt(encrypText, key);
Console.WriteLine("The decrypted string is: " + decryptText);
if (text.Equals(decryptText)) Console.WriteLine("The test was sucessful");
else Console.WriteLine("The test failed!");
Console.ReadKey();
}
static string EncryptString(string text, string key)
{
byte[] key16 = getKey16(key);
string text64 = System.Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(text));
byte[] encrypted;
byte[] ivArr = { 1, 3, 3, 4, 5, 6, 6, 7, 4, 3, 2, 1, 7, 5, 5, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged aes = new RijndaelManaged())
{
aes.Key = key16;
aes.IV = IVBytes16Value;
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
// Create a decryptor to perform the stream transform.
ICryptoTransform encryptor = aes.CreateEncryptor();
try
{
byte[] textBytes = Convert.FromBase64CharArray(text64.ToCharArray(), 0, text64.Length);
encrypted = encryptor.TransformFinalBlock(textBytes, 0, textBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return "";
};
}
// Return the encrypted bytes from the memory stream.
return Convert.ToBase64String(encrypted);
}
private static string Decrypt(string CipherText, string key)
{
byte[] key16 = getKey16(key);
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] ivArr = { 1, 3, 3, 4, 5, 6, 6, 7, 4, 3, 2, 1, 7, 5, 5, 7 };
byte[] IVBytes16Value = new byte[16];
Array.Copy(ivArr, IVBytes16Value, 16);
aes.Key = key16;
aes.IV = IVBytes16Value;
ICryptoTransform decrypto = aes.CreateDecryptor();
byte[] decryptedData = null;
try
{
byte[] encryptedBytes = Convert.FromBase64CharArray(CipherText.ToCharArray(), 0, CipherText.Length);
decryptedData = decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return "";
};
return System.Text.ASCIIEncoding.UTF8.GetString(decryptedData);
}
}
private static byte[] getKey16(string key)
{
byte[] key16 = new byte[16];
//make key a 64bit string
string base64key = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(key));
byte[] keyArr = Convert.FromBase64String(base64key);
int keyarraysize = keyArr.Count();
if (keyarraysize < 16)
{
int counter = 0;
while (keyarraysize * (counter + 1) < 16)
{
for (int i = 0; i < keyarraysize; ++i) key16[i + keyarraysize * counter] = keyArr[i];
++counter;
}
for (int i = keyarraysize * counter; i < 16; ++i)
{
key16[i] = 0;
}
}
else for (int i = 1; i < 16; ++i) key16[i] = keyArr[i];
return key16;
}
}
the encrypt and decrypt in C# are exact duals. It should simply produce a correct test, instead i get the output below
Plese enter text to encrypt:This is a test
Plese enter Key:testKey
The encrypted string is: vLCR4QCJcVHvN4ss7H4Q2g== Error: Padding is invalid and cannot be removed. The decrypted string is: The test failed!
Upvotes: 1
Views: 628