首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

实战篇-OpenSSL之AES加密算法-OFB128模式

  • 23-09-19 13:42
  • 2458
  • 8268
blog.csdn.net

本文属于《OpenSSL加密算法库使用系列教程》之一,欢迎查看其它文章。

实战篇-OpenSSL之AES加密算法-OFB128模式

  • 一、AES简介
  • 二、OFB128模式
    • 1、命令行操作
    • 2、函数说明
    • 3、编程实现
      • (1)特别注意
      • (2)实现OFB128模式加解密
      • (3)测试代码

一、AES简介

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS
PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES属于对称加密算法,加解密使用同一个秘钥。

对称加密算法,一般有至少4种模式,即ECB、CBC、CFB、OFB等。

具体的加密原理,就不进行介绍了,本文主要从使用角度,进行说明。

以下命令行和编程实现,均基于OpenSSL开源库。在命令行中,我们可以使用命令实现对文件加解密,以验证我们的编程实现,是否正确。

二、OFB128模式

输出反馈模式 Output Feedback Mode(OFB)。输出反馈模式与CFB 相似,惟一差别是,CFB 中密文填入加密过程下一阶段,而 在OFB 中,初始化向量加密过程的输入填入加密过程下一阶段。

1、命令行操作

使用aes-128-ofb对hello.txt加密,128位密钥为8cc72b05705d5c46f412af8cbed55aad,初始化向量为667b02a85c61c786def4521b060265e8,密文为hello.en。

openssl enc -e -aes-128-ofb -in hello.txt -out hello.en -K 8cc72b05705d5c46f412af8cbed55aad -iv 667b02a85c61c786def4521b060265e8
  • 1

使用aes-128-ofb对hello.en解密,128位密钥为8cc72b05705d5c46f412af8cbed55aad,初始化向量为667b02a85c61c786def4521b060265e8,解密后的文件为hello.de。

openssl enc -d -aes-128-ofb -in hello.en -out hello.de -K 8cc72b05705d5c46f412af8cbed55aad -iv 667b02a85c61c786def4521b060265e8
  • 1

2、函数说明

AES OFB128加密/解密:

void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        unsigned char *ivec, int *num);
  • 1
  • 2
  • 3
参数名称含义
in输入数据,长度任意
out输出数据,长度与输入数据相等
length输入数据的长度,字节数
key使用AES_set_encrypt_key生成的Key
ivec可读写的一块内存。长度必须是16字节。
num应总是为0,否则会触发断言

AES_ofb128_encrypt在加密的过程中会修改ivec的内容,因此ivec参数不能是一个常量,而且不能在传递给加密函数后再立马传递给解密函数,必须重新赋值之后再传递给解密函数。

可以看到该函数没有加密和解密标识参数enc,即表明当in为明文时,执行的是加密操作;当in为密文时,执行的是解密操作,相当于是对等的。

3、编程实现

(1)特别注意

  • OFB模式加密和解密均使用加密key,这一点比较反常,务必记住。
  • OFB模式不需要对输入数据进行填充。
  • AES_ofb128_encrypt函数既是加密,又是解密。当in为明文时,执行的是加密操作;当in为密文时,执行的是解密操作,相当于是对等的。

(2)实现OFB128模式加解密

下面,函数已经封装完毕,如下:

/**
 * @brief AES::ofb128_encrypt
 * OFB128模式加解密,支持对任意长度明文进行加解密。
 * @param in 输入数据
 * @param out 输出结果
 * @param key 密钥,长度必须是16/24/32字节,否则加密失败
 * @param ivec 初始向量,长度必须是16字节
 * @param enc true-加密,false-解密
 * @return 执行结果
 */
bool AES::ofb128_encrypt(const QByteArray &in, QByteArray &out, const QByteArray &key, const QByteArray &ivec, bool enc)
{
    // 检查密钥合法性(只能是16、24、32字节)
    Q_ASSERT(key.size() == 16 || key.size() == 24 || key.size() == 32);
    Q_ASSERT(ivec.size() == 16); // 初始向量为16字节

    // 特别注意:OFB模式加密和解密均使用加密key。
    // 生成加密key
    AES_KEY aes_key;
    if (AES_set_encrypt_key((const unsigned char*)key.data(), key.size() * 8, &aes_key) != 0)
    {
        return false;
    }

    Q_UNUSED(enc);

    // 特别注意:加密与解密执行相同的操作
    // 执行OFB128模式加密或解密
    int num = 0;
    QByteArray ivecTemp = ivec; // ivec会被修改,故需要临时变量来暂存
    out.resize(in.size()); // 调整输出buf大小
    AES_ofb128_encrypt((const unsigned char*)in.data(),
                    (unsigned char*)out.data(),
                    in.size(),
                    &aes_key,
                    (unsigned char*)ivecTemp.data(),
                    &num);
    return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

加解密过程:

  • 生成加密key
  • 执行加解密

经测试,本函数支持对任意长度输入数据进行加解密。

(3)测试代码

void createTestData(QByteArray& data, int size)
{
    data.resize(size);
    for (int i = 0; i < size; i++)
    {
        data[i] = i % 128;
    }
}

void testAES(const QByteArray& data)
{
    QByteArray plainText = data;
    QByteArray encryptText;
    QByteArray decryptText;

    QByteArray key = QByteArray::fromHex("8cc72b05705d5c46f412af8cbed55aad");
    QByteArray ivec = QByteArray::fromHex("667b02a85c61c786def4521b060265e8");

    // AES ofb128模式加密验证
    AES aes;
    aes.ofb128_encrypt(plainText, encryptText, key, ivec, true);     // 加密
    aes.ofb128_encrypt(encryptText, decryptText, key, ivec, false);  // 解密
    qDebug() << "AES ofb128 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);

    // 测试AES
    testAES(data);     // 测试,直接调用OpenSSL中AES算法函数

    return a.exec();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

执行结果:

在这里插入图片描述

本文涉及工程代码地址:http://iyenn.com/index/link?url=https://gitee.com/bailiyang/cdemo/tree/master/Qt/49OpenSSL/OpenSSL



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

在这里插入图片描述

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览50757 人正在系统学习中
注:本文转载自blog.csdn.net的百里杨的文章"https://blog.csdn.net/zyhse/article/details/112292503"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top