AES加密算法实验报告总结计划

时间:2020-11-19 09:53:35 手机站 来源:网友投稿

实 验 报 告

学号:姓名:专业: 班级: 第 10 周

课程

实验课时

2

密码学与网络安全

名称

实验

AES加密算法 实验时间

项目

实验

完成 AES加密算法,实现图片加密与解密,并将加密后的结果以图片格式保存。

目的

实验

环境



PC机, Windows7操作系统, Visual C++

实验

内容

(算

法、

程 序、步骤和方

法)



一、 简介

美国国家标准技术研究所在 2001 年发布了高级加密标准( AES)。

 AES是一个对称加密算法,旨在取代 DES成为广泛使用的标准。

AES中的所有运算都是在 8 为的字节上运行的。特别饿,加减乘除算术都是在有限域 GF(28) 上运行的。

二、 程序特点

本次试验中要求对图片进行加密与解密,并将加密结果以图片格式进行保存。因此为了实现对图片的调度及保存,使用头文件进行对图片的操作,实现对图片的像素读取,图片的保存。

在程序运行读取需要加密的图片时, 需要进行图片的选取, 本次实验中使用在弹窗中选取文件的方式,使用头文件来实现在文件夹中选择需要的文件的选

取。

三、 加密算法流程

AES加密算法流程如下

字节代替:用一个 S 盒完成分组的字节到字节的代替;

行移位:进行一次行上的置换;

列混合:利用有限域 GF(28) 上的运算特性的一个代替;

轮密钥加:当前分组和扩展密钥的一部分进行按位异或。

四、 代码实现

#include <string>

#include <iostream>

class plaintext

{

public :

plaintext();

static void createplaintext( unsigned char a[]);

static

void

SubBytes( unsigned char p[16]);

static

void

inSubBytes(

unsigned

char p[16]);

static

void

ShiftRows(

unsigned

char e[]);

static

void

inShiftRows(

unsigned

char e[]);

static

void

MatrixToByte(

unsigned

char e[]);

static

void

inMatrixToByte(

unsigned

char

e[]);

static

unsigned char FFmul( unsigned

char

a,

unsigned

char b);

static

void

KeyAdding(

unsigned

char state[16],

unsigned char k[][4]);

static

void

KeyExpansion(

unsigned

char * key,

unsigned

char w[][4][4]);

~plaintext();

private :

};

#include ""

using namespacestd;

static unsigned char sBox[] = {};

unsigned char insBox[256] ={};

plaintext ::plaintext()

{

}

void plaintext ::createplaintext(

{



/ 定义加密 S盒/

// 定义解密 S盒

unsigned char a[]) // 创建明文

int i = 0;

unsigned



int



p[16];

for



( int



j = 0; j<200; j++)

{

if

{



( a[j] == 0)

break ;

}

}

for (; i<16; i++)

{

p[i] =

a[i] =



a[i];

a[i + 16];

}

}

void plaintext

{



::SubBytes( unsigned char p[16]) // 字节变换函数

unsigned char b[16];

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

{

b[i] = sBox[(



int ) p[i]];

}

}

void plaintext



::inSubBytes(



unsigned char p[16]) // 逆字节变换函数

{

unsigned char b[16];

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

{

b[i] = insBox[(



int ) p[i]];

}

}

void plaintext



::ShiftRows(



unsigned char e[]) // 行移位变换函数

{

unsigned char t[4];

for ( int i = 1; i<4; i++)

{

for ( int x = 0; x<4; x++)

t[x] = e[x + i * 4];

for ( int y = 0; y<4; y++)

e[(y + 4 - i) % 4 + i * 4] = t[y];

}

}

void plaintext ::inShiftRows( unsigned char e[]) // 逆行移位变换函数

{

unsigned char t[4];

for ( int i = 1; i<4; i++)

{

for ( int x = 0; x<4; x++)

t[x] = e[x + i * 4];

for ( int y = 0; y<4; y++)

e[(y + i) % 4 + i * 4] = t[y];

}

}

void plaintext ::MatrixToByte( unsigned char e[]) // 列混合变换函数

{

unsigned char t[4];

int r, c;

for (c = 0; c< 4; c++)

{

for (r = 0; r<4; r++)

{

t[r] = e[r * 4 + c];

}

for (r = 0; r<4; r++)

{

e[r * 4 + c] = FFmul(0x02, t[r])

FFmul(0x03, t[(r + 1) % 4])

FFmul(0x01, t[(r + 2) % 4])

FFmul(0x01, t[(r + 3) % 4]);

}

}

}

void plaintext ::inMatrixToByte( unsigned char e[]) // 逆列混合变换函数

{

unsigned char t[4];

int r, c;

for (c = 0; c< 4; c++)

{

for (r = 0; r<4; r++)

{

t[r] = e[r * 4 + c];

}

for (r = 0; r<4; r++)

{

e[r * 4 + c] = FFmul(0x0e, t[r])

FFmul(0x0b, t[(r + 1) % 4])

FFmul(0x0d, t[(r + 2) % 4])

FFmul(0x09, t[(r + 3) % 4]);

}

}

}

unsigned char plaintext ::FFmul( unsigned char a, unsigned char b)

{

unsigned

char bw[4];

unsigned

char res = 0;

int

i;

bw[0] =

b;

for

(i = 1; i<4; i++)

{

bw[i] = bw[i - 1] << 1;

if (bw[i - 1] & 0x80)

{

bw[i] ^= 0x1b;

}

}

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

{

if (( a >> i) & 0x01)

{

res ^= bw[i];

}

}

return



res;

}

void



plaintext



::KeyAdding( unsigned char state [16],



unsigned char k [][4])



// 轮密钥加

{

int r, c;

for (c = 0; c<4; c++)

{

for (r = 0; r<4; r++)

{

state [r + c * 4] ^= k[r][c];

}

}

}

void plaintext ::KeyExpansion( unsigned char * key, unsigned char w[][4][4]) // 密钥扩展

{

int i, j, r, c;

unsigned char rc[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; for (r = 0; r<4; r++)

{

for (c = 0; c<4; c++)

{

w[0][r][c] = key [r + c * 4];

}

}

for (i = 1; i <= 10; i++)

{

for (j = 0; j<4; j++)

{

unsigned char t[4];

for (r = 0; r<4; r++)

{

t[r] = j ? w[i][r][j - 1] : w[i - 1][r][3];

}

if (j == 0)

{

unsigned char temp = t[0];

for (r = 0; r<3; r++)

{

t[r] = sBox[t[(r + 1) % 4]];

}

t[3] = sBox[temp];

t[0] ^= rc[i - 1];

}

for (r = 0; r<4; r++)

{

w[i][r][j] = w[i - 1][r][j] ^ t[r];

}

}

}

}

plaintext ::~plaintext()

{

}

#include <iostream>

#include <>

#include <>// 使用文件选取功能

#include ""

using namespacestd;

unsigned char w[11][4][4] = { 0 };

int len = 0; // 图片每行需要加密的长度

void Cipher(); // 加密图片

void inCipher(); // 解密图片

void Cipher( unsigned char a[])

{

unsigned char b[16];

for ( int i = 0; i < (len / 16); i++)

{

for ( int j = 0; j<16; j++)

b[j] = a[j + i * 16];

plaintext ::KeyAdding(b, w[0]);

for ( int n = 1; n <= 10; n++)

{

plaintext ::SubBytes(b);

plaintext ::ShiftRows(b);

if (n != 10) plaintext ::MatrixToByte(b);

plaintext ::KeyAdding(b, w[n]);

}

for ( int m = 0; m<16; m++)

a[m + i * 16] = b[m];

}

}

void inCipher( unsigned char a[]){

unsigned char b[16];

for ( int i = 0; i < (len / 16) ; i++)

{

for ( int j = 0; j<16; j++)

{

b[j] =



a[j + i * 16];

}

plaintext ::KeyAdding(b, w[10]);

for ( int n = 9; n >= 0; n--)

{

plaintext ::inShiftRows(b);

plaintext ::inSubBytes(b);

plaintext ::KeyAdding(b, w[n]);

if (n) plaintext ::inMatrixToByte(b);

}

for ( int m = 0; m<16; m++)

a[m + i * 16] = b[m];

}

}

bool ImageCopy( const CImage & srcImage , CImage &destImage )

{

int i, j;

if ())



// 循环变量

return



FALSE;

源图像参数

BYTE* srcPtr = ( BYTE*)();

int srcBitsCount = ();

int srcWidth = ();

int srcHeight = ();

int srcPitch = ();

销毁原有图像

if (!())

{

();

}

// 创建新图像

if (srcBitsCount == 32)

{



// 支持 alpha 通道

(srcWidth, srcHeight, srcBitsCount, 1);

}

else

{

(srcWidth, srcHeight, srcBitsCount, 0);

}

BYTE*destPtr = ( BYTE*)();

int destPitch = ();

len=abs(srcPitch);

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

Cipher(srcPtr + i*srcPitch);

复制图像数据

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

{

memcpy(destPtr + i*destPitch, srcPtr + i*srcPitch, abs(srcPitch));

}

return TRUE;

}

bool inImageCopy( const CImage &srcImage , CImage &destImage )

{

int

if



i, j;

())



// 循环变量

return



FALSE;

源图像参数

BYTE* srcPtr = ( BYTE*)();

int srcBitsCount = ();

int srcWidth = ();

int srcHeight = ();

int srcPitch = ();

销毁原有图像

if (!())

{

();

}

// 创建新图像

if (srcBitsCount == 32)

{



// 支持 alpha 通道

(srcWidth, srcHeight, srcBitsCount, 1);

}

else

{

(srcWidth, srcHeight, srcBitsCount, 0);

}

BYTE*destPtr = ( BYTE*)();

int destPitch = ();

len = abs(srcPitch);

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

inCipher(srcPtr + i*srcPitch);

复制图像数据

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

{

memcpy(destPtr + i*destPitch, srcPtr + i*srcPitch, abs(srcPitch));

}

return TRUE;

}

int

{



main()

unsigned char key[16] = { 0x77, 0x59, 0xc5, 0xa4, 0x55, 0x90, 0xa4, 0xa3, 0xb2, 0xcc, 0x01, 0xa9, 0xcb, 0xac, 0x77, 0x23 };



// 固定密钥

plaintext



::KeyExpansion(key, w);

TCHARszBuffer[ MAX_PATH] = { 0 }; // 使用文件选取功能

OPENFILENAMEofn = { 0 };

sizeof (ofn);

= m_hWnd;

_T( "" ); // 要选择的文件后缀

_T( "D:\\" ); // 默认的文件路径

szBuffer; // 存放文件的缓冲区

= sizeof (szBuffer) / sizeof (*szBuffer);

0;

OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST| OFN_EXPLORER; // 标志如果是多选要加上

OFN_ALLOWMULTISELECT

BOOLbSel = GetOpenFileName(&ofn);

CImage image, image2, image3; // 读取图片

(szBuffer);

ImageCopy(image, image2);

( "e:/" );

inImageCopy(image2, image3);

( "e:/" );

system( "pause" );

}

运行程序,出现选择图片界面

本数

据记



加密结束

和计



原图片



加密图片



解密图片

根据结果显示,程序成功的实现了对图片的加密,得到的加密后的结果仍然为图片,并成

结 功地的解密得到了正确的解密后的图片。

(结

果)

通过本次试验,成功的完成了对 AES密码算法的初步编写,了解了 AES算法的工作原理。

对于图片加密方面,掌握了新的调用图片的方法



,使用头文件大大简化了



c++中对图片调

小 用的难度。

同时在文件读取方面使用了头文件,使得程序在使用上更加方便。

指导

老师

成绩评定: 指导教师签名:

  • 下载文档
  • 收藏
  • 0

推荐访问:实验报告 加密算法 实验 计划 AES加密算法实验报告总结计划

版权声明 :以上文章中选用的图片文字均来源于网络或用户投稿 ,如果有侵权请立即联系我们 , 我们立即删除 。