Is this wrapper around AesManaged ok? - c#

I need to encrypt/decrypt some strings. I've build my wrapper class according to the msdn documentation but with some changes.
Since I want to encrypt/decrypt data with a given string/passphrase, I don't use AesManaged for creating a key. (The user should be able to encrypt/decrypt with a key he enters, and therefore I cannot use the key from AesManaged and I cannot save the key).
I instead create the key by using Rfc2898DeriveBytes (PBKDF2) with a given salt. The given salt is used since I do not store the key and I think because of this, the salt must be always the same.
I then create an IV, encrypt the given string and concatenate the IV and the encrypted string. This will then eventually got saved in a file. This means the IV gets save together with the encrypted data.
Questions:
Is it ok to store the IV together with the encrypted data?
Is there another way to create the key without using the same salt everytime(Based on a given passphrase)?
Is this encryption done using AES128 or AES256?
Will the IV be always 16 bytes, or can this change?
static void Main(string[] args)
{
const string stringToEncrypt = "String to be encrypted/decrypted. Encryption is done via AesManaged";
const string password = "m1Sup3rS3cre!Password";
string encrypted = EncryptString(stringToEncrypt, password);
string roundtrip = DecryptStringFromBytes_Aes(encrypted, password);
Console.WriteLine("Original: {0}", stringToEncrypt);
Console.WriteLine("Round Trip: {0}", roundtrip);
Console.ReadLine();
}
static string EncryptString(string plainText, string password)
{
string encryptedString;
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = PasswordAsByte(password);
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))
{
swEncrypt.Write(plainText);
}
var encrypted = msEncrypt.ToArray();
encryptedString = Encoding.Default.GetString(aesAlg.IV);
encryptedString += Encoding.Default.GetString(encrypted);
}
}
}
return encryptedString;
}
static string DecryptStringFromBytes_Aes(string cipherText, string password)
{
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = PasswordAsByte(password);
aesAlg.IV = Encoding.Default.GetBytes(cipherText).Take(16).ToArray();
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
var encryptedByteArray = Encoding.Default.GetBytes(cipherText).Skip(16).ToArray();
using (MemoryStream msDecrypt = new MemoryStream(encryptedByteArray))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
}
}
private static byte[] PasswordAsByte(string password)
{
byte[] salt = Encoding.Default.GetBytes("foobar42");
Rfc2898DeriveBytes passwordBytes = new Rfc2898DeriveBytes(password, salt);
return passwordBytes.GetBytes(32);
}

No, this is not okay.
1) You're using Encoding.Default in various places. Don't do that - it means you're at the whim of the platform you're on. Always use an explicit encoding, ideally UTF-8 in most cases.
2) You're using Encoding.GetString / Encoding.GetBytes to convert arbitrary binary data to a string and back. That's almost bound to lose data. (It happened to succeed on my machine, but it really depends on the encoding - and it's fundamentally a bad idea.) Encoding is designed for data which is inherently text data, and you're just applying an encoding one way or the other. Your encrypted data is inherently binary data. Use Convert.ToBase64String and Convert.FromBase64String instead.
For your other questions:
Yes, it's okay to store the IV with the encrypted data, as far as I know.
You could use the same approach for the password: generate a different salt each time, and store that with the encrypted text. Not sure whether that's generally recommended or not, I'm afraid.
I believe you're controlling whether the key size is 128 or 256 bits, with your call to passwordBytes.GetBytes(32) - that's a 256-bit key, so it's AES256.
I believe the IV size for AES is always 16 bytes (128 bits)

Normally salt is used together with cryptographic hashing of say passwords to protect against dictionary attacks. To get the same kind of protection for symmetric encryption with AES you should use a random initialization vector. So when you encrypt create a random IV and prepend it to the message (in cleartext). When you decrypt get the IV from the encrypted message and use it to decrypt the message. Then the ciphertext of the same message encrypted with the same key will be different.
So, yes, it is OK to store the IV together with the encrypted data.
You do not need a different salt every time because the purpose of the random IV is similar in how salt makes dictionary attacks on hashes harder.
AES can use key sizes of 128, 192 or 256 bits so to use AES 256 you need a 256 bit key (32 bytes) which is what you use.
AES uses a 128 bit block which requires a 128 bit IV (or 16 bytes).

Is it ok to store the IV together with the encrypted data?
Yes, it is ok. Moreover, you're using AesManaged without explicit setting of Mode - it this case mode is CBC, and in CBC mode IV should preceed cyphertext.
Is there another way to create the key without using the same salt everytime(Based on a given passphrase)?
Rfc2898DeriveBytes is pretty standard way to derive key from text password. There is no need to reinvent way of deriving key from password, just use Rfc2898DeriveBytes as you're doing it now.
Is this encryption done using AES128 or AES256?
It is AES256 since you're using 32-byte password.
Will the IV be always 16byte, or can this change?
The size of the IV property must be the same as the BlockSize property divided by 8. So it is 16 for 128-bit blocks.

Related

Correct AesCryptoServiceProvider usage

I'm trying to write some straight forward encryption routines. Here's what I've been able to come up with based on searching the Web.
public string Encrypt(string plainText)
{
byte[] encrypted;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
// 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())
{
msEncrypt.WriteByte((byte)aesAlg.Key.Length);
msEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
msEncrypt.WriteByte((byte)aesAlg.IV.Length);
msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
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 Convert.ToBase64String(encrypted);
}
public string Decrypt(string cipherText)
{
string plaintext = null;
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
{
int l = msDecrypt.ReadByte();
byte[] key = new byte[l];
msDecrypt.Read(key, 0, l);
l = msDecrypt.ReadByte();
byte[] IV = new byte[l];
msDecrypt.Read(IV, 0, l);
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(key, IV);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
return plaintext;
}
Two questions:
First, most of the examples I found hard coded the Key and IV. So what I'm doing is writing it to the encrypted bytes. This will make my encrypted data larger. Is there a better way?
Also, I'm not using any password. Would one use a password to generate a custom Key? And, if so, how would I know how long that key needed to be?
First, most of the examples I found hard coded the Key and IV. So what I'm doing is writing it to the encrypted bytes. This will make my encrypted data larger. Is there a better way?
Obviously you should not write the key to the unprotected stream, as the key needs to be shared or established in advance and remain secret. This sharing of the secret key can be performed in many ways, ranging from key agreement to key derivation, ratcheting, etc. etc.
Also, I'm not using any password. Would one use a password to generate a custom Key? And, if so, how would I know how long that key needed to be?
That's a possibility. However, remind yourself that passwords are often not that strong, so if password based encryption (PBE) can be avoided, it may be a good idea to do so.
If you derive a key from a password, you should use a Password Based Key Derivation Function (also sometimes called a password hash). In C# there is an implementation of PBKDF2 (badly) called Rfc2898DeriveBytes. By now that's not very state of the art either, but it should suffice - if you set a high enough iteration count anyway.
When you derive a key from a human remembered password then 128 bits is plenty. There is almost no way that the key can be found easier than the password that was used to derive it.

File encryption in C# with AES, decryption with phpseclib

I am working on a project for secure file transfer which encrypts files using c# client on the customer side. i need to decrypt the files on server side using php and maybe phpseclib. The code here i copied from a msdn example. But i cant work out the decrypt function in php.
public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = passwordBytes;
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.KeySize = 256;
AES.BlockSize = 256;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.Zeros;
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
using (CryptoStream cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
This is the php code which doesnt work:
$pw = "this_is_my_pw";
$aes = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aes->setKey($pw);
$aes->setKeyLength(256);
$aes->disablePadding();
$file = "enc.txt";
$fh = fopen($file, "r");
$contents = trim(fread($fh, filesize($file)));
fclose($fh);
//echo "Encoded: \n\n" . $contents;
$contents = $aes->decrypt($contents);
#$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
#$padding = $block - (strlen($clear) % $block);
#$dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $pw, base64_decode($contents), MCRYPT_MODE_CBC, $pw);
echo "Decoded: \n\n" . $contents;
Can someone help me fixing this or give me a hint what i do wrong?
No initialization vector used when decrypting. You need to send the initialization vector (IV) along with the data - your PHP code is never calling $aes->setIV from phpseclib, so it will never be able to decrypt the text because phpseclib uses an IV of all zeros if one is not set according to the docs. I would personally recommend generating a secure random IV from C# using RijndaelManaged.GenerateIV, but apparently it's considered acceptable to derive the IV from a PBKDF2 key. PBKDF2 (specified in RFC 2898) is the key-stretching algorithm Rfc2898DeriveBytes implements. Regardless, you need to re-produce the IV on the PHP side, whether that means transmitting the IV with the encrypted data (which is completely fine) or re-deriving the IV on the PHP side.
Using the password as the salt is a REALLY BAD IDEA. The salt needs to be of sufficient length and cryptographically randomly generated. Using the password as the salt completely defeats the point of having a salt. MSDN has some sample code that shows how to generate a cryptographically random salt in conjunction with using Rfc2898DeriveBytes, but the important part is here:
byte[] saltBytes = new byte[8];
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with a random value.
rngCsp.GetBytes(salt1);
}
The salt must be transmitted with the encrypted data. You need to send the PBKDF2 salt bytes along with the IV bytes and encrypted data. phpseclib will need all of those to properly initialize itself and decrypt the data. You'll probably want to use phpseclib's setPassword to do this, like so:
$salt = ...; // get the salt to your PHP code somehow
$iv = ...; // get the IV to your PHP code
$pw = "this_is_my_pw";
$aes = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aes->setPassword($pw, 'pbkdf2' /* key extension algorithm */,
'sha1' /* hash algorithm */, $salt /* generated salt from C# */,
1000 /* number of iterations, must be same as C# code */,
256 / 8 /* key size in bytes, 256 bit key / 8 bits per byte */
);
$aes->setIV($iv);
Keep the other answers in mind about blocksize. 128 bits is the standard AES blocksize, so make sure both C# and phpseclib can function correctly with a larger blocksize, or just use the AES standard for both.
If you are trying to use AES set the block size to 128-bits, that is the only block size that is supported. Using a different block size means you are using Rijndael encryption which is not well supported cross platform.
AES supports multiple key sizes of 128, 192 and 256 bits. Sometimes there is confusion when using a Rijndael implementation to use AES encryption.
In the Java code I see AES.BlockSize = 256;. Technically, AES has a fixed block size of 128 bits. Rijndael supports variable block sizes but AES doesn't. If you want to make use of variable block sizes in PHP with phpseclib you'd need to do this:
$pw = "this_is_my_pw";
$aes = new Crypt_Rijndael(CRYPT_RIJNDAEL_MODE_CBC);
$aes->setKey($pw);
$aes->setKeyLength(256);
$aes->setBlockLength(256);
$aes->disablePadding();
Also, your key is 13 bytes long. AES keys need to be either 16 bytes (128 bits) long, 24 bytes (192 bits) long or 32 bytes (256 bits) long. idk what js lib you're using but phpseclib 1.0/2.0 null pads keys if they're not long enough. The newest version of phpseclib - currently under development - throws exceptions.
Or maybe you mean to be using a password based key derivation function? phpseclib provides two that can be utilized via setPassword() but if that were the case you'd need to know what method and parameters were being utilized by the js lib.

CryptSharp SCrypt implementation in C#

I'm working on a CryptSharp SCrypt implementation in VS2015. I need to encrypt/decrypt text files meant to be sent as email attachments. Initially I was using AES but considering that HMAC-SHA1 is outdated I opted to use SCrypt for password hashing. However, SCrypt does not expose public methods for the data encryption itself, so would it make sense to pass the SCrypt hashed password to AES, then use the latter for data encryption? Or perhaps there is a better approach?
In this scenario, I would imagine something like this, yet I would need to find a way to reliably randomize the IV...
private static Aes SetAes(string userName, string password)
{
var passBytes = Encoding.UTF8.GetBytes(password);
var saltBytes = Encoding.UTF8.GetBytes(userName);
var cost = 131072; // around 5 secs with block at 16(on Xeon 1241 v3)
var blockSize = 16; // 8 is default but might not suffice against modern GPUs(?)
var parallel = 1;
var maxThreads = (int?)null;
byte[] derivedKey = new byte[32]; // 256 bits
SCrypt.ComputeKey(passBytes, saltBytes, cost, blockSize, parallel, maxThreads, derivedKey);
Aes aes = new AesManaged();
aes.Padding = PaddingMode.PKCS7;
aes.Key = derivedKey;
byte[] IV = new byte[16];
Array.Copy(derivedKey, IV, 16); // how to reliably randomize the IV?
aes.IV = IV;
return aes;
}
Then for file encryption:
internal static void EncryptText(string text, string userName, string password, string file)
{
// omitting argument checks for readability
using (Aes aes = SetAes(userName, password))
{
using (FileStream fileStream = new FileStream(file, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
{
using (CryptoStream cryptoStream = new CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(cryptoStream, text); // I'm using a class to wrap the text for serialization, not shown here for readability
}
}
}
}
Even though it seems to work, I'm not sure it makes sense, so thank you very much for any insight.
EDIT:
Following vcsjones recommendations, the SetAes function would rather look like this, if I understand correctly:
private static Aes SetAes(string userName, string password, byte[] IV = null)
{
var passBytes = Encoding.UTF8.GetBytes(password);
var saltBytes = Encoding.UTF8.GetBytes(userName);
var cost = 131072;
var blockSize = 16;
var parallel = 1;
var maxThreads = (int?)null;
byte[] derivedKey = new byte[32];
SCrypt.ComputeKey(passBytes, saltBytes, cost, blockSize, parallel, maxThreads, derivedKey);
Aes aes = new AesManaged();
aes.Padding = PaddingMode.PKCS7;
aes.Key = derivedKey;
if (IV == null) // when encrypting, generate IV
{
RandomNumberGenerator rn = RandomNumberGenerator.Create();
rn.GetBytes(aes.IV);
}
else aes.IV = IV; // when decrypting, read IV from file and pass it to aes through IV parameter for decryption
return aes;
}
However, SCrypt does not expose public methods for the data encryption itself, so would it make sense to pass the SCrypt hashed password to AES
SCrypt is a Key Derivation Function, so yes, that is an acceptable thing to do.
how to reliably randomize the IV?
Don't use the output of the KDF in the IV. The IV should be random for AES-CBC, so use RandomNumberGenerator.Create() to create a CSPRNG for the IV. Using the KDF output as part of the IV actually leaks the key since the IV is stored in plaintext.
An IV in AES-CBC should be random, and it should not be reused. Don't derive it from the password. You do need to store the IV somewhere. Since it looks like you're trying to encrypt files, you may just want to put the IV in at the beginning of the file. The IV is not a secret - it's OK if someone can read it. Then, when it comes time to decrypt the file, read the IV from the file, and then decrypt everything past the IV.
I would also recommend that you MAC the file, as well, as right now your application does not authenticate the encryption.

C# AES 256-Bit Decrypt given Encrypted Text and Secret

Somebody asked me how I would decrypt a given AES 256-bit encrypted string if I knew the secret key. I'm not very familiar with encryption, so I sat down to look into the problem.
I found this example on MSDN, and tried to modify it to do only the Decrypt:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
internal class AesExample
{
public static void Main()
{
var encryptedString = "U2FsdGVkX1/cHT8XuHCfpw0AV4jpaO8JfLqUeCRJqjY=";
var secret = "SPARKY";
// I know this is not the correct way to get my input byte arrays...
// Just illustrating that I DO need byte arrays.
var encryptedBytes = Encoding.UTF8.GetBytes(encryptedString);
var secretBytes = Encoding.UTF8.GetBytes(secret);
try
{
using (var aes = new AesManaged())
{
aes.Key = secretBytes;
// Decrypt the bytes to a string.
var decryptedString = Decrypt(encryptedBytes, aes.Key, aes.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Encrypted: {0}", encryptedString);
Console.WriteLine("Decrypted: {0}", decryptedString);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
}
private static string Decrypt(byte[] cipherText, byte[] key, byte[] iv)
{
// Declare the string used to hold
// the decrypted text.
string plaintext;
// Create an AesManaged object
// with the specified key and IV.
using (var aes = new AesManaged())
{
aes.Key = key;
aes.IV = iv;
// Create a decrytor to perform the stream transform.
var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
// Create the streams used for decryption.
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
Of course as soon as I hit the following line, a CryptographicExcetion is thrown with the message "Specified key is not a valid size for this algorithm."
==> aes.Key = secretBytes
Someone suggested taking a SHA1 hash of the secret and trimming that to 20 byes. I tried that, and I started getting a new CryptographicException with the message "Length of the data to decrypt is invalid."
So, I have a few questions:
1) Is this even possible given only the encrypted text and secret key?
2) If so, are them some base assumptions one would need to make, like the CipherMode? I was reading that the ECB mode doesn't have a initialization vector. That's why I ask.
3) What would I need to do to put the inputs (encrypted text and secret key) into the correct Byte[] format for the decryption to work?
Thanks!
You probably need more information to make this work. To answer your specific questions:
Yes, except that you don't have the secret key. "SPARKY" is not a valid AES key, as DavidH mentions, though passwords are routinely used to derive secret keys through what are called key derivation functions. You could try running your password through Rfc2898DeriveBytes (a popular KDF in .NET) to derive different AES keys that might work, but it too takes parameters that you apparently don't have. You could also try various SHA hash digests of your password, though again 20 bytes is not a valid AES key - you need a 16, 24 or 32 byte key.
If you don't have an IV, then yes, you'll have to assume the encryption uses ECB. (But note that in general you should never use ECB mode.)
Your encrypted string appears to be encoded using base64. Converting it to a byte array is simple enough in .NET using Convert.FromBase64String(encryptedString);.
This sounds like a fun exercise, but you're probably just going to end up frustrated without a bit more information.
AES key lengths are 128, 192, and 256 bit depending on the cipher you want to use. You must ensure that your string is the appropriate length of bytes.

Using AES Encryption in an Application

This is the first time that I have worked with AES encryption, and I am somewhat confused. I am encrypting some sensitive data (no passwords just names, address, id number etc). I found a nice example of how to implement AES into my application. I understand that I supply the Password, Salt, Hash Algorithm, and Password Iterations to make the Key. This then creates the cipher text. Couple of questions I have is why is the KeySize dived by 8? If I wanted someone else to decrypt this what do I need to give them? Should the password, salt and IV be different every time I encrypt something new, if that is the case how to I ensure that the other person I want to use this information is always aware of that?
public static string Encrypt(string PlainText, string Password, string Salt, string HashAlgorithm, int PasswordIterations, string InitialVector, int KeySize)
{
try
{
byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);
PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.CBC;
ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
MemoryStream MemStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
cryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] CipherTextBytes = MemStream.ToArray();
MemStream.Close();
cryptoStream.Close();
MemStream.Dispose();
cryptoStream.Dispose();
Encryptor.Dispose();
return Convert.ToBase64String(CipherTextBytes);
}
catch (Exception ex)
{
throw ex;
}
}
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
The keysize is divided by 8 because it's typically specified as a number of bits, but is being stored in a byte array.
The values that you keep the same are subject to the design of your program. In practice, the IV should change every time, but should you choose, you could keep the key and salt constant.
I know that the IV is included in the output of the stream, so you don't have to include it explicitly for decryption (it will be read from the stream). You shouldn't have to include the salt either for a similar reason. I believe that the only value you'd need to decrypt the cyphertext is the key. I may not be correct about this. You can always write a decryptor and see what you need to pass to make it work.
KeySize is in bits. And as we know on any normal machine 1 byte = 8 bits, hence division.
And what you need to give someone to be able to decrypt the data? Key and IV (Initialization Vector) will be enough.
That said - how do you usually do this? You send the AES encrypted data along with Key and IV encrypted using some asymetric encryption algorithm. This gives you higher level of protection - only someone with private key will be able to read Key and IV and use them do decrypt the most interesting data. You use generated Key and IV of some significant length to make yourself safe.
Why to do this this way? Because asymetric encryption is slow (very slow and for a good reason - to be harder to break), but symetric encryption (like AES) gives you high security if used with long key and is at the same time pretty fast. Combining both you get performance and security at high level.

Categories

Resources