openssl对称加密代码讲解实战
文章目录
- 一、openssl对称加密和非对称加密算法对比
 - 1. 加密原理
 - 2. 常用算法
 - 3. 加密速度
 - 4. 安全性
 - 5. 应用场景
 - 6. 优缺点对比
 - 综合分析
 
- 二、代码实战
 - 代码说明:
 - 运行输出示例
 - 代码说明:
 - 注意事项
 
一、openssl对称加密和非对称加密算法对比
OpenSSL 是一个广泛使用的加密库,提供了丰富的对称加密和非对称加密算法。这两类加密方式各有不同的特点和适用场景。以下是两者的对比:
1. 加密原理
-  
对称加密:
- 使用相同的密钥进行加密和解密。
 - 密钥在加密和解密双方之间共享,因此需要一个安全的密钥传输方式。
 - 加密速度较快,适合加密大量数据。
 
 -  
非对称加密:
- 使用一对密钥:公钥和私钥。公钥用于加密,私钥用于解密。
 - 公钥可以公开,私钥则需要保护,只有拥有私钥的人才能解密公钥加密的数据。
 - 适合小数据量加密和签名,但处理大数据效率较低。
 
 
2. 常用算法
-  
对称加密算法(在 OpenSSL 中支持的常见算法):
- AES(高级加密标准):流行且安全的对称加密算法,支持 128、192 和 256 位密钥长度。
 - SM4:主要用于中国的商用密码标准,采用 128 位密钥。
 - DES 和 3DES(数据加密标准及三重数据加密标准):早期的加密算法,但已不再安全,较少使用。
 
 -  
非对称加密算法(在 OpenSSL 中支持的常见算法):
- RSA:广泛使用的非对称算法,密钥长度通常为 2048 或 4096 位。
 - ECC(椭圆曲线加密):基于椭圆曲线的加密,密钥较短但安全性高,用于资源受限的环境。
 - DSA(数字签名算法):主要用于签名,常见于数字证书。
 
 
3. 加密速度
-  
对称加密:
- 对称加密算法如 AES 在处理速度上显著优于非对称加密,非常适合大文件或大量数据的加密。
 - 常用于文件加密、数据存储、网络数据传输加密等场景。
 
 -  
非对称加密:
- 非对称加密算法处理速度慢,因为其运算更为复杂,适合小数据量的加密,如数字签名和密钥交换。
 - 在实际应用中,通常将其与对称加密结合使用,通过非对称加密传输对称密钥来实现安全的密钥交换,后续的数据传输则使用对称加密。
 
 
4. 安全性
-  
对称加密:
- 安全性依赖于密钥长度和算法设计;例如,AES-256 被认为是非常安全的对称加密算法。
 - 密钥必须在传输中保持安全,一旦密钥泄露,数据的机密性将受到威胁。
 
 -  
非对称加密:
- 安全性依赖于密钥长度和密钥保护。比如 RSA-2048 被认为是安全的,而 ECC 则以较短密钥提供更高安全性。
 - 私钥的安全性至关重要,如果私钥泄露,任何持有公钥的人都可以解密数据。
 
 
5. 应用场景
-  
对称加密的应用场景:
- 用于 HTTPS 中的数据加密(结合非对称加密交换密钥后)。
 - 云存储、数据库等大文件的加密保护。
 - VPN、WiFi 等网络传输中对数据的加密。
 
 -  
非对称加密的应用场景:
- 数字签名,用于认证数据的来源和完整性。
 - SSL/TLS 协议中,用于加密对称加密密钥并验证通信双方身份。
 - 数据加密用于保护敏感信息的小文件,例如加密密码、密钥或数字证书。
 
 
6. 优缺点对比
| 对比项目 | 对称加密 | 非对称加密 | 
|---|---|---|
| 密钥数量 | 1 个密钥,共享密钥 | 1 对密钥(公钥和私钥) | 
| 加密速度 | 快,适合大数据 | 慢,适合小数据 | 
| 安全性 | 密钥泄露会导致数据泄密 | 公钥泄露不会影响数据的私密性 | 
| 密钥分配 | 需要安全的密钥传输 | 私钥无需传输,安全性更高 | 
| 典型应用 | 大数据文件的加密、VPN、存储加密 | SSL/TLS、数字签名、密钥交换 | 
综合分析
OpenSSL 中通常结合对称加密和非对称加密,以实现性能与安全性兼备的加密方案。例如,在 SSL/TLS 协议中,服务器会先使用非对称加密交换密钥,然后使用对称加密传输数据。
二、代码实战
下面是使用 OpenSSL 实现对称加密的示例代码,采用 AES-256-CBC 算法对数据进行加密。此代码会生成一个随机的初始向量(IV),并且使用固定的密钥对数据加密。
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>#define AES_KEY_LENGTH 32  // AES-256, so 256 bits = 32 bytes
#define AES_BLOCK_SIZE 16void handleErrors() {ERR_print_errors_fp(stderr);abort();
}// 对称加密函数
int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,unsigned char *iv, unsigned char *ciphertext) {EVP_CIPHER_CTX *ctx;int len;int ciphertext_len;// 创建并初始化上下文if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();// 初始化加密操作,指定 AES-256-CBC 算法if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handleErrors();// 加密数据if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))handleErrors();ciphertext_len = len;// 完成加密if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();ciphertext_len += len;// 释放上下文EVP_CIPHER_CTX_free(ctx);return ciphertext_len;
}int main() {// 32 字节的密钥 (256 位)unsigned char key[AES_KEY_LENGTH] = "0123456789abcdef0123456789abcdef";// 生成 16 字节的初始向量 (128 位)unsigned char iv[AES_BLOCK_SIZE];if (!RAND_bytes(iv, AES_BLOCK_SIZE)) {fprintf(stderr, "随机生成初始向量失败\n");return 1;}unsigned char plaintext[] = "This is the data to encrypt";  // 要加密的数据unsigned char ciphertext[128];  // 存储密文的缓冲区// 执行加密操作int ciphertext_len = aes_encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext);// 打印初始向量printf("Initial Vector (IV): ");for (int i = 0; i < AES_BLOCK_SIZE; i++) {printf("%02x ", iv[i]);}printf("\n");// 打印加密后的数据(密文)printf("Ciphertext (hex): ");for (int i = 0; i < ciphertext_len; i++) {printf("%02x ", ciphertext[i]);}printf("\n");return 0;
}
 
代码说明:
- 初始化加密上下文:使用 
EVP_CIPHER_CTX_new()创建加密上下文。 - 设置加密算法和密钥:通过 
EVP_EncryptInit_ex()指定 AES-256-CBC 算法。 - 加密数据:
EVP_EncryptUpdate()用于加密数据块。 - 完成加密:
EVP_EncryptFinal_ex()处理最后的数据块。 - 生成随机初始向量(IV):
RAND_bytes()生成随机 IV,确保加密的安全性。 
运行输出示例
Initial Vector (IV): 1a 2b 3c 4d ... (随机生成)
Ciphertext (hex): ae f5 67 89 ... (加密后的密文)
 
注意:密钥和初始向量(IV)应安全存储,并且应仅与需要解密的接收方共享。
这是对应解密代码,解密前需要与加密代码相同的密钥和初始向量(IV),用相同的算法参数对密文进行解密:
#include <openssl/evp.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>#define AES_KEY_LENGTH 32  // 256 位密钥
#define AES_BLOCK_SIZE 16  // AES 块大小 128 位(16 字节)void handleErrors() {ERR_print_errors_fp(stderr);abort();
}// 对称解密函数
int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,unsigned char *iv, unsigned char *plaintext) {EVP_CIPHER_CTX *ctx;int len;int plaintext_len;// 创建并初始化上下文if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();// 初始化解密操作,使用 AES-256-CBC 算法if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) handleErrors();// 提供待解密的数据if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))handleErrors();plaintext_len = len;// 完成解密操作if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();plaintext_len += len;// 清理上下文EVP_CIPHER_CTX_free(ctx);return plaintext_len;
}int main() {// 密钥和 IV 与加密时保持一致unsigned char key[AES_KEY_LENGTH] = "0123456789abcdef0123456789abcdef";unsigned char iv[AES_BLOCK_SIZE] = {0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x7a, 0x8b,0x9c, 0xad, 0xbe, 0xcf, 0xde, 0xef, 0xfa, 0x1b};unsigned char ciphertext[] = {0xae, 0xf5, 0x67, 0x89, /* ... 加密数据的字节数组 */};unsigned char decryptedtext[128];  // 缓冲区用于存储解密后的明文// 执行解密操作int decryptedtext_len = aes_decrypt(ciphertext, sizeof(ciphertext), key, iv, decryptedtext);// 添加字符串终止符decryptedtext[decryptedtext_len] = '\0';// 输出解密后的明文printf("Decrypted text: %s\n", decryptedtext);return 0;
}
 
代码说明:
- 初始化解密上下文:使用 
EVP_CIPHER_CTX_new()创建解密上下文。 - 设置解密算法和密钥:通过 
EVP_DecryptInit_ex()指定 AES-256-CBC 算法。 - 解密数据:
EVP_DecryptUpdate()用于处理密文的主要部分。 - 完成解密:
EVP_DecryptFinal_ex()处理最后的数据块,并将明文长度加到总长度中。 - 输出解密结果:解密后的数据存储在 
decryptedtext中,作为原始的明文数据输出。 
注意事项
- 密钥和初始向量(IV)必须与加密时一致。
 - 输出的解密文本会和加密前的原始文本一致。
 
相关文章:
openssl对称加密代码讲解实战
文章目录 一、openssl对称加密和非对称加密算法对比1. 加密原理2. 常用算法3. 加密速度4. 安全性5. 应用场景6. 优缺点对比综合分析 二、代码实战代码说明:运行输出示例代码说明:注意事项 一、openssl对称加密和非对称加密算法对比 OpenSSL 是一个广泛使…...
web前端动画按钮(附源代码)
效果图 源代码 HTML部分 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> …...
go函数传值是值传递?还是引用传递?slice案例加图解
先说下结论 Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。 值语义类型:参数传递的时候,就是值拷贝,这样就在函数中就无法修改原内容数据。 基本类型:byte、int、bool…...
PostgreSQL数据库笔记
PostgreSQL 是什么 PostgreSQL(简称Postgres或PG)是一个功能强大、可靠性高、可扩展性好的开源对象-关系数据库服务器(ORDBMS),它以加州大学伯克利分校计算机系开发的POSTGRES版本4.2为基础。 发展历程 起源与发展&a…...
财务软件源码SaaS云财务
在如今的商业环境中,准确的财务管理是一家企业取得成功的关键。然而,传统的财务管理方法已经无法满足现代企业的需求,需要一个全新的解决方案。推出了全新的财务软件为您提供完美的解决方案。 选择财务软件源码,您将享受到以下优…...
Elasticsearch集群和Kibana部署流程
搭建Elasticsearch集群 1. 进入Elasticsearch官网下载页面,下载Elasticsearch 在如下页面选择Elasticsearch版本,点击download按钮,进入下载页面 右键选择自己操作系统对应的版本,复制下载链接 然后通过wget命令下载Elastics…...
丹摩征文活动 | 丹摩智算:大数据治理的智慧引擎与实践探索
丹摩DAMODEL|让AI开发更简单!算力租赁上丹摩! 目录 一、引言 二、大数据治理的挑战与重要性 (一)数据质量问题 (二)数据安全威胁 (三)数据管理复杂性 三、丹摩智算…...
【Django】Clickjacking点击劫持攻击实现和防御措施
Clickjacking点击劫持 1、clickjacking攻击2、clickjacking攻击场景 1、clickjacking攻击 clickjacking攻击又称为点击劫持攻击,是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段。 2、clickj…...
Ansys Zemax | 手机镜头设计 - 第 4 部分:用LS-DYNA进行冲击性能分析
该系列文章将讨论智能手机镜头模组设计的挑战,从概念和设计到制造和结构变形分析。本文是四部分系列中的第四部分,它涵盖了相机镜头的显式动态模拟,以及对光学性能的影响。使用Ansys Mechanical和LS-DYNA对相机在地板上的一系列冲击和弹跳过程…...
工具收集 - java-decompiler / jd-gui
工具收集 - java-decompiler / jd-gui 参考资料 用法:拖进来就行了 参考资料 https://github.com/java-decompiler/jd-gui 脚本之家:java反编译工具jd-gui使用详解...
《无线重构世界》射频模组演进
射频前端四大金刚 射频前端由PA、LNA、滤波器、开关“四大金刚” 不同的模块有自己的工艺和性能特点 分层设计 射频前端虽然只由PA、LNA、开关、混频器4个模块构成,但不同模块之间相互连接且相互影响。如果将射频系统当成一个整体来理解,其中的细节和…...
渗透测试---docker容器
声明:学习素材来自b站up【泷羽Sec】,侵删,若阅读过程中有相关方面的不足,还请指正,本文只做相关技术分享,切莫从事违法等相关行为,本人一律不承担一切后果 目录 一、Docker的作用与优势 二、docker的核心…...
【go从零单排】Atomic Counters原子计数
🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 语言中,原子计数器(Atomic Counters)是…...
VSCode中python插件安装后无法调试
问题 VSCode中python插件安装后无法调试,如下,点击调试,VScode中不报错,也没有调试 解决方法 1、查看配置 打开所在路径 2、拷贝 将整个文件夹拷贝到vscode默认路径下 3、问题解决 再次调试,可以正常使用了…...
用react实现radio同时关联proform组件
实现: <ProFormRadio.GroupradioType{button}name{[bodyConfig, format]}label"请求体格式"initialValue{json}options{createTabs}fieldProps{{buttonStyle: solid,wrapperMarginInlineEnd: 20,onChange: e > {let v e.target.value;databaseMod…...
Objective-C 1.0和2.0有什么区别?
Objective-C ObjC比较小众,在1980年左右由Stepstone公司的Brad Cox和Tom Love发明。后来NeXT公司获得ObjC语言使用权,再后来到1996年NeXT被苹果公司收购也变成苹果公司使用,Mac市场占有率本身就不高,ObjC没有太多程序员。在移动互…...
TCP连接如何保障数据传输安全
TCP连接保障数据传输安全主要通过以下几个机制实现: 1、建立连接:TCP通过三次握手过程建立连接,确保通信双方实体真实存在,为后续的可靠数据传输打下基础。 2、序号机制:TCP为每个传输的数据包分配一个序号ÿ…...
【论文复现】ChatGPT多模态命名实体识别
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ChatGPT ChatGPT辅助细化知识增强!1. 研究背景2. 模型结构和代码3. 任务流程第一阶段:辅助精炼知识启发式生成第二阶段…...
管理 Elasticsearch 变得更容易了,非常容易!
作者:来自 Elastic Ken Exner Elasticsearch 用户,我们听到了你的心声。管理 Elasticsearch 有时会变得很复杂,面临的挑战包括性能调整、问题检测和资源优化。我们一直致力于简化你的体验。今天,我们宣布了自收购 Opster 以来的一…...
SynchronousQueueworkQueue.offer() 和 poll() 方法的超时控制及线程池的讨论
2024.11.12 11:26 问:workQueue.offer(command) 这里 workQueue.poll(keepAlive, TimeUnit.NANOSECONDS) : 这里的 workQueue.offer(command) 没有超时时间控制? Claude 3.5 Haiku 非常好的问题!我来详细解释 offer() 和 poll() 方法的区别…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...
