admin管理员组

文章数量:1532771

2024年1月20日发(作者:)

ASE算法原理与实现

产生背景

1、AES 是美国国家标准技术研究所NIST旨在取代DES的新一代的加密标准。NIST

对AES 候选算法的基本要求是:对称分组密码体制;密钥长度支持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

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、

using System;

using c;

using ;

using ;

using ;

using graphy;

using ;

namespace AES_DemoConApp

{

///

/// The helper class

///

public class CryptoHelper

{

// the provider

private ICryptoTransform encryptor; // encryptor object

private ICryptoTransform decryptor; // decryptor object

private const int BufferSize = 1024;

///

/// Construct function

///

/// the name of encryption

algorithm

/// the key

//构造函数

public CryptoHelper(string algorithmName, string key)

{

SymmetricAlgorithm provider = (algorithmName);

if (provider is DESCryptoServiceProvider)

{

//The key of DES algorithm must be 8 bit.

= es(ing(0, 8));

= new DESCryptoServiceProvider().IV;

}

else if (provider is TripleDESCryptoServiceProvider)

{

//The key of TripleDES algorithm is 16 bit.

= es(ing(0, 16));

= new TripleDESCryptoServiceProvider().IV;

}

else if (provider is RijndaelManaged)

{

//The key of AES algorithm must be 16 bit.

= es(ing(0, 16));

// = new RijndaelManaged().IV;

= new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,

0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

}

encryptor = Encryptor();

decryptor = Decryptor();

}

//加密

public void Cipher(byte[] bytePlainData, ref byte[] byteCipherData)

{

//Create plain stream

MemoryStream plainStream = new MemoryStream(bytePlainData);

//Create nullable cipher stream

MemoryStream cipherStream = new MemoryStream();

CryptoStream cryptoStream = new CryptoStream(cipherStream, encryptor,

);

//Write the plain stream into the cryptoStream

int iBytesRead = 0;

byte[] byteBuffer = new byte[BufferSize];

do

{

iBytesRead = (byteBuffer, 0, BufferSize);

(byteBuffer, 0, iBytesRead);

} while (iBytesRead > 0);

inalBlock();

// Get the ciphered byte data

byteCipherData = y();

}

//解密

public void InvCipher(byte[] byteCipherData, ref byte[] bytePlainData)

{

//Create the cipher stream

MemoryStream cipherStream = new MemoryStream(byteCipherData);

//Create the nullable plain stream

MemoryStream plainStream = new MemoryStream();

CryptoStream cryptoStream =

new CryptoStream(cipherStream, decryptor, );

// Write the cipher stream into the crypto stream

int iBytesRead = 0;

byte[] byteBuffer = new byte[BufferSize];

do

{

iBytesRead = (byteBuffer, 0, BufferSize);

(byteBuffer, 0, iBytesRead);

} while (iBytesRead > 0);

bytePlainData = y();

}

}

}

程序2、

using System;

using c;

using ;

using ;

namespace AES_DemoConApp

{

class Program

{

static void Main(string[] args)

{

//明文(以字节数组的形式表示)

byte[] plainText = new byte[] {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,

0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};

//存放加密后的密文(同样以字节数组形式表示)

byte[] cipherText = null; //new byte[16];

//存放解密后的明文

byte[] decipheredText = null;//new byte[16];

//加密的密钥

byte[] keyBytes = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,

0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};

ine("nAdvanced Encryption Standard Demo in .NET");

ine("nThe plaintext is: ");

DisplayAsBytes(plainText);

CryptoHelper helper2 = new CryptoHelper("Rijndael", "45678");

(plainText, ref cipherText);

ine("nThe resulting ciphertext is: ");

DisplayAsBytes(cipherText);

her(cipherText, ref decipheredText);

ine("nAfter deciphering the ciphertext, the result is: ");

DisplayAsBytes(decipheredText);

ine("nDone");

ne();

}

static void DisplayAsBytes(byte[] bytes)

{

for (int i = 0; i < ; ++i)

{

(bytes[i].ToString("x2") + " ");

if (i > 0 && i % 16 == 0) ("n");

}

ine("");

} // DisplayAsBytes()

}

}

运行结果

本文标签: 算法加密分组变换密钥