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;
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 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!
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 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
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.