应用Cryptopp库实现AES加密【转】

2023-11-12


crypto++自身的wiki上就有一些例子,可以参考:

   http://www.cryptopp.com/wiki/Category:Sample

(本文来源:http://ste.xidian.edu.cn/bbs/a/a.asp?B=5&ID=224&p=1&q=1&r=146  )

应用Cryptopp库实现AES加密


在win32的操作系统下用vc6++来编译Crypto++? Library 5.1 的源代码,在对应的目录下会产生文件夹Debug,在文件夹Debug里,会有一个编译好的静态库文件cryptlib.lib;下面通过实例研究这个静态库文件的使用:

在应用lib文件时先把库里的头文件和lib文件复制到工程的目录里这是最好的方法,或者把它们放到一个文件夹里修改指定的include 目录,即在菜单Tools中选Options,在Options的对话框里选Directories 在include files和Library files 的页面添加指向该文件夹的路径。



Hash函数的应用:

Hash函数的最基本的用法就是计算Hash值,一个Hash函数是一个多对一的映射,可以输入任意长度的消息,输出却是一个固定长度的消息,而且,只要有一点很微小的差异的两个消息之间的Hash值也会有很大的差异,根据两个不同的Hash值就可以判断对应的两个消息是不同的。所以Hash函数通常用于数字签名和消息的完整性检测等等一些安全性方面的应用。下面举一个计算字符串的Hash值简单的例子。

#pragma comment (lib,"cryptlib.lib")  //加载lib文件的语句

#include "md5.h"

#include <iostream>

using namespace CryptoPP; //使用名字空间CryptoPP

 using namespace std; //使用名字空间std



void main(){

    byte message[128];       byte m[16];

       cout<<"输入字符串"<<endl; cin.getline((char*) message,128);  

       MD5 md5; md5.Update(message,128); md5.Final(m);        

       for(int i=0;i<16;i++)printf("%02x",m);printf("\n");            

}

这个例子首先生成MD5对象(类MD5在md5.h里定义),调用方法Update()和Final(),这两个方法是定义在基类HashTransformation里的。void Update (const byte *input, unsigned int length) 是用来处理输入的方法,input 是byte型是将要计算Hash值的字符串,length是字符串的长度。void Final (byte *digest) 是计算当前消息的Hash值并重新开始新的消息的方法,digest是用来存放Hash值的byte型数组。

HashTransformation还定义了几个常用的方法 void CalculateDigest (byte *digest, const byte *input, unsigned int length)也是用来计算hash值的方法,可以用md5. CalculateDigest(m,message,128),来替换上面例子md5.Update(message,128)与 md5.Final(m) 这两个语句。

在消息完整性检测方面我们通常都是检测文件的完整性,一个相当大的文件如果对其进行一个很微小的修改我们根本看不出的,但是它们的Hash值却有很大的变化,所以我们只要比较Hash值就很容易看出该文件是否为原来的文件。计算文件的Hash值在这个密码库的支持下就比较简单就用下面的一行代码就行了

FileSource f(file, true, new HashFilter(md5,

                new HexEncoder(new ArraySink(buffer,2 * MD5::DIGESTSIZE))));

这一行代码总共用了4个类ArraySink、HexEncoder、HashFilter和FileSource。首先用类ArraySink复制一个2 * MD5::DIGESTSIZE 字节的buffer存储缓冲区,接着用类HexEncoder把这个缓冲区转换为16进制。计算Hash值主要用到类HashFilter。类FileSource是把要计算Hash值的文件file进行一定的转换放入临时缓冲区,然后调用实例化的HashFilter对其进行计算相应Hash函数的Hash值。

对称密码的应用

我们说明DES的编程。DES有四种工作模式:电子密码本模式(electronic codebook mode),密码分组链接模式(cipher block chaining mode),密码反馈模式(cipher feedback mode)以及输出反馈模式(output feedback mode)。

应用对称密码首先我们要确定用那种工作模式,即用ECB, CBC, CFB和OFB中的那种模式。Crypto++提供的工作模式对象,其本质上是把分组密码(block cipher)转换成序列密码(stream cipher)。下面就是创建工作模式CFB的例子:

byte key[AES::DEFAULT_KEYLENGTH], iv[AES::BLOCKSIZE];
CFB_Mode<AES >::Encryption cfbEncryption(key, AES::DEFAULT_KEYLENGTH, iv);

其中iv 是一个增量值,可以随便取一个字符串。

知道什么创建工作模式后我们就通过具体的例子来研究对称密码的用法。下面我们来看高级加密标准AES在工作模式CFB下的简单应用。

string AESEncryptString(const char *instr, const char *passPhrase) // AES加密字符串函数{


    std::string outstr;

    byte iv[AES::BLOCKSIZE]="123456";

    AES::Encryption aesEncryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH);

CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);

    StreamTransformationFilter 

cfbEncryptor(cfbEncryption, new HexEncoder(new StringSink(outstr)));

    cfbEncryptor.Put((byte *)instr, strlen(instr));

    cfbEncryptor.MessageEnd();

    return outstr;

}

string AESDecryptString(const char *instr, const char *passPhrase)// AES解密字符串函数{


    std::string outstr;

    byte iv[AES::BLOCKSIZE]="123456";

    CFB_Mode<AES >::Decryption 

cfbDecryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH, iv);

    HexDecoder 

decryptor(new StreamTransformationFilter(cfbDecryption, new StringSink(outstr)));

    decryptor.Put((byte *)instr, strlen(instr));

    decryptor.MessageEnd();

    return outstr;

}

在应用这两个函数时要加三个头文件 aes.h、hex.h和modes.h。

加密函数string AESEncryptString(const char *instr, const char *passPhrase)中参数instr是要加密的字符串,passPhrase是密钥。这个函数的基本流程为:先用密钥passPhrase初始化一个AES的加密对象aesEncryption,然后用aesEncryption和增值量iv创建一个加密的CFB工作模式,iv是可以随便取一个字符串,但是要注意加密使用的iv要和解密的一样,否则解密不了。这里我们用了一个流过滤器StreamTransformationFilter对工作模式进行包装, StreamTransformationFilter可以作为一个Filter对象。StreamTransformationFilter将在需要的时候将缓冲区数据阻塞。为了让输出的密文比较直观,我们在处理输出时用十六进制输出,所以我们在这里用了转换为十六进制的类HexEncoder。方法Put()是对输入进行处理,然后调用上面的加密对象对字符串进行加密,方法MessageEnd()是输入的结束性标志。

解密函数string AESDecryptString(const char *instr, const char *passPhrase) 中参数instr是要解密的密文,passPhrase是密钥。解密函数的基本流程和加密的差不多,只是用到的类和加密的是相对的。用密钥passPhrase和iv创建一个AES解密的CFB工作模式对象cfbDecryption,然后用流过滤器StreamTransformationFilter对工作模式进行包装,用转化十六进制为byte型的类HexDecoder对对象进行转化得出对象decryptor,再调用方法Put()对输入进行处理,然后调用上面的加密对象对字符串进行解密。

现在我们就用这两个函数对字符串“贵州大学计算机软件与理论研究所 Guizhou University”进行加解密,密钥我们用“guizhoudaxue”,在vc6编译平台下,运行结果为:






由于AES加密速度比较快、效率高而且比较安全,所以我们通常用来对文件进行加解密,下面我们就来看加解密文件的例子。
void AESEncryptFile(const char *in, const char *out, const char *passPhrase)//加密文件

{

       byte iv[AES::BLOCKSIZE]="123456";

    AES::Encryption aesEncryption((byte *)passPhrase, AES::DEFAULT_KEYLENGTH);

       CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);

       FileSource

 f(in, true, new StreamTransformationFilter(cfbEncryption, new FileSink(out)));

}

void AESDecryptFile(const char *in, const char *out, const char *passPhrase)//解密文件

{

       byte iv[AES::BLOCKSIZE]="123456";

    CFB_Mode<AES >::Decryption cfbDecryption((byte *)passPhrase, 16, iv);

       FileSource 

  f(in, true, new StreamTransformationFilter(cfbDecryption, new FileSink(out)));      

}

在应用这两个函数时要加四个头文件 aes.h、hex.h、files.h和modes.h。

加密函数void AESEncryptFile(const char *in, const char *out, const char *passPhrase)中参数in是要加密的文件名,out是要解密的文件名,passPhrase是密钥。这个函数的基本流程为:先用增量值iv和密钥passPhrase创建一个AES加密的CFB工作模式对象aesEncryption。

下面来看在工作模式CBC下用DES-EDE对字符串加解密的简单例子。下面给出两个函数。

string EncryptString(const char *instr, const char *passPhrase){ //加密函数

       string outstr;

       DefaultEncryptorWithMAC  //生成对象

encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));

       encryptor.Put((byte *)instr, strlen(instr)); encryptor.MessageEnd(); return outstr;

}

string DecryptString(const char *instr, const char *passPhrase){ //解密函数

       string outstr;

       HexDecoder 

decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));

       decryptor.Put((byte *)instr, strlen(instr));     decryptor.MessageEnd();      return outstr;

}

加密函数string EncryptString(const char *instr, const char *passPhrase) 中instr是要加密的字符串,passPhrase是用来加密的密钥。这个函数用了密码库里的四个类DefaultEncryptorWithMAC、HexEncoder和StringSink。StringSink 是类StringSinkTemplate<std::string>的一个实例化,主要作用是添加输入到一个字符串对象。HexEncoder在hex.h里定义是用来转换所给的数据为十六进制。DefaultEncryptorWithMAC在default.h里定义,是用DES-EDE2 和 HMAC/SHA-1 在密钥下进行加密,Put()和MessageEnd()是这个类的两个基本的方法。unsigned int Put (const byte *inString, unsigned int length, bool blocking=true)是用来处理输入多重的字节,bool MessageEnd (int propagation=-1, bool blocking=true)用来作为输入消息的结束标志。这个函数的基本流程是:首先用类StringSink 把outstr添加到一个String对象,接着用HexEncoder把这个对象转换为十六进制。然后用加密密钥passPhrase产生一个DefaultEncryptorWithMAC对象encryptor,最后调用encryptor的方法Put()来处理输入instr进而对其进行加密,把加密后的密文放到outstr。

解密函数string DecryptString(const char *instr, const char *passPhrase) 中instr是要解密的字符串,passPhrase是用来解密的密钥,跟加密的密钥要相同。也用了三个类HexDecoder、DefaultDecryptorWithMAC和StringSink。HexDecoder是把给定的十六进制数据转换成为byte型。DefaultDecryptorWithMAC 也是定义在default.h文件里与类DefaultEncryptorWithMAC相应的是用来解密。这个函数的基本流程是:首先用类StringSink 把outstr添加到一个String对象,然后用解密密钥passPhrase产生一个DefaultDecryptorWithMAC对象,利用类HexDecoder对DefaultDecryptorWithMAC对象进行数据转换生成对象decryptor,然后利用decryptor的方法Put()进行输入处理,进而进行解密,把解密后的明文放到outstr。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应用Cryptopp库实现AES加密【转】 的相关文章

  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • linux-x64 二进制文件无法在 linuxmusl-x64 平台上使用错误

    我正在安装Sharp用于使用 package json 的 Nodejs 项目的 docker 映像上的映像压缩包 当我创建容器时 我收到有关 Sharp 包的以下错误 app node modules sharp lib libvips
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • 执行“minikube start”命令时出现问题

    malik malik minikube start minikube v1 12 0 on Ubuntu 18 04 Using the docker driver based on existing profile Starting c
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 使用包管理器时如何管理 Perl 模块?

    A 最近的问题 https stackoverflow com questions 397817 unable to find perl modules in intrepid ibex ubuntu这让我开始思考 在我尝试过的大多数 Li
  • 从 Xlib 转换为 xcb

    我目前正在将我的一个应用程序从 Xlib 移植到 libxcb 但在查找有关我有时使用的 XInput2 扩展的信息时遇到了一些麻烦 libxcb 中有 XInput2 实现吗 如果是的话 在哪里可以找到文档 目前我在使用此功能时遇到问题
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • 使用 python 脚本更改 shell 中的工作目录

    我想实现一个用户态命令 它将采用其参数之一 路径 并将目录更改为该目录 程序完成后 我希望 shell 位于该目录中 所以我想实施cd命令 但需要外部程序 可以在 python 脚本中完成还是我必须编写 bash 包装器 Example t
  • 这种文件锁定方法可以接受吗?

    我们有 10 个 Linux 机器 每周必须运行 100 个不同的任务 这些计算机主要在我们晚上在家时执行这些任务 我的一位同事正在开发一个项目 通过使用 Python 自动启动任务来优化运行时间 他的程序将读取任务列表 抓取一个打开的任务
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • 为什么同一个curl命令在windows和linux下输出不同的东西?

    为什么同样的curl o file https www link com 命令输出不同的东西 例如 如果我运行命令curl o source txt https www youtube com playlist list PLIx6Fwnp
  • [A-Z] 表示 [A-Za-z] 是怎么回事?

    我已经注意到 至少在我使用的一些基于 Unix 的系统上 ls A Z 已经给了我预期的结果ls A Za z 让我无法轻松获得以大写字母开头的该死的文件列表 我刚刚遇到了同样的事情grep 我无法让它停止与小写字母匹配 A Z 直到我最终
  • 如何在文件中搜索多行模式?

    我需要找到包含特定字符串模式的所有文件 我想到的第一个解决方案是使用find管道与xargs grep find iname py xargs grep e YOUR PATTERN 但是 如果我需要查找跨越多行的模式 我就会陷入困境 因为
  • 从核心转储中获取堆栈跟踪

    如何从核心转储文件中获取堆栈跟踪 该文件大约 14 mb 是在我的应用程序退出并显示 分段错误 后生成的 我使用的是红帽 5 5 gdb usr bin myapp binary corefile 然后 使用以下之一 gdb bt gdb
  • 如何在Linux中自动启动需要X的应用程序

    我试图在系统进入运行级别 5 时自动启动 X 应用程序 这样做的正确方法是什么 我写了一个脚本并将其放在 etc init d 中 我已运行适当的 chkconfig 命令来设置 etc rcX d 目录中的符号链接 一切工作正常 除了当我
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu

随机推荐

  • JDK的安装及配置详细图文教程(win10)

    JDK的下载 进入官网 选择Products下的Software下的java 官网 下拉 找到java SE页面并选择Oracle JDK 进入后选择JDK Download 然后就会进入到jdk最新版本的下载界面 选择系统对应的下载安装包
  • Linux创建用户并修改shell类型

    base root 57beff3260ef sudo su test exit base root 57beff3260ef apt get install zsh base root 57beff3260ef echo SHELL bi
  • react html 显示,react如何控制元素的显示与隐藏功能?

    react如何控制元素显示与隐藏 在vue中常用v if和v show指令 react中用什么方法呢 下面本篇文章给大家介绍一下 有一定的参考价值 有需要的朋友可以参考一下 希望对大家有所帮助 下面说我知道的三种方法 1 通过 state
  • Python3内置模块

    1 os all functions from posix nt or ce e g unlink stat etc os name is either posix nt or ce os curdir is a string repres
  • jvm不同版本(jdk6、jdk7、jdk8)之间的class常量池、运行时常量池、字符串常量池与堆、方法区的种种关系

    这几天研究了一下JVM底层原理 其中的内存分配前前后后看了三天 感觉还是没太看透 先研究到这 做个阶段性的笔记 感兴趣的小伙伴们欢迎大家评论区共同讨论 查阅了各种博客 长篇大论 例证太多 不清晰 本文主要目的精简浓缩一下 感兴趣的去文中参考
  • 数据库报错1264错误

    数据库报错1264 php程序报错1264 这个原因有可能是字段长度不够 改变一下字段长度
  • Install Ubuntu 12.04 on Macbook pro Retina

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 Install rEFIt Download and mount the rEFIt 0 14 dmg disk image Double click on the r
  • log4j 2读取配置文件的三种方法

    log4j 2读取配置文件的三种方法 log4j 2读取的配置文件可以分为三类 src下的配置文件 绝对路径的配置文件 相对路径的配置文件 我们一一给例子 直接看代码 package com herman test import java
  • 【Linux之Shell脚本实战】查询邮政编码与对应地区

    Linux之Shell脚本实战 查询邮政编码与对应地区 一 脚本要求 二 检查本地系统环境 1 检查系统版本 2 检查系统内核版本 三 配置脚本注释模板 1 编辑 vimrc 文件 2 检查模板生效情况 四 编辑shell脚本 1 创建脚本
  • 「数据结构」三步搞定表达式中缀转后缀 手算法 通俗易懂 C语言

    表达式中缀转后缀 举个例子 一个式子 5 20 1 3 14 如何把该式子转换成后缀表达式呢 其实就是分三步 按运算符优先级对所有运算符和它的运算数加括号 原本有括号的不用加 把运算符移到对应的括号后 去掉括号 对应的具体实现为 5 20
  • 音视频开发系列-音视频核心知识精讲

    音视频开发系列 音视频核心知识精讲 1 视频为什么会花屏 2 音频为什么容易有杂音 3 音视频进阶需要掌握什么项目 音视频核心知识 为什么会花屏 容易有杂音 进阶需要掌握什么项目 https www bilibili com video B
  • day09:定时器

    目录 总结 1 三种解绑事件 2 事件冒泡 3 阻止事件冒泡 4 事件委托 事件代理 5 事件的三个阶段 一 最大的匿名函数 二 定时器setInterval 三 一起摇摆案例 四 亮起来案例 五 美女时钟效果 六 进一步优化时钟 七 渐变
  • 我们用4行代码节省了100万 相见恨晚的PCDN

    我们公司主要做视频在线点播 还有少量视频下载 比较关心网络加速 首先就是价格 其次是首播时间 流畅率这几个核心性能指标 目前使用阿里云PCDN也有几个月了 整体结果是超预期 值得安利的 写这篇文章 希望能通过选型对比 接入过程 效果实现几个
  • torchserve使用-注册模型设置参数(二)

    目录 1 自定义处理程序 2 托管多个模型 3 模型接口 3 1 添加注册新模型 3 2 查看是否注册成功 3 3 查看注册模型基本信息 3 4 设置注册模型参数 3 5 使用以下代码注销模型 3 6 模型版本控制 4 记录和指标 1 自定
  • xxl-job-admin多数据库支持

    记录一下改造过程 针对 xxl job 2 3版本 什么是xxl job 你的系统中有很多定时任务 如果你想统一管理 你需要一个调度系统 XXL JOB是一个分布式任务调度平台 其核心设计目标是开发迅速 学习简单 轻量级 易扩展 githu
  • 机器学习初实践——恶意域名检测

    这次恶意域名检测实践是第一次自己做机器学习而非单纯复现 参考了第一次鸢尾花的代码和GitHub的UrlDetect中的特征提取参数的代码 一 数据处理 首先要实现自动化处理数据 在这里我没有使用urlparser而是直接写脚本提取域名 提取
  • 【南邮操作系统实验】页面置换算法 (FIFO、LRU、OPTP)

    写在前面 操作系统内存管理的页面置换算法 因为懒得看老师给的代码 太长了而且据说好像还有错误 就自己写了一个python版本的 因为比较菜 所以写的一般般 仅供大伙参考一下Orz python版本的 代码如下 import random 生
  • mysql视图基本操作

    mysql视图介绍及如何创建视图请看 一个案例理解mysql视图 本章主要记录视图的修改 删除以及展示视图语法 目录 一 创建视图 二 修改视图 三 删除视图 四 更新视图 五 展示视图 一 创建视图 请看 一个案例理解mysql视图 二
  • Docker 使用网络

    文章目录 外部访问容器 端口绑定 映射所有接口地址 映射到指定地址的指定端口 查看当前端口配置 多个端口绑定 容器互联 配置 DNS 外部访问容器 1 使用 P 标记时 Docker 会随机映射一个 490000 49900 的端口到内部容
  • 应用Cryptopp库实现AES加密【转】

    crypto 自身的wiki上就有一些例子 可以参考 http www cryptopp com wiki Category Sample 本文来源 http ste xidian edu cn bbs a a asp B 5 ID 224