ASE算法原理与实现
产生背景
1、AES 是美国国家标准技术研究所NIST旨在取代DES的新一代的加密标准。NIST 对AES 候选算法的基本要求是:对称分组密码体制writeline用什么替代;密钥长度支持128 ,192 ,256位;明文分组长度128 位;算法应易于各种硬件和软件实现。
2、1998 年NIST开始AES 第一轮征集、分析、测试,共产生了15 个候选算法。1999 年3 月完成了第二轮AES 的分析、测试。1999 年8 月NIST 公布了五种算法(MARS , RC6 ,Rijndael ,Serpent ,Twofish) 成为候选算法。最后,Rijndael ,这个由比利时人设计的算法与其它候选算法在成为高级加密标准(AES) 的竞争中取得成功,于2000 年10月被NIST宣布成为取代DES 的新一代的数据加密标准,即AES。
3、Rijndael 作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。
4、AES 设计有三个密钥长度:128 ,192 ,256 比特
AES 加密/ 解密算法原理
AES 算法属于分组密码算法,它的输入分组、输出分组以及加/ 解密过程中的中间分组都是128比特。(对称密码算法根据对明文消息加密方式的不同可分为两大类,即分组密码和流密码。分组密码将消息分为固定长度的分组,输出的密文分组通常与输入的明文分组长度相同。)
1、AES 的加密与解密框图如图所示
(1) 加密变换
设X是AES 的128 比特明文输入,Y是128 比特的密文输出,则AES 密文Y可以用下面的复合变换表示: Y= Ak(r + 1)·R·S·Akr·C·R·S·Ak(r21)·⋯·C·R·S·Ak1 (X)其中“·”表示复合运算。这里Aki :表示对X 的一个变换Aki (X) = XÝ Ki (Ki 为第i 轮的子密钥,为比特串的异或运算) 。S:S 盒置换。即对每一个字节用S2Box 做一个置换。S2Box 是一个给定的转换表。R: 行置换。C: 列置换。
s′(x) = a (x) á s (x)
这里á 是特殊的乘法运算
(2) 解密变换
解密变换是加密变换的逆变换。
2、AES(128bits密钥)加密解密流程如下图所示
(1)加密流程:
AESEncrypt (State, ExpandedKey)
{
AddRoundKey (State, ExpandedKey); //种子密钥加,实际已经进行过子密钥扩展
for (i=1; i <Nr; i ++) //Nr根据密钥长度进行取值
Round (State, ExpandedKey+Nb* i);//加密轮函数
FinalRound (State, ExpandedKey+Nb*Nr);//加密最后一轮轮函数
}
加密轮函数:
Round (State, RoundKey)
{
ByteSub (State); //字节替代变换
ShiftRow (State);//行移位变换
MixColumn (State);//列混合变换
AddRoundKey (State, RoundKey)//子密钥加(其实是一个简单的逐比特模2加)
}
加密最后一轮轮函数:
FinalRound (State, RoundKey)
{
ByteSub (State);//字节替代变换
ShiftRow (State);//行移位变换
AddRoundKey (State, RoundKey);//子密钥加
}
(2)解密流程:
AESDecrypt (State, ExpandedKey)
{
AddRoundKey (State, ExpandedKey+Nb*Nr);//子密钥加
for (i= Nr-1; i >=1; i --) // Nr根据密钥长度进行取值
InvRound (State, InvMixColumn (ExpandedKey+Nb* i));//解密轮函数
InvFinalRound (State, ExpandedKey); //解密最后一轮轮函数
}
解密轮函数:
InvRound (State, RoundKey)
{
InvShiftRow (State);//逆移位变换
InvByteSub (State);//逆字节替代变换
AddRoundKey (State, RoundKey);//子密钥加
InvMixColumn (State); //逆列混合变换
}
解密最后一轮轮函数:
InvFinalRound (State, RoundKey)
{
InvShiftRow (State);//逆移位变换
InvByteSub (State);//逆字节替代变换
AddRoundKey (State, RoundKey);//逆列混合变换
}
AES算法应用举例——控制台应用程序
程序1、
CryptoHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace AES_DemoConApp
{
/// <summary>
/// The helper class
/// </summary>
public class CryptoHelper
{
// the provider
private ICryptoTransform encryptor; // encryptor object
private ICryptoTransform decryptor; // decryptor object
private const int BufferSize = 1024;
{
/// <summary>
/// The helper class
/// </summary>
public class CryptoHelper
{
// the provider
private ICryptoTransform encryptor; // encryptor object
private ICryptoTransform decryptor; // decryptor object
private const int BufferSize = 1024;
/// <summary>
/// Construct function
/// </summary>
/// <param name="algorithmName">the name of encryption algorithm</param>
/// Construct function
/// </summary>
/// <param name="algorithmName">the name of encryption algorithm</param>
/// <param name="key">the key</param>
//构造函数
public CryptoHelper(string algorithmName, string key)
{
SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName);
if (provider is DESCryptoServiceProvider)
{
//The key of DES algorithm must be 8 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 8));
provider.IV = new DESCryptoServiceProvider().IV;
}
else if (provider is TripleDESCryptoServiceProvider)
{
//The key of TripleDES algorithm is 16 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 16));
public CryptoHelper(string algorithmName, string key)
{
SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName);
if (provider is DESCryptoServiceProvider)
{
//The key of DES algorithm must be 8 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 8));
provider.IV = new DESCryptoServiceProvider().IV;
}
else if (provider is TripleDESCryptoServiceProvider)
{
//The key of TripleDES algorithm is 16 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 16));
provider.IV = new TripleDESCryptoServiceProvider().IV;
}
else if (provider is RijndaelManaged)
{
//The key of AES algorithm must be 16 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 16));
//provider.IV = new RijndaelManaged().IV;
provider.IV = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
}
}
else if (provider is RijndaelManaged)
{
//The key of AES algorithm must be 16 bit.
provider.Key = Encoding.UTF8.GetBytes(key.Substring(0, 16));
//provider.IV = new RijndaelManaged().IV;
provider.IV = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
}
encryptor = provider.CreateEncryptor();
decryptor = provider.CreateDecryptor();
}
decryptor = provider.CreateDecryptor();
}
//加密
public void Cipher(byte[] bytePlainData, ref byte[] byteCipherData)
{
//Create plain stream
MemoryStream plainStream = new MemoryStream(bytePlainData);
{
//Create plain stream
MemoryStream plainStream = new MemoryStream(bytePlainData);
//Create nullable cipher stream
MemoryStream cipherStream = new MemoryStream();
MemoryStream cipherStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(cipherStream, encryptor, CryptoStreamMode.Write);
//Write the plain stream into the cryptoStream
int iBytesRead = 0;
byte[] byteBuffer = new byte[BufferSize];
do
int iBytesRead = 0;
byte[] byteBuffer = new byte[BufferSize];
do
{
iBytesRead = plainStream.Read(byteBuffer, 0, BufferSize);
cryptoStream.Write(byteBuffer, 0, iBytesRead);
} while (iBytesRead > 0);
iBytesRead = plainStream.Read(byteBuffer, 0, BufferSize);
cryptoStream.Write(byteBuffer, 0, iBytesRead);
} while (iBytesRead > 0);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论