I use this function to decrypt a executable file :
public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) ...
But, this function return a string output I can see the ASCII output of my corresponding decrypted file. But, I need to get a byte[] output.
I have try many thing but I'm stuck: I need a DecryptBytesToBytes function
That function is proprietary - i.e. it's part of your codebase, it's certainly not part of the BCL. So I suggest you find the source code and write a new version that returns a byte array.
As a variant:
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;
// 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;
}
The code you posted is for encrypting strings. The following code will encrypt a file and decrypt it using the file path. It will write out the file to the hard disk.
static void EncryptFile(string sInputFilename, string sOutputFilename, byte[] key, byte[] iv)
{
FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);
using (AesCryptoServiceProvider encryptor = new AesCryptoServiceProvider())
{
encryptor.Key = key;
encryptor.IV = iv;
ICryptoTransform transform = encryptor.CreateEncryptor();
using (CryptoStream cryptostream = new CryptoStream(fsEncrypted, transform, CryptoStreamMode.Write))
{
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
}
fsInput.Close();
fsEncrypted.Close();
}
}
static void DecryptFile(string sInputFilename, string sOutputFilename, byte[] key, byte[] iv)
{
using (AesCryptoServiceProvider encryptor = new AesCryptoServiceProvider())
{
encryptor.Key = key;
encryptor.IV = iv;
using (FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read))
{
using (ICryptoTransform transform = encryptor.CreateDecryptor())
{
using (CryptoStream cryptostream = new CryptoStream(fsread, transform, CryptoStreamMode.Read))
{
using (BinaryWriter fsDecrypted = new BinaryWriter(File.Open(sOutputFilename, FileMode.Create)))
{
byte[] buffer = new byte[1024];
var read = cryptostream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
fsDecrypted.Write(buffer, 0, read);
read = cryptostream.Read(buffer, 0, buffer.Length);
}
fsDecrypted.Flush();
cryptostream.Flush();
}
}
}
}
}
}
This works without all the streams:
public static Byte[] Encrypt(Byte[] input, SymmetricAlgorithm crypto)
{
return Transform(crypto.CreateEncryptor(), input, crypto.BlockSize);
}
public static Byte[] Decrypt(Byte[] input, SymmetricAlgorithm crypto)
{
return Transform(crypto.CreateDecryptor(), input, crypto.BlockSize);
}
private static Byte[] Transform(ICryptoTransform cryptoTransform, Byte[] input, Int32 blockSize)
{
if (input.Length > blockSize)
{
Byte[] ret1 = new Byte[( ( input.Length - 1 ) / blockSize ) * blockSize];
Int32 inputPos = 0;
Int32 ret1Length = 0;
for (inputPos = 0; inputPos < input.Length - blockSize; inputPos += blockSize)
{
ret1Length += cryptoTransform.TransformBlock(input, inputPos, blockSize, ret1, ret1Length);
}
Byte[] ret2 = cryptoTransform.TransformFinalBlock(input, inputPos, input.Length - inputPos);
Byte[] ret = new Byte[ret1Length + ret2.Length];
Array.Copy(ret1, 0, ret, 0, ret1Length);
Array.Copy(ret2, 0, ret, ret1Length, ret2.Length);
return ret;
}
else
{
return cryptoTransform.TransformFinalBlock(input, 0, input.Length);
}
}
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'm trying to use AesCryptoProvider to encrypt and decrypt byte arrays.
Here are my encrypt and decrypt methods:
public static byte[] EncryptAes(byte[] data, out byte[] key, out byte[] iv)
{
if (data == null || data.Length <= 0)
throw new ArgumentNullException("data");
try
{
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.KeySize = 256;
aesAlg.BlockSize = 128;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.CBC;
aesAlg.GenerateKey();
aesAlg.GenerateIV();
key = aesAlg.Key;
iv = aesAlg.IV;
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aesAlg.CreateEncryptor(), CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
}
return msEncrypt.ToArray();
}
}
}
catch (CryptographicException e)
{
Log.Error(e);
key = null;
iv = null;
return null;
}
}
public static byte[] DecryptAes(byte[] encryptedData, byte[] key, byte[] iv)
{
if (encryptedData == null || encryptedData.Length <= 0)
throw new ArgumentNullException("encryptedData");
if (key == null || key.Length <= 0)
throw new ArgumentNullException("key");
if (iv == null || iv.Length <= 0)
throw new ArgumentNullException("iv");
try
{
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.KeySize = 256;
aesAlg.BlockSize = 128;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Key = key;
aesAlg.IV = iv;
using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, aesAlg.CreateDecryptor(), CryptoStreamMode.Write))
{
csDecrypt.Write(encryptedData, 0, encryptedData.Length);
}
return msDecrypt.ToArray();
}
}
}
catch (CryptographicException e)
{
Log.Error(e);
return null;
}
}
Then to test it, I'm using this code:
originalMessage = "This is a test message.";
originalData = System.Text.Encoding.UTF8.GetBytes(originalMessage);
byte[] key, iv;
byte[] encryptedData = Encryption.EncryptAes(originalData, out key, out iv);
byte[] decryptedData = Encryption.DecryptAes(encryptedData, key, iv);
string decryptedMessage = System.Text.Encoding.UTF8.GetString(decryptedData);
Log.Debug(decryptedMessage); // This is a test message.?{?o?}??
The log output shows that the decrypted message has a bunch of garbage characters "?{?o?}??" at the end.
I've seen similar questions, but their answers don't seem to help. I've tried writing to another array during decryption like this:
using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, aesAlg.CreateDecryptor(), CryptoStreamMode.Write))
{
byte[] decryptedData = new byte[encryptedData.Length];
csDecrypt.Write(decryptedData, 0, decryptedData.Length);
}
return msDecrypt.ToArray();
}
But that results in this exception:
System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.
So there's gotta be something I'm missing. Any ideas? Thanks!
Yeah, reusing buffers is biting you. You generally don't expect the encrypted and decrypted data to be the same sizes, so reusing a buffer causes you to see left-over encrypted data in the decrypted data.
Make your decrypt similar to encrypt. Don't pass the buffer to the constructor of MemoryStream, let it allocate a buffer of the correct size:
using (MemoryStream msDecrypt = new MemoryStream())
{
using (CryptoStream csDecrypt =
new CryptoStream(msDecrypt,
aesAlg.CreateDecryptor(),
CryptoStreamMode.Write))
{
csDecrypt.Write(encryptedData, 0, encryptedData.Length);
}
return msDecrypt.ToArray();
}
I've tried writing to another array during decryption like this:
using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
{
using (CryptoStream csDecrypt =
new CryptoStream(msDecrypt,
aesAlg.CreateDecryptor(),
CryptoStreamMode.Write))
{
byte[] decryptedData = new byte[encryptedData.Length];
csDecrypt.Write(decryptedData, 0, decryptedData.Length);
}
return msDecrypt.ToArray();
}
No read it back to yourself. You're still configuring the cryptostream to write rather than read. What you're doing here is allocating a new buffer and then telling AES to decrypt that empty buffer into the memory stream which was initialized with the encrypted data.
My problem is the following:
I have a client/server application connected over sockets. My client´s task is to send a file byte-wise to the server. The server gets the bytes, decrypt them, send it back to the client and he writes them in a new file on disk.
I get everytime a serverside exception (System.Security.Cryptography.Exception: Padding is invalid and cannot be removed) at this line of code: plaintext = sr.ReadToEnd();
Could somebody help me to solve my problem?
Here is the decryption code:
public byte[] Dec(byte[] content, byte[] Key, byte[] IV, int fileLength, string filepath, int chunkSize, int bytesToRead)
{
byte[] contentDec;
string plaintext = null;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream ms = new MemoryStream(content))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
plaintext = sr.ReadToEnd();
cs.FlushFinalBlock();
}
contentDec = encoding.GetBytes(plaintext);
}
}
}
return contentDec;
}
Here is my encryption code:
public byte[] Enc(byte[] content,byte[] Key, byte[] IV, int fileLength,string filepath, int chunkSize, int bytesToRead)
{
byte[] contentEnc;
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(content);
}
contentEnc = ms.ToArray();
}
}
}
return contentEnc;
}
On client side I call encryption method like this
int chunkSize = 1024;
byte[] chunk = new byte[chunkSize];
using (FileStream fileReader = new FileStream(plainPath, FileMode.Open, FileAccess.Read))
using (FileStream filewriter = new FileStream(pathEncrypt, FileMode.Create, FileAccess.ReadWrite))
using (BinaryReader binaryReader = new BinaryReader(fileReader))
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
Key = myRijndael.Key;
IV = myRijndael.IV;
int bytesToRead = (int)fileReader.Length;
do
{
chunk = service.Enc(binaryReader.ReadBytes(chunkSize), Key, IV,(int)fileReader.Length,
fileReader.Name, chunkSize, bytesToRead);
filewriter.Write(chunk, 0, chunk.Length);
bytesToRead -= chunkSize;
} while (bytesToRead > 0);
}
Key and IV are declared as private byte[]
On client side I call decryption method like this
int chunkSize = 1024;
byte[] chunk = new byte[chunkSize];
using (FileStream fileReader = new FileStream(pathEncrypt, FileMode.Open, FileAccess.Read))
using (FileStream filewriter = new FileStream(pathDecrypt, FileMode.Create, FileAccess.ReadWrite))
using (BinaryReader binaryReader = new BinaryReader(fileReader))
{
int bytesToRead = (int)fileReader.Length;
do
{
chunk = service.Dec(binaryReader.ReadBytes(chunkSize), Key, IV, (int)fileReader.Length,
fileReader.Name, chunkSize, bytesToRead);
filewriter.Write(chunk, 0, chunk.Length);
bytesToRead -= chunkSize;
} while (bytesToRead > 0);
}
Edit: This is my connection establishment between client and server.
Server:
var host = new ServiceHost(typeof(Service),
new Uri("net.pipe://localhost"));
host.AddServiceEndpoint(typeof(TiService),
new NetNamedPipeBinding(), "TestService");
host.Open();
Console.WriteLine("Server connection established...");
Console.ReadKey();
Client:
var callback = new Callback();
var context = new InstanceContext(callback);
var pipeFactory =
new DuplexChannelFactory<TiService>(context,
new NetNamedPipeBinding(),
new EndpointAddress("net.pipe://localhost/TestService"));
service = pipeFactory.CreateChannel();
service.Connect();
Your problem start from using StreamWriter in the encryption. It's meant for writing Text file, not arbitrary file. When you call sw.Write(content), it simply call content.ToString(), which return "System.Byte[]", instead what you'd probably expect, each byte of the array. To fix it, simply write the CryptoStream, no need to use StreamWriter, like this :
using (var rijAlg = new AesCng())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(content, 0, content.Length);
}
contentEnc = ms.ToArray();
}
}
You probably noticed I used AesCng instead of RijndaelManaged. Why? Because it's much faster in my test, and unless you really need non-standard block, there's no benefit of using RijndaelManaged. Also, I use the parameterless CreateEncryptor because you already set the Key & IV on the previous lines anyway.
Same deal in the decryption. You shouldn't treat them as text, thus :
var buffer = new byte[content.Length]; //at first its size is actual size+padding
using (var rijAlg = new AesCng())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform decryptor = rijAlg.CreateDecryptor();
using (MemoryStream ms = new MemoryStream(content))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
var actualSize = cs.Read(buffer, 0, content.Length);
//we write the decrypted content to the buffer, and get the actual size
Array.Resize(ref buffer, actualSize);
//then we resize the buffer to the actual size
}
}
}
return buffer;
Also, your usage of the Enc and Dec is needlessly complex. It's already able to handle the whole file by itself. So to encrypt the file, simply use
var original = File.ReadAllBytes("originalPath");
var enc = Enc(original, rM.Key, rM.IV);
File.WriteAllBytes("encryptedPath", enc);
And to decrypt the file, just use
var enc = File.ReadAllBytes("encryptedPath");
var dec = Dec(enc, rM.Key, rM.IV);
File.WriteAllBytes("decryptedPath", dec);
As you can see, I throw away the fileLength,filepath, chunkSize, and bytesToRead on Enc & Dec, because your current code doesn't actually use them anyway. I've tried the code with short text file on ASCII, Unicode and UTF-8, and with large binary files, all encrypted & decrypted successfully with identical hash on the final decrypted files.
Edit :
Turning the code into direct filestream writing affair actually makes everything so much simpler.
public static void Transform(string source, string target, ICryptoTransform transf)
{
var bufferSize = 65536;
var buffer = new byte[bufferSize];
using (var sourceStream = new FileStream(source, FileMode.Open))
{
using (var targetStream = new FileStream(target, FileMode.OpenOrCreate))
{
using (CryptoStream cs = new CryptoStream(targetStream, transf, CryptoStreamMode.Write))
{
var bytesRead = 0;
do
{
bytesRead = sourceStream.Read(buffer, 0, bufferSize);
cs.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
}
}
public static void Enc(string source, byte[] Key, byte[] IV, string target)
{
using (var rijAlg = new AesCng())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor();
Transform(source, target, encryptor);
}
}
public static void Dec(string source, byte[] Key, byte[] IV, string target)
{
using (var rijAlg = new AesCng())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform decryptor = rijAlg.CreateDecryptor();
Transform(source, target, decryptor);
}
}
Usage is :
Enc(#"originalPath", key, iv, #"encryptedPath");
Dec(#"encrypedPath", key, iv, #"decryptedPath");
I am trying to encrypt bytes with Aes. However, the output I get is really weird. Here is my functions (encrypt and decrypt). Am I doing something wrong?
public static byte[] encryptStream(byte[] plain, byte[] Key, byte[] IV)
{
byte[] encrypted; ;
using (MemoryStream mstream = new MemoryStream())
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
using (CryptoStream cryptoStream = new CryptoStream(mstream,
aesProvider.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
cryptoStream.Write(plain, 0, plain.Length);
}
}
encrypted = mstream.ToArray();
}
return encrypted;
}
public static byte[] decryptStream(byte[] encrypted, byte[] Key, byte[] IV)
{
byte[] plain;
using (MemoryStream mStream = new MemoryStream())
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
using (CryptoStream cryptoStream = new CryptoStream(mStream,
aesProvider.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
cryptoStream.Read(encrypted, 0, encrypted.Length);
}
}
plain = mStream.ToArray();
}
return plain;
}
The issue is in your decryptStream() method, when you read from the cryptoStream you read INTO the encrypted buffer. When you call Read() you are already reading from the encrypted buffer because you wrapped it with the memory stream. You want to read into a NEW buffer which concatenated together will be the decrypted bytes.
public static byte[] decryptStream(byte[] encrypted, byte[] Key, byte[] IV)
{
byte[] plain;
byte[] buffer = new byte[32768];
int totalRead = 0;
MemoryStream plainStream = new MemoryStream();
using (MemoryStream mStream = new MemoryStream(encrypted))
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
using (CryptoStream cryptoStream = new CryptoStream(mStream,
aesProvider.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
while (true)
{
int read = cryptoStream.Read(buffer, 0, encrypted.Length);
if (read == 0)
break;
else
plainStream.Write(buffer, totalRead, read);
totalRead += read;
}
}
}
plain = plainStream.ToArray();
}
return plain;
}
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;