2014-04-28 38 views
1

我必须将信用卡号加密并作为字符串存储在数据库中。我做了以下Rijndael初始化向量16字节

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); 

,这是加密功能:

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; 
} 

而且我他们都存储在数据库中。这似乎很好。但是,当我回检索数据库,从串并使用System.Text.Encoding.UTF8.GetBytes(string)转换为byte,它抛出一个异常

指定的初始化向量(IV)不适合这个算法的块大小匹配。

是否有可能生成这样的IV是16字节?在此先感谢您的答复

回答

3

在您的文章的顶部使用的是BASE64算法,以四字节转换为字符串

string ivString = Convert.ToBase64String(rijMan.IV); 

,然后在您的文章底部使用的是UTF8编码读取字符串成字节数组

byte[] iv = System.Text.Encoding.UTF8.GetBytes(ivString); 

,但你应该再次使用BASE64算法:

byte[] iv = Convert.FromBase64String(ivString); 

顺便说一句:我希望你没有将AES密钥(rijMan.Key)存储在与你的加密信用卡号相同的数据库中,因为这会使整个加密完全无用。

+2

将IV与密文一起存储是标准的 - 这不是秘密,每封邮件都需要不同。 – CodesInChaos

+0

@CodesInChaos好点。我编辑了我的答案以反映您的评论。 – jariq

+0

我为每个条目生成新的IV。 RijndaelManaged rijMan = new RijndaelManaged(); byte [] encrypt = Encrypt(txtCredit.Text,rijMan.Key,rijMan.IV); – Partha