摘 要:介绍了高级加密标准Rijndael算法的背景和特点,深入研究和分析了该算法的实现原理和过程,并给出了该算法在文件加解密过程实现的关键代码。
关键词:Rijndael算法;状态;密钥
1 Rijndael算法的背景
AES(Advanced Encryption Standard)是美国联邦标准局于1997年开始向全世界征集的加密标准[1],属于对称加密算法,代表了当今最先进的编码技术,最终获胜的是RijnDael算法。统计显示,即使使用目前世界上运算速度最快的计算机,穷尽128 bit密钥也需要几十亿年的时间,更不用说去破解采用256 bit密钥长度的AES算法了。
Rijndael算法由比利时计算机科学家Vincent Rijmen和Joan Daemen开发,它使用128 bit、192 bit、256 bit的密钥长度,比56 bit的DES更健壮可靠[3]。美国国家标准技术研究所选择Rijndael作为美国政府加密标准AES的加密算法,取代早期的数据加密标准DES[1]。Rijndael作为一种迭代分组加密算法,其数据块长度和密钥长度均是可变的,因此它汇聚了强安全性、高性能、高效率、易用、灵活等优点被广泛应用在各个领域中。
2 Rijndael算法的设计原理
Rijndael作为加密标准AES算法,其128 bit输入分组用以字节为单位的矩阵方阵描述[4]。该数组被复制到State数组。数据块长度、密钥长度可以被设定为128 bit、192 bit、256 bit三个可选长度,相应的加密轮数分别为10、12、14,每一轮循环都有一个循环密钥,它来自于初始密钥。
2.1 Rijndael算法的加密流程
加密过程分为四个阶段:密钥扩展、轮密钥加、Nr-1(128 bit、192 bit、256 bit密钥长度,Nr分别为10、12、14)轮变换及最后一轮变换。轮变换包括字节代换、行移位、列混淆和轮密钥加四个过程,最后一轮变换包括字节代换、行移位和轮密钥加三个过程。其流程图如图1所示。
(1)状态:指明文分组及每次变换的中间结果[4],是一个4×Nb的矩阵,Nb为数据块长度除以32。
(2)字符代换:用一个简单的查表操作代替了基于矩阵乘法的复杂仿射变换。S盒是一个16×16字节矩阵,包含8 bit值所能表达的256种可能的变换。把Statc中每个字节的高4位作为行值,低4位作为列值,取出S盒中对应行列的元素作为新的字节输出。
2.2 解密过程
Rijndael解密过程是加密的逆过程,每轮循环中的步骤都被它们的逆所替换,值得注意的是:循环密钥使用起来应该颠倒次序。
3 Rijndael算法的应用
Rijindael算法常被用于文件的加解密过程,加密时先将读入的明文依次分组,用加密密钥将明文加密后写入文件中;解密时用解密密钥将文件中的密文解密后将明文写入结果文件中。
3.1 Rijindael算法在文件加解密应用的实现
try
{// 创建新的Rijndael 对象以产生Key和IV
Rijndael RijndaelAlg= Rijndael.Create();
//需要加密的字符串及保存的文件名
string sData = "Here is some data to encrypt.";
string FileName = "CText.txt";
//利用Key和IV加密字符串到文件中
EncryptTextToFile(sData,FileName,RijndaelAlg.Key, RijndaelAlg.IV); //利用Key和IV从文件中解密
string Final=DecryptTextFromFile(FileName, RijndaelAlg.Key, RijndaelAlg.IV);
Console.WriteLine(Final); //显示密码
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
3.2加密模块实现
public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
{
try
{//创建文件
FileStream fStream=File.Open(FileName, FileMode.OpenOrCreate);
//创建新的Rijndael对象
Rijndael RijndaelAlg=Rijndael.Create();
//创建加密流,以passed key 和initialization vector (IV)填充
CryptoStream cStream = new CryptoStream(fStream,
RijndaelAlg.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);
}
}
3.3 解密模块的实现
public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] IV)
{
try
{ //创建文件流
FileStream fStream = File.Open(FileName, FileMode.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;
}
}
Rijndael算法一直经受着世界各国密码机构和专家的攻击,最有名的当属Squre攻击[4]。目前Rijndael算法已被广泛应用于身份认证、数字签名、数据加密等方面,由于硬件的加解密速度要比软件快,且可在物理上保证系统安全,国内很多单位用硬件的方法来实现该算法。
参考文献
[1] 段钢.加密与解密(第3版)[M].北京:电子工业出版社,2008.
[2] 冯登国.信息安全中的数学方法与技术[M].北京:清华大学出版社,2009.
[3] Http://zhidao.baidu.com.
[4] DAEMEN J, RIJMAN V.高级加密标准算法(AES)—Rijndael的设计[M].谷大武,徐胜波译.北京:清华大学出版社,2003.