大家好,又见面了,我是你们的朋友全栈君。
本文属于《OpenSSL加密算法库使用系列教程》之一,欢迎查看其它文章。
实战篇-OpenSSL之TripleDES加密算法-CFB64模式
- 一、TripleDES简介
- 二、CFB64模式
- 1、命令行操作
- 2、函数说明
- 3、编程实现
- (1)特别注意
- (2)实现CFB64模式加解密
- (3)测试代码
一、TripleDES简介
3DES又称Triple DES,是DES加密算法的一种模式,它使用2条不同的56位的密钥对数据进行三次加密。
数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。
DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。 它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。
Triple DES属于对称加密算法,加解密使用同一个秘钥。
对称加密算法,一般有至少4种模式,即ECB、CBC、CFB、OFB等。
具体的加密原理,就不进行介绍了,本文主要从使用角度,进行说明。
以下命令行和编程实现,均基于OpenSSL开源库。在命令行中,我们可以使用命令实现对文件加解密,以验证我们的编程实现,是否正确。
二、CFB64模式
加密反馈模式 Cipher Feedback Mode(CFB)。面向字符的应用程序的加密要使用流加密法,可以使用加密反馈模式。在此模式下, 数据用更小的单元加密,如可以是8 位,这个长度小于定义的块长(通常是64 位)。
1、命令行操作
使用des-ede3-cfb对hello.txt加密,密钥为8cc72b05705d5c46f412af8cbed55aad8cc72b05705d5c46,初始化向量为667b02a85c61c786,密文为hello.en。
代码语言:javascript复制openssl enc -e -des-ede3-cfb -in hello.txt -out hello.en -K 8cc72b05705d5c46f412af8cbed55aad8cc72b05705d5c46 -iv 667b02a85c61c786
使用des-ede3-cfb对hello.en解密,密钥为8cc72b05705d5c46f412af8cbed55aad8cc72b05705d5c46,初始化向量为667b02a85c61c786,解密后的文件为hello.de。
代码语言:javascript复制openssl enc -d -des-ede3-cfb -in hello.en -out hello.de -K 8cc72b05705d5c46f412af8cbed55aad8cc72b05705d5c46 -iv 667b02a85c61c786
2、函数说明
CFB64模式加密/解密:
代码语言:javascript复制void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
long length, DES_key_schedule *ks1,
DES_key_schedule *ks2, DES_key_schedule *ks3,
DES_cblock *ivec, int *num, int enc);
参数名称 | 含义 |
---|---|
in | 输入数据,长度任意 |
out | 输出数据,长度与输入数据相等。 |
length | 输入数据的实际长度。 |
ks1 | 使用DES_set_key_unchecked生成的Key |
ks2 | 使用DES_set_key_unchecked生成的Key |
ks3 | 使用DES_set_key_unchecked生成的Key |
ivec | 可读写的一块内存。长度必须是8字节。 |
enc | DES_ENCRYPT代表加密, DES_DECRYPT代表解密 |
DES_ede3_cfb64_encrypt在加密的过程中会修改ivec的内容,因此ivec参数不能是一个常量,而且不能在传递给加密函数后再立马传递给解密函数,必须重新赋值之后再传递给解密函数。
3、编程实现
(1)特别注意
- CFB模式不需要对输入数据进行填充。
(2)实现CFB64模式加解密
下面,函数已经封装完毕,如下:
代码语言:javascript复制/** * @brief TripleDES::cfb64_encrypt * CFB64模式加解密,支持对任意长度明文进行加解密。 * @param in 输入数据 * @param out 输出结果 * @param key 密钥,长度必须是24字节,否则加密失败 * @param ivec 初始向量,长度必须是8字节 * @param enc true-加密,false-解密 */
void TripleDES::cfb64_encrypt(const QByteArray &in, QByteArray &out, const QByteArray &key, const QByteArray &ivec, bool enc)
{
// 检查密钥合法性(只能是24字节)
Q_ASSERT(key.size() == 24);
Q_ASSERT(ivec.size() == 8); // 初始向量为8字节
// 设置key
DES_key_schedule sch1, sch2, sch3;
setKey(key, sch1, sch2, sch3);
// 进行加解密
int num = 0;
QByteArray ivecTemp = ivec; // 此参数被自动修改,故使用局部变量传递
int encVal = enc ? DES_ENCRYPT : DES_DECRYPT;
out.resize(in.size()); // 调整输出buf大小
DES_ede3_cfb64_encrypt((const unsigned char *)in.constData(),
(unsigned char *)out.data(),
in.size(), &sch1, &sch2, &sch3,
(DES_cblock *)ivecTemp.data(), &num, encVal);
}
加解密过程:
- 生成key
- 执行加解密
经测试,本函数支持对任意长度输入数据进行加解密。
(3)测试代码
代码语言:javascript复制void createTestData(QByteArray& data, int size)
{
data.resize(size);
for (int i = 0; i < size; i )
{
data[i] = i % 128;
}
}
void testTripleDES(const QByteArray& data)
{
QByteArray plainText = data;
QByteArray encryptText;
QByteArray decryptText;
QByteArray key = QByteArray::fromHex("8cc72b05705d5c46f412af8cbed55aad8cc72b05705d5c46");
QByteArray ivec = QByteArray::fromHex("667b02a85c61c786");
// TripleDES cfb64模式加密验证
TripleDES tripleDES;
tripleDES.cfb64_encrypt(plainText, encryptText, key, ivec, true); // 加密
tripleDES.cfb64_encrypt(encryptText, decryptText, key, ivec, false); // 解密
qDebug() << "TripleDES cfb64 encrypt verify" << ((decryptText == plainText) ? "succeeded" : "failed");
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 产生1MB 3B的测试数据,为了使该测试数据长度,不为8或16的整数倍
QByteArray data;
createTestData(data, 1*1024*1024 3);
// 测试TripleDES
testTripleDES(data);
return a.exec();
}
执行结果:
本文涉及工程代码地址:https://gitee.com/bailiyang/cdemo/tree/master/Qt/49OpenSSL/OpenSSL
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/126942.html原文链接:https://javaforall.cn