AES / RSA : Bad Data error et autres problemes (de stream?)
AES / RSA : Bad Data error et autres problemes (de stream?) - C#/.NET managed - Programmation
MarshPosté le 17-07-2007 à 10:33:39
Bonjour!
Je suis actuellement en train de coder un encryptage de données. L'encryptage choisi est a cle symetrique (pour la rapidite), ou la cle sera elle meme encryptee avec un algorithme asymetrique (pour la securite). J'ai choisi AES (Rijndael) pour l'encryptage symetrique, et RSA (4096 bits) pour l'asymetrique.
L'idee de l'encryptage est qu'on a un fichier en entree, et qu'on veut un fichier encrypte en sortie. Il faut de plus transmettre les deux cles (Key et IV) de l'algorithme symetrique pour la decryption.
J'ai 2 problemes (pour l'instant ) : - le fichier encrypte par Rijndael ne pese pas autant que l'original (dans un rapport de 1:1.7 a peu pres), alors que le fichier decrypte par Rijndael pese autant que le fichier crypte (en decoule fatalement que le fichier decrypte n'est pas le meme que le fichier encrypte ) - lors de la decryption, une erreur "Bad Data" est levee lors de l'import des parametres RSA.
Quelques rapides commentaires sur ce qui va suivre : - C'est mon premier programme en C# - C'est la premiere fois que j'utilise les Streams - J'ai choisi de faire les passages byte[] <-> string avec ASCII, mais c'est surement pas une bonne idee, etant donne que je ne sais pas s'il utilise un ASCII 128bits (pas cool) ou 256bits (cool) - Dans mes recherches, j'ai souvent vu parler de "Flush" du stream. Est-ce utile si le stream est ferme quasiment immediatement?
Merci d'avance.
Voila a peu pres ce que ca donne :
using System; using System.Collections.Generic, using System.Text; using System.IO; using System.Security.Cryptography;
namespace Project { class EncryptedData { // contains the names of the files where encrypted data will be stored
public string Enc_File { get {return enc_file}; set {enc_file = value}; } string enc_file;
public string Enc_Key { get {return enc_key}; set {enc_key = value}; } string enc_key;
public string Enc_IV { get {return enc_IV}; set {enc_IV = value}; } string enc_IV; }
// 2 : open and read file FileStream fstf = File.Open(FileToEncrypt, FileMode.OpenOrCreate); StreamReader strf = new StreamReader(fst); string file_contents = str.ReadToEnd();
EncryptedData encryptedFiles = new EncryptedData(); encryptedFiles.Enc_File = "encryptedFile";
// 3 : creating a new file, and writing encrypted data into it FileStream fstef = new FileSream(encryptedFiles.Enc_File, FileMode.OpenOrCreate); CryptoStream cstf = new CryptoStream(fstef, rijndaelEncryptor, CryptoStreamMode.Write); StreamWriter stw = new StreamWriter(cstf); stw.Write(file_contents);
// Part 2 : encrypting keys // 1 : create a RSA instance, and import the public keys RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(RSA_KEY_SIZE); RSA.ImportParameters(RSAParam);
Marsh Posté le 17-07-2007 à 10:33:39
Bonjour!
Je suis actuellement en train de coder un encryptage de données. L'encryptage choisi est a cle symetrique (pour la rapidite), ou la cle sera elle meme encryptee avec un algorithme asymetrique (pour la securite).
J'ai choisi AES (Rijndael) pour l'encryptage symetrique, et RSA (4096 bits) pour l'asymetrique.
L'idee de l'encryptage est qu'on a un fichier en entree, et qu'on veut un fichier encrypte en sortie. Il faut de plus transmettre les deux cles (Key et IV) de l'algorithme symetrique pour la decryption.
J'ai 2 problemes (pour l'instant ) :
- le fichier encrypte par Rijndael ne pese pas autant que l'original (dans un rapport de 1:1.7 a peu pres), alors que le fichier decrypte par Rijndael pese autant que le fichier crypte (en decoule fatalement que le fichier decrypte n'est pas le meme que le fichier encrypte )
- lors de la decryption, une erreur "Bad Data" est levee lors de l'import des parametres RSA.
Quelques rapides commentaires sur ce qui va suivre :
- C'est mon premier programme en C#
- C'est la premiere fois que j'utilise les Streams
- J'ai choisi de faire les passages byte[] <-> string avec ASCII, mais c'est surement pas une bonne idee, etant donne que je ne sais pas s'il utilise un ASCII 128bits (pas cool) ou 256bits (cool)
- Dans mes recherches, j'ai souvent vu parler de "Flush" du stream. Est-ce utile si le stream est ferme quasiment immediatement?
Merci d'avance.
Voila a peu pres ce que ca donne :
using System;
using System.Collections.Generic,
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace Project
{
class EncryptedData
{
// contains the names of the files where encrypted data will be stored
public string Enc_File
{
get {return enc_file};
set {enc_file = value};
}
string enc_file;
public string Enc_Key
{
get {return enc_key};
set {enc_key = value};
}
string enc_key;
public string Enc_IV
{
get {return enc_IV};
set {enc_IV = value};
}
string enc_IV;
}
class LetsDoIt
{
const int RSA_KEY_SIZE = 4096;
static void Main()
{
try
{
RSACryptoServiceProvider RSACrypto = new RSACryptoServiceProvider(RSA_KEY_SIZE);
EncryptedData encFiles = new EncryptedData();
encFiles = encrypt("toEncrypt.txt", RSACrypto.ExportParameters(false));
string decFile = decrypt(encFiles, RSACrypto.ExportParameters(true));
}
catch (Exception e) { Console.WriteLine("Error in Main: {0}", e.Message); }
}
static EncryptedData encrypt(string FileToEncrypt, RSAParameters RSAParam)
{
try
{
// Part 1 : encrypting data
// 1 : create a Rijndael instance.
Rijndael rijndaelAlg = Rijndael.Create();
rijndaelAlg.GenerateKey();
rijndaelAlg.GenerateIV();
ICryptoTransformer rijndaelEncryptor = rijndael.CreateEncryptor(rijndaelAlg.Key, rijndaelAlg.IV);
// 2 : open and read file
FileStream fstf = File.Open(FileToEncrypt, FileMode.OpenOrCreate);
StreamReader strf = new StreamReader(fst);
string file_contents = str.ReadToEnd();
EncryptedData encryptedFiles = new EncryptedData();
encryptedFiles.Enc_File = "encryptedFile";
// 3 : creating a new file, and writing encrypted data into it
FileStream fstef = new FileSream(encryptedFiles.Enc_File, FileMode.OpenOrCreate);
CryptoStream cstf = new CryptoStream(fstef, rijndaelEncryptor, CryptoStreamMode.Write);
StreamWriter stw = new StreamWriter(cstf);
stw.Write(file_contents);
// 4 : closing streams
stw.Close();
cstf.Close();
fstef.Close();
strf.Close();
fstf.Close();
// Part 2 : encrypting keys
// 1 : create a RSA instance, and import the public keys
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(RSA_KEY_SIZE);
RSA.ImportParameters(RSAParam);
// 2 : encrypt Rijndael keys
byte[] EncKey_byte = RSA.Encrypt(rijndaelAlg.Key, false);
byte[] EncIV_byte = RSA.Encrypt(rijndaelAlg.IV, false);
ASCIIEncoding ByteConverter = new ASCIIEncoding();
string EncKey_string = ByteConverter.GetString(EncKey_byte);
string EncIV_string = ByteConverter.GetString(EncIV_byte);
// 3 : finally, writing encrypted keys into files
encryptedFiles.Enc_Key = "encryptedKey";
encryptedFiles.Enc_IV = "encryptedIV";
FileStream fstK = new FileStream(encryptedFiles.Enc_Key, FileMode.OpenOrCreate);
FileStream fstI = new FileStream(encryptedFiles.Enc_IV, FileMode.OpenOrCreate);
StreamWriter stwK = new StreamWriter(fstK);
StreamWriter stwI = new StreamWriter(fstI);
stwK.Write(EncKey_string);
stwI.Write(EncIV_string);
// 4 : closing streams
stwK.Close();
stwI.Close();
fstK.Close();
fstI.Close();
return encryptedFiles;
}
catch (Exception e) { Console.WriteLine("Error in encrypt: {0}", e.Message); }
}
static string decrypt(EncryptedData encData, RSAParameters RSAParam)
{
try
{
// 1 : get files' contents
FileStream fstK = File.Open(encData.Enc_Key, FileMode.Open);
FileStream fstI = File.Open(encData.Enc_I, FileMode.Open);
StreamReader stwK = new StreamReader(fstK);
StreamReader stwI = new StreamReader(fstI);
string EncKey_string = stwK.ReadToEnd();
string EncIV_Key = stwI.ReadToEnd();
ASCIIEncoding ByteConverter = new ASCIIEncoding();
byte[] EncKey_byte = ByteConverter.GetBytes(EncKey_string);
byte[] EncIV_byte = ByteConverter.GetBytes(EncIV_string);
// 2 : decrypt keys with RSA algorithm
RSACryptoServiceProvider RSA = RSACryptoServiceProvider();
RSA.ImportParameters(RSAParam);
byte[] Key_byte = RSA.Decrypt(EncKey_byte, false);
byte[] IV_byte = RSA.Decrypt(EncIV_byte, false);
// 3 : decrypt the file using the rijndael keys
Rijndael rijndaelAlg = Rijndael.Create();
ICryptoTransform rijndaelDecryptor = rijndaelAlg.CreateDecryptor(Key_byte, IV_byte);
FileStream fstef = File.Open(encData.Enc_File, FileMode.Open);
CryptoStream cstef = new CryptoStream(fstef, rijndaelDecryptor, CryptoStreamMode.Read);
StreamReader stref = new StreamReader(cstef);
// 4 : writing retrieved contents into file
string contents;
string DecFile = "DecFile.txt";
FileStream fstf = File.Open(DecFile, FileMode.OpenOrCreate);
StreamWriter stwf = new StreamWriter(fstf);
contents = stref.ReadToEnd();
stwf.Write(contents);
// 5 : closing streams
stwf.Close();
fstf.Close();
stref.Close();
cstef.Close();
stwK.Close();
stwI.Close();
fstK.Close();
fstI.Close();
return DecFile;
}
catch (Exception e) { Console.WriteLine("Error in decrypt: {0}", e.Message); }
}
}
}