张青凤,张凤琴
(1.运城学院公共计算机教学部,山西运城044000;2.空军工程大学计算机系,陕西西安710071)
2001年美国国家标准技术协会已经将Rijndael算法作为下一代对称密码算法的标准,该算法借鉴了很多Square算法的设计思想。它允许128,192,256位密钥长度,不仅能够在128位分组上工作,也能够在不同的硬件上工作[1-3]。
Rijndael属对称加密,是一种可变数据块长和可变密钥长的迭代分组加密算法,在安全、性能、效率、可实现、灵活等多方面有优点,它被设计成数据块长、密钥长为128/192/256三个可选长度,来加密128bit分组,相应的加密轮数分别为10/12/14,每一轮循环都有一个循环密钥,它来自于初始密钥[4-5]。
状态由一个4行、Nb列的二维字节数组表示,Nb等于数据块长度除以32,取Nb=4时的状态为:
Rijindael的消息组a00长度和密钥长度可以是128/192/256比特。为了方便数据的计算和算法的描述,限制密钥长度为128位,128位输入分成16个字节,每字节8位,密码也类似由一个4阶方阵组成,NK等于密码的长度除以32:
有限域中的元素是按字节计算的,GF(28)的元素代表8比特的字节。例如x7+x6+x3+x+1代表11001011,Rijindael算法选择的多项式为x8+x4+x3+x+1。
设Nb为一个消息组经上述处理后得到的字的个数,Nk为加密密钥处理后的字的个数。那么Nb=4,6,8;Nk=4,6,8,加密的轮数Nr根据表1由Nb和Nk控制。
Rijindael算法由10轮、12轮、14轮循环组成,加密过程的每轮循环都有一个循环密钥,每轮循环有4个基本步骤组成:字节转换、移动行变换、混合列变换、加循环密钥。因属对称加密,在加密和解密时都使用相同的密钥。
表1 密钥长度Nb、加密分组长、加密轮数Nr之间的关系
(1)取明文分组为128bit的数据X,
(2)与原始密钥k1异或
(3)s盒变换
(4)行置换
(5)列置换
(6)与子密钥Ki异或
(7)重复(3)~(6)
(1)取加密分组数据S
(2)与子密钥 Ki+1异或
(3)反行置换
(4)反盒置换
(5)与子密钥Ki异或
(6)反列置换
(7)得解密分组数据
(8)恢复明文分组数据
Rijindael算法常被用于文件的加解密过程,加密时先将读入的明文依次分组,用加密密钥将明文加密后写入文件中;解密时用解密密钥将文件中的密文解密后将明文写入结果文件中。
public static void EncryptTextToFile(String Data,String FileName,byte[]Key,byte[]IV)
{
try
{//创建文件
FileStream fStream = File.Open(FileName,File-Mode.OpenOrCreate);
//创建新的Rijndael对象
Rijndael RijndaelAlg = Rijndael.Create();
//创建加密流,以passed key和initialization vector(IV)填充
CryptoStream cStream=new CryptoStream(fStream,Ri
jndaelAlg.CreateEncryptor(Key,IV),
CryptoStreamMode.Write);
//用加密流创建StreamWriter StreamWriter sWriter=new StreamWriter(cStream);
try
{//加密
sWriter.WriteLine(Data);
}
catch(Exception e)
{
Console.WriteLine("An error occurred:{0}",e.Message);
}
finally
{//关闭文件
sWriter.Close();
cStream.Close();
fStream.Close();
}
}
catch(CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred:{0}",e.Message);
}
catch(UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred:{0}",e.Message);
}
}
从文件中读取密文实现关键代码:
public static string DecryptTextFromFile(String File-
Name,byte[]Key,byte[]IV)
{
try
{//创建文件流
FileStream fStream = File.Open(FileName,File-Mode.OpenOrCreate);
//创建新的Rijndael对象
Rijndael RijndaelAlg = Rijndael.Create();
//创建加密流,以 passed key和 initialization vector(IV)填充
CryptoStream cStream=new CryptoStream(fStream,RijndaelAlg.CreateDecryptor(Key,IV),
CryptoStreamMode.Read);//用加密流创建StreamWriter
StreamReader sReader=new StreamReader(cStream);string val=null;
try
{//解密
val= sReader.ReadLine();
}
catch(Exception e)
{
Console.WriteLine("An error occurred:{0}",e.Message);
}
finally
{//关闭文件
sReader.Close();
cStream.Close();
fStream.Close();
}
//返回密码结果
return val;
}
catch(CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred:{0}",e.Message);
return null;
}
catch(UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred:{0}",e.Message);return null;
}
}
try
{//创建新的Rijndael对象以产生Key和IV(初始化向量)
Rijndael RijndaelAlg = Rijndael.Create ();//需要加密的字符串及保存的文件名
string sData="Here is some data to encrypt.";
string FileName="CText.txt";
//利用Key和IV加密字符串到文件中Encrypt-TextToFile(sData,FileName,RijndaelAlg.Key,RijndaelAlg.IV);
//利用Key和IV从文件中解密
string Final=DecryptTextFromFile(FileName,Rijn
daelAlg.Key,RijndaelAlg.IV);
//显示密码
Console.WriteLine(Final);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Rijndael算法作为AES标准,其密钥长度的安全性已经足够,分析结果表明,7轮以上的Rijndael对于square攻击是安全的。Rijndael算法已被广泛应用于身份认证、数字签名、结点加密机、网络加密等方面。Rijndael也有一个非常小的版本(52位),适用在蜂窝电话、个人数字处理器(PDA)和其他的小设备上。
[1]段钢.加密与解密[M].3版.北京:电子工业出版社,2008.
[2]冯登国.信息安全中的数学方法与技术[M].北京:清华大学出版社,2009.
[3]裴定一,徐祥.信息安全数学基础[M].北京:人民邮电出版社,2007.
[4]高永强,郭世泽.网络安全技术与应用大典[M].北京:人民邮电出版社,2004.
[5]王衍波,薛通.应用密码学[M].北京:机械工业出版社,2003.