问题
I have to credit card number to be encrypted and stored in database as a string. I do the following
RijndaelManaged rijMan = new RijndaelManaged();
byte[] encrypt = Encrypt(txtCredit.Text, rijMan.Key, rijMan.IV);
string card = Convert.ToBase64String(encrypt);
string key = Convert.ToBase64String(rijMan.Key);
string iv = Convert.ToBase64String(rijMan.IV);
and this is encrypt function:
public static byte[] Encrypt(string message, byte[] key, byte[] iv)
{
byte[] encrypted;
using (RijndaelManaged rijMan = new RijndaelManaged())
{
rijMan.Key = key;
rijMan.IV = iv;
ICryptoTransform encrypt = rijMan.CreateEncryptor(rijMan.Key, rijMan.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
}
encrypted = ms.ToArray();
}
}
}
return encrypted;
}
And i store them all in database. This seems to be fine. But when i retrieve back the string from database and use System.Text.Encoding.UTF8.GetBytes(string) to convert to byte, it throws an exception
Specified initialization vector (IV) does not match the block size for this algorithm.
Is it possible to generate the IV such that it is 16 bytes ? Thanks in advance for the reply
回答1:
In the top of your post you are using BASE64 algorithm to convert IV bytes to string
string ivString = Convert.ToBase64String(rijMan.IV);
and then in the bottom of your post you are using UTF8 encoding to read string into byte array
byte[] iv = System.Text.Encoding.UTF8.GetBytes(ivString);
but you should use BASE64 algorithm again:
byte[] iv = Convert.FromBase64String(ivString);
BTW: I hope you are not storing AES key (rijMan.Key) in the same database as your encrypted credit card number because that would make whole encryption completely useless.
来源:https://stackoverflow.com/questions/23332338/rijndael-initialization-vector-with-16-bytes