AES加密算法实验报告.docx
实 验 报 告 _专业: _第 10 周课程名称密码学与网络安全实验课时实验项目AES加密算法实验时间实验目的完成AES加密算法,实现图片加密与解密,并将加密后的结果以图片格式保存.实验环境PC机,Windows7操作系统,Visual C+ 6.0实验内容算法、程序、步骤和方法一、 简介美国国家标准技术研究所在2001年发布了高级加密标准AES.AES是一个对称加密算法,旨在取代DES成为广泛使用的标准.AES中的所有运算都是在8为的字节上运行的.特别饿,加减乘除算术都是在有限域GF<28>上运行的.二、 程序特点本次试验中要求对图片进行加密与解密,并将加密结果以图片格式进行保存.因此为了实现对图片的调度与保存,使用头文件atlimage.h进行对图片的操作,实现对图片的像素读取,图片的保存.在程序运行读取需要加密的图片时,需要进行图片的选取,本次实验中使用在弹窗中选取文件的方式,使用头文件mdlg.h来实现在文件夹中选择需要的文件的选取.三、 加密算法流程AES加密算法流程如下字节代替:用一个S盒完成分组的字节到字节的代替;行移位:进行一次行上的置换;列混合:利用有限域GF<28>上的运算特性的一个代替;轮密钥加:当前分组和扩展密钥的一部分进行按位异或.四、 代码实现cryptograph.h#include<string>#include<iostream>classplaintextpublic:plaintext<>staticvoid createplaintext<unsignedchar a>staticvoid SubBytes<unsignedchar p16>staticvoid inSubBytes<unsignedchar p16>staticvoid ShiftRows<unsignedchar e>staticvoid inShiftRows<unsignedchar e>staticvoid MatrixToByte<unsignedchar e>staticvoid inMatrixToByte<unsignedchar e>staticunsignedchar FFmul<unsignedchar a, unsignedchar b>staticvoid KeyAdding<unsignedchar state16, unsignedchar k4>staticvoid KeyExpansion<unsignedchar* key, unsignedchar w44>plaintext<>private:;cryptograph.cpp#include"cryptography.h"usingnamespace std;staticunsignedchar sBox = ;/定义加密S盒/unsignedchar insBox256 =;/定义解密S盒plaintext:plaintext<>voidplaintext:createplaintext<unsignedchara>/创建明文int i = 0;unsignedint p16;for <int j = 0; j<200; j+>if <aj = 0>break;for < i<16; i+>pi = ai;ai = ai + 16;voidplaintext:SubBytes<unsignedcharp16>/字节变换函数unsignedchar b16;for <int i = 0; i<16; i+>bi = sBox<int>pi;voidplaintext:inSubBytes<unsignedcharp16>/逆字节变换函数unsignedchar b16;for <int i = 0; i<16; i+>bi = insBox<int>pi;voidplaintext:ShiftRows<unsignedchare>/行移位变换函数unsignedchar t4;for <int i = 1; i<4; i+>for <int x = 0; x<4; x+>tx = ex + i * 4;for <int y = 0; y<4; y+>e<y + 4 - i> % 4 + i * 4 = ty;voidplaintext:inShiftRows<unsignedchare>/逆行移位变换函数unsignedchar t4;for <int i = 1; i<4; i+>for <int x = 0; x<4; x+>tx = ex + i * 4;for <int y = 0; y<4; y+>e<y + i> % 4 + i * 4 = ty;voidplaintext:MatrixToByte<unsignedchare>/列混合变换函数unsignedchar t4;int r, c;for <c = 0; c< 4; c+>for <r = 0; r<4; r+>tr = er * 4 + c;for <r = 0; r<4; r+>er * 4 + c = FFmul<0x02, tr> FFmul<0x03, t<r + 1> % 4> FFmul<0x01, t<r + 2> % 4> FFmul<0x01, t<r + 3> % 4>voidplaintext:inMatrixToByte<unsignedchare>/逆列混合变换函数unsignedchar t4;int r, c;for <c = 0; c< 4; c+>for <r = 0; r<4; r+>tr = er * 4 + c;for <r = 0; r<4; r+>er * 4 + c = FFmul<0x0e, tr> FFmul<0x0b, t<r + 1> % 4> FFmul<0x0d, t<r + 2> % 4> FFmul<0x09, t<r + 3> % 4>unsignedcharplaintext:FFmul<unsignedchara, unsignedcharb>unsignedchar bw4;unsignedchar res = 0;int i;bw0 = b;for <i = 1; i<4; i+>bwi = bwi - 1 << 1;if <bwi - 1 & 0x80>bwi = 0x1b;for <i = 0; i<4; i+>if <<a >> i> & 0x01>res = bwi;return res;voidplaintext:KeyAdding<unsignedcharstate16, unsignedchark4>/轮密钥加int r, c;for <c = 0; c<4; c+>for <r = 0; r<4; r+>stater + c * 4 = krc;voidplaintext:KeyExpansion<unsignedchar* key, unsignedcharw44>/密钥扩展int i, j, r, c;unsignedchar rc = 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 ;for <r = 0; r<4; r+>for <c = 0; c<4; c+>w0rc = keyr + c * 4;for <i = 1; i <= 10; i+>for <j = 0; j<4; j+>unsignedchar t4;for <r = 0; r<4; r+>tr = j ? wirj - 1 : wi - 1r3;if <j = 0>unsignedchar temp = t0;for <r = 0; r<3; r+>tr = sBoxt<r + 1> % 4;t3 = sBoxtemp;t0 = rci - 1;for <r = 0; r<4; r+>wirj = wi - 1rj tr;plaintext:plaintext<>main.cpp#include<iostream>#include<atlimage.h>#include<mdlg.h>/使用文件选取功能#include"cryptography.h"usingnamespace std;unsignedchar w1144 = 0 ;int len = 0;/图片每行需要加密的长度void Cipher<>/加密图片void inCipher<>/解密图片void Cipher<unsignedchara>unsignedchar b16;for <int i = 0; i < <len / 16> i+>for <int j = 0; j<16; j+>bj = aj + i * 16;plaintext:KeyAdding<b, w0>for <int n = 1; n <= 10; n+>plaintext:SubBytes<b>plaintext:ShiftRows<b>if <n != 10>plaintext:MatrixToByte<b>plaintext:KeyAdding<b, wn>for <int m = 0; m<16; m+>am + i * 16 = bm;void inCipher<unsignedchara>unsignedchar b16;for <int i = 0; i < <len / 16> ; i+>for <int j = 0; j<16; j+>bj = aj + i * 16;plaintext:KeyAdding<b, w10>for <int n = 9; n >= 0; n->plaintext:inShiftRows<b>plaintext:inSubBytes<b>plaintext:KeyAdding<b, wn>if <n>plaintext:inMatrixToByte<b>for <int m = 0; m<16; m+>am + i * 16 = bm;bool ImageCopy<constCImage &srcImage, CImage &destImage>int i, j;/循环变量if <srcImage.IsNull<>>returnFALSE;/源图像参数BYTE* srcPtr = <BYTE*>srcImage.GetBits<>int srcBitsCount = srcImage.GetBPP<>int srcWidth = srcImage.GetWidth<>int srcHeight = srcImage.GetHeight<>int srcPitch = srcImage.GetPitch<>/销毁原有图像if <!destImage.IsNull<>>destImage.Destroy<>/创建新图像if <srcBitsCount = 32> /支持alpha通道destImage.Create<srcWidth, srcHeight, srcBitsCount, 1>elsedestImage.Create<srcWidth, srcHeight, srcBitsCount, 0>BYTE *destPtr = <BYTE*>destImage.GetBits<>int destPitch = destImage.GetPitch<>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>>returnTRUE;bool inImageCopy<constCImage &srcImage, CImage &destImage>int i, j;/循环变量if <srcImage.IsNull<>>returnFALSE;/源图像参数BYTE* srcPtr = <BYTE*>srcImage.GetBits<>int srcBitsCount = srcImage.GetBPP<>int srcWidth = srcImage.GetWidth<>int srcHeight = srcImage.GetHeight<>int srcPitch = srcImage.GetPitch<>/销毁原有图像if <!destImage.IsNull<>>destImage.Destroy<>/创建新图像if <srcBitsCount = 32> /支持alpha通道destImage.Create<srcWidth, srcHeight, srcBitsCount, 1>elsedestImage.Create<srcWidth, srcHeight, srcBitsCount, 0>BYTE *destPtr = <BYTE*>destImage.GetBits<>int destPitch = destImage.GetPitch<>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>>returnTRUE;int main<>unsignedchar key16 = /固定密钥0x77, 0x59, 0xc5, 0xa4,0x55, 0x90, 0xa4, 0xa3,0xb2, 0xcc, 0x01, 0xa9,0xcb, 0xac, 0x77, 0x23 ;plaintext:KeyExpansion<key, w>TCHAR szBufferMAX_PATH = 0 ;/使用文件选取功能OPENFILENAME ofn = 0 ;ofn.lStructSize = sizeof<ofn>/ofn.hwndOwner = m_hWnd;ofn.lpstrFilter = _T<"">/要选择的文件后缀ofn.lpstrInitialDir = _T<"D:">/默认的文件路径ofn.lpstrFile = szBuffer;/存放文件的缓冲区ofn.nMaxFile = sizeof<szBuffer> / sizeof<*szBuffer>ofn.nFilterIndex = 0;ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;/标志如果是多选要加上OFN_ALLOWMULTISELECT BOOL bSel = GetOpenFileName<&ofn>CImage image, image2, image3;/读取图片image.Load<szBuffer>ImageCopy<image, image2>image2.Save<"e:/encryption.jpg">inImageCopy<image2, image3>image3.Save<"e:/reencryption.jpg">system<"pause">本数据记录和计算 运行程序,出现选择图片界面加密结束原图片 加密图片 解密图片结 论结 果 根据结果显示,程序成功的实现了对图片的加密,得到的加密后的结果仍然为图片,并成功地的解密得到了正确的解密后的图片.小 结 通过本次试验,成功的完成了对AES密码算法的初步编写,了解了AES算法的工作原理.对于图片加密方面,掌握了新的调用图片的方法,使用头文件atlimage.h大大简化了c+中对图片调用的难度.同时在文件读取方面使用了头文件mdlg.h,使得程序在使用上更加方便.指导老师评 议 成绩评定: 指导教师签名: