非对称加密、解密原理及openssl中的RSA示例代码
一、【原理简介】非对称加密
非对称加密,也被称为公钥加密,其中使用一对相关的密钥:一个公钥和一个私钥。公钥用于加密数据,私钥用于解密数据。公钥可以公开分享,而私钥必须保密。
-
密钥生成:
- 当一个用户或设备希望使用非对称加密时,要生成一对密钥:一个公钥和一个私钥。这两个密钥是数学上相关的,但从公钥中计算出私钥在计算上是不可行的。
-
加密过程:
- 发送方使用接收方的公钥对消息进行加密。只有持有与那个公钥相对应的私钥的人(在这种情况下是接收方)才能解密这个消息。
-
解密过程:
- 接收方使用其私钥对接收到的加密消息进行解密,以恢复原始消息。
-
安全性:
- 即使攻击者知道公钥并且他们拦截了加密的消息,但由于他们没有私钥,所以他们不能解密那个消息。这提供了保密性。
- 由于私钥不是公开的,因此无法用它来伪造加密的消息。
-
数字签名:
- 除了保密性外,非对称加密还可以用于数字签名。发送方使用其私钥对消息的哈希进行加密,产生一个数字签名。
- 接收方可以使用发送方的公钥来验证签名,确保消息是从发送方发出的,并且没有被修改。
-
主要算法:
- RSA、ElGamal、ECC(椭圆曲线加密)是非对称加密的主要算法。
-
性能问题:
- 与对称加密相比,非对称加密通常计算上更加昂贵,所以它在处理大量数据时可能不太实用。在实际场景中,经常使用非对称加密来交换一个对称密钥(如AES密钥),然后使用对称加密来加密实际的数据。
-
公钥基础设施(PKI):
- PKI是一个结合硬件、软件、策略和标准,以实现公钥加密和数字签名服务的体系结构。它包括证书颁发机构(CA),负责颁发和验证数字证书。
总结:非对称加密使用一对密钥来确保数据的安全性和完整性。公钥用于加密,而私钥用于解密或签名。
二、【代码】生成秘钥对文件 和 读取秘钥对加密、加密
- example 1 生成秘钥对
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>/* compile : gcc createRSA_KeyPair.c -I./include -L./lib -lcrypto -Wl,-rpath=./lib */
int main() {int ret = 0;RSA *r = NULL;BIGNUM *bne = NULL;int bits = 2048;unsigned long e = RSA_F4;// 1. 生成 RSA 密钥对bne = BN_new();ret = BN_set_word(bne, e);if(ret != 1) {goto free_all;}r = RSA_new();ret = RSA_generate_key_ex(r, bits, bne, NULL);if(ret != 1) {goto free_all;}// 2. 保存私钥到 PEM 文件FILE *fp = fopen("private_key.pem", "wb");if(fp == NULL) {perror("Unable to open private key file for writing");goto free_all;}PEM_write_RSAPrivateKey(fp, r, NULL, NULL, 0, NULL, NULL);fclose(fp);// 3. 保存公钥到 PEM 文件fp = fopen("public_key.pem", "wb");if(fp == NULL) {perror("Unable to open public key file for writing");goto free_all;}PEM_write_RSA_PUBKEY(fp, r);fclose(fp);free_all:RSA_free(r);BN_free(bne);return 0;
}
- example 2 使用秘钥对加密、解密
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>/* compile : gcc keyFromFile.c -I./include -L./lib -lcrypto -Wl,-rpath=./lib */
int main() {// 加载公钥FILE* pubKeyFile = fopen("public_key.pem", "rb");RSA* rsaPublicKey = PEM_read_RSA_PUBKEY(pubKeyFile, NULL, NULL, NULL);fclose(pubKeyFile);// 加载私钥FILE* privKeyFile = fopen("private_key.pem", "rb");RSA* rsaPrivateKey = PEM_read_RSAPrivateKey(privKeyFile, NULL, NULL, NULL);fclose(privKeyFile);const char* plainText = "Hello, OpenSSL!";char encrypted[4098] = {};char decrypted[4098] = {};// 使用公钥加密int encryptedLength = RSA_public_encrypt(strlen(plainText), (unsigned char*)plainText,(unsigned char*)encrypted, rsaPublicKey, RSA_PKCS1_OAEP_PADDING);if (encryptedLength == -1) {printf("Public Encrypt failed \n");return 0;}// 使用私钥解密int decryptedLength = RSA_private_decrypt(encryptedLength, (unsigned char*)encrypted,(unsigned char*)decrypted, rsaPrivateKey, RSA_PKCS1_OAEP_PADDING);if (decryptedLength == -1) {printf("Private Decrypt failed \n");return 0;}decrypted[decryptedLength] = '\0';printf("Original: %s\n", plainText);printf("Decrypted: %s\n", decrypted);RSA_free(rsaPublicKey);RSA_free(rsaPrivateKey);return 0;
}
三、【代码】代码内生成秘钥对并加密解密
- c风格
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>/* compile : gcc RSA.c -I./include -L./lib -lcrypto -Wl,-rpath=./lib */
int main() {// 1. create keyint ret = 0;RSA *rsa = NULL;BIGNUM *bne = NULL;int bits = 2048;unsigned long e = RSA_F4;bne = BN_new();ret = BN_set_word(bne, e);if(ret != 1) {goto free_all;}rsa = RSA_new();ret = RSA_generate_key_ex(rsa, bits, bne, NULL);if(ret != 1) {goto free_all;}// 2. encryptoconst char* plainText = "Hello, OpenSSL!";char encrypted[4098] = {};int encryptedLength = RSA_public_encrypt(strlen(plainText) + 1, (unsigned char*)plainText,(unsigned char*)encrypted, rsa, RSA_PKCS1_OAEP_PADDING);if(encryptedLength == -1) {printf("Public Encrypt failed \n");goto free_all;}// 3. decryptochar decrypted[4098] = {};int decryptedLength = RSA_private_decrypt(encryptedLength, (unsigned char*)encrypted,(unsigned char*)decrypted, rsa, RSA_PKCS1_OAEP_PADDING);if(decryptedLength == -1) {printf("Private Decrypt failed \n");goto free_all;}decrypted[decryptedLength] = '\0';printf("Original: %s\n", plainText);printf("Decrypted: %s\n", decrypted);free_all:RSA_free(rsa);BN_free(bne);return 0;
}
- C++风格
#include <iostream>
#include <vector>
#include <stdexcept>extern "C"{
#include <openssl/pem.h>
#include <openssl/rsa.h>
}class RSAWrapper {
public:RSAWrapper() {rsa = RSA_new();bne = BN_new();BN_set_word(bne, RSA_F4);RSA_generate_key_ex(rsa, 2048, bne, nullptr);}~RSAWrapper() {RSA_free(rsa);BN_free(bne);}std::vector<unsigned char> encrypt(const std::string &plainText) {std::vector<unsigned char> encrypted(RSA_size(rsa));int encryptLength = RSA_public_encrypt(plainText.size(),reinterpret_cast<const unsigned char*>(plainText.c_str()),encrypted.data(),rsa,RSA_PKCS1_OAEP_PADDING);if (encryptLength == -1) {throw std::runtime_error("Error during encryption");}return encrypted;}std::string decrypt(const std::vector<unsigned char> &cipherText) {std::vector<unsigned char> decrypted(RSA_size(rsa));int decryptLength = RSA_private_decrypt(cipherText.size(),cipherText.data(),decrypted.data(),rsa,RSA_PKCS1_OAEP_PADDING);if (decryptLength == -1) {throw std::runtime_error("Error during decryption");}return std::string(reinterpret_cast<char*>(decrypted.data()));}private:RSA *rsa;BIGNUM *bne;
};/* compile : g++ -std=c++11 RSA.cpp -I./include -L./lib -lcrypto -Wl,-rpath=./lib */
int main() {try {RSAWrapper rsaWrapper;std::string plainText = "Hello, OpenSSL C++!";auto encrypted = rsaWrapper.encrypt(plainText);auto decrypted = rsaWrapper.decrypt(encrypted);std::cout << "Original Text: " << plainText << std::endl;std::cout << "Decrypted Text: " << decrypted << std::endl;} catch (const std::exception &e) {std::cerr << "Error: " << e.what() << std::endl;}return 0;
}
相关文章:
非对称加密、解密原理及openssl中的RSA示例代码
一、【原理简介】非对称加密 非对称加密,也被称为公钥加密,其中使用一对相关的密钥:一个公钥和一个私钥。公钥用于加密数据,私钥用于解密数据。公钥可以公开分享,而私钥必须保密。 密钥生成: 当一个用户或设备希望使用…...
基于springboot漫画管理系统springboot001
摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&…...
【探索C++】string类详解
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
python 第一次作业
1.使用turtle换一个五环 2.设计这样一个程序:输入一个数字 判断它是不是一个质数 使用turtle换一个五环: >>> import turtle #导入模块 >>> turtle.width(10) #设置圆圈宽度 >>> turtle.color("blue&qu…...
个人博客网站一揽子:Docker建站(Nginx、Wordpress、MySql)
前言 既然安装了Docker,那就不妨建立一个自己的博客网站。实现内外网隔离网站部署,更安全。 1.创建Docker子网络 首先创建一个Docker虚拟子网: sudo docker network create wpnt检查是否建立成功: sudo docker network ls最后…...
Unity 课时 4 : No.4 模拟面试题
课时 4 : No.4 模拟面试题 C# 1. 请说明字符串中 string str null string str “” string str string.Empty 三者的区别 第一个未作初始化没有值, 第二个为空字符串, 答案: str null 在堆中没有分配内存地址 str "" 和 string.Empty 一样都是…...
Golang 基础面试题 01
Golang 面试题合集.png 背景 在之前的文章中分享了 k8s 相关的面试题,本文我们重点来讨论和 k8s 密切相关的 Go 语言面试题。 这几年随着云原生的兴起,大部分后端开发者,特别是 Java 开发者都或多或少的想学习一些 Go 相关的技能,…...
007-第一代软件需求整理
第一代软件需求整理 文章目录 第一代软件需求整理项目介绍需求来源需求来源1:竞品软件分析需求来源2:医生(市场)需求来源3:项目组内部需求来源4:软件组内部需求来源5:软件开发成员需求来源6&…...
XMLHttpRequest介绍
目录 一、介绍1.创建 XMLHttpRequest2.初始化3.发送请求4.获取响应5.响应类型 二、发送GET请求示例三、发送POST请求示例四、发送POST请求下载文件示例五、发送POST请求上传文件示例 一、介绍 1.创建 XMLHttpRequest let xhr new XMLHttpRequest();2.初始化 xhr.open(metho…...
阿里云无影云电脑和传统PC有什么区别?
阿里云无影云电脑和传统电脑PC有什么区别?区别大了,无影云电脑是云端的桌面服务,传统PC是本地的硬件计算机,无影云电脑的数据是保存在云端,本地传统PC的数据是保存在本地客户端,阿里云百科分享阿里云无影云…...
基于matlab实现的船舶横摇运动仿真程序
完整程序: clc clear syms w we; w0.4:0.05:1.6;mu90;v6;%kb1;kt1;%航速6m/s,航向90度,即横浪,cos(90)0 T3;B10;Sw0.785;%船宽10米,吃水3米,水线面系数假设为0.785 weww.^2.*v/9.8; for i1:24 delta_we(i)we(i1)-…...
Java手写二叉索引树和二叉索引树应用拓展案例
Java手写二叉索引树和二叉索引树应用拓展案例 1. 算法思维导图 以下为二叉索引树的实现原理的思维导图,使用Mermanid代码表示: #mermaid-svg-raMRIu7t3H33MKh1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#…...
大数据知识点之大数据5V特征
大数据的特征可以浓缩为五个英文单词,Volume(大量)、Variety(多样性)、Velocity(速度)、Value(价值)、Veracity(准确性)。因为是5个特征都是以“V”开头的英文单词,又叫大数据5V特征。 概述&…...
Java的Socket通信的断网重连的正确写法
Java的Socket通信的断网重连的正确写法 Socket通信的断网重连介绍客户端与服务端源码演示截图本地演示服务器演示演示截图 总结 Socket通信的断网重连介绍 针对于已经建立通信的客户端与服务器,当客户端与服务器因为网络问题导致网络不通而断开连接了或者由于服务器…...
Rocketmq--消息发送和接收演示
使用Java代码来演示消息的发送和接收 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.0.2</version> </dependency> 1 发送消息 消息发送步骤: 创建…...
ArcGIS Pro将SHP文件转CAD并保留图层名称
相信大家应该都使用过ArcGIS将SHP文件转CAD格式,转换过后所有的要素都在一个图层内,那么有没有办法将SHP文件某个字段的值作为CAD的图层名字呢,答案是肯定的,这里就为大家介绍一下ArcGIS Pro转CAD文件并且保留图层名称的方法&…...
GEE:使用for循环合成时间序列影像
作者:CSDN @ _养乐多_ 在本博客中,我们将介绍如何使用Google Earth Engine创建一个时间序列图像集合,以便进行时间序列分析或生成动态图像。 文章目录 一、核心代码二、代码解释三、示例代码链接一、核心代码 // 创建一个空的 image 图像集合 var imagelist = ee.List([])…...
flink1.13.2版本的对应的hive的Hcatalog的使用记录
依赖版本要求<hive.version>3.1.2</hive.version><flink.version>1.13.2</flink.version><hadoop.version>3.3.2</hadoop.version><scala.binary.version...
STM32 ADC介绍和应用
目录 1.ADC是什么? 2.ADC的性能指标 3.ADC特性 4.ADC通道 5.ADC转换顺序 6.ADC触发方式 7.ADC转化时间 8.ADC转化模式 扫描模式 单次转换/连续转换 9.ADC实验 使用ADC读取烟雾传感器的值 代码实现思路: 1.ADC是什么? 全称&#…...
vue项目打包_以生产环境prod模式打包_vue-cli-service 不是内部或外部命令,也不是可运行的程序---vue工作笔记0025
打开命令行: 首先执行npm install 不执行会报错: npm run build:prod --scripts-prepend-node-pathauto 然后再这样执行就是以生产环境模式打包了....
软件需求捕获:从Therac-25悲剧到安全关键系统开发的脊柱工程
1. 项目概述:从Therac-25悲剧到现代软件安全基石上世纪90年代中期,一系列由Therac-25放射治疗机引发的致命事故,最终催生了一场由华盛顿大学Nancy Leveson教授主导的正式调查。这场调查的结论,远不止于揪出一款医疗设备的软件缺陷…...
告别电网波动干扰:手把手教你用双同步坐标系锁相环搞定不平衡电压
告别电网波动干扰:手把手教你用双同步坐标系锁相环搞定不平衡电压 当光伏逆变器在阴天突然遭遇电网电压跌落,或是风电变流器面对负载突变导致的相位抖动时,工程师的控制台前总会亮起刺眼的警报灯。这种三相电压不平衡的工况,就像在…...
别再只会addItem了!QT QComboBox的5个高级用法与实战场景(含完整代码)
别再只会addItem了!QT QComboBox的5个高级用法与实战场景(含完整代码) 在QT开发中,QComboBox可能是最容易被低估的控件之一。很多开发者仅仅把它当作一个简单的下拉选择框,用addItem()填充几个静态选项就草草了事。但实…...
为OpenClaw智能体工作流配置Taotoken作为统一的模型调用后端
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为OpenClaw智能体工作流配置Taotoken作为统一的模型调用后端 对于使用OpenClaw框架构建AI智能体的开发者而言,一个稳定…...
开源语言模型项目实践:从Transformer核心到训练调优全解析
1. 项目概述:一个开源语言模型的实践与探索最近在GitHub上看到一个名为“angeluriot/Language_model”的项目,点进去一看,是个挺有意思的语言模型实现。虽然项目标题很简单,但内容却涵盖了从数据处理、模型构建到训练推理的完整链…...
3分钟快速上手:91160-cli医疗预约自动化助手完整指南
3分钟快速上手:91160-cli医疗预约自动化助手完整指南 【免费下载链接】91160-cli 健康160全自动挂号脚本,捡漏神器 项目地址: https://gitcode.com/gh_mirrors/91/91160-cli 还在为医院挂号难而烦恼吗?91160-cli是一款专为医疗预约设计…...
Java十道高频面试题(一)
Java基础与集合1. HashMap的底层数据结构是什么?(JDK 1.7 vs 1.8)考察点:数据结构演进、哈希冲突解决、扩容死循环问题。参考答案:HashMap在JDK 1.7和1.8中有着本质的区别,主要体现在底层结构和扩容机制上&…...
Memor:为LLM对话构建结构化记忆引擎,实现可重现、可移植的AI交互管理
1. 项目概述:Memor,为LLM对话赋予结构化记忆如果你和我一样,长期和各类大语言模型打交道,从早期的GPT-3到现在的Claude、Gemini,一个绕不开的痛点就是:对话历史的管理。默认的聊天界面里,历史记…...
高效自动化安装:Windows平台ADB与Fastboot驱动完整配置指南
高效自动化安装:Windows平台ADB与Fastboot驱动完整配置指南 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirrors/…...
别再复制粘贴了!手把手教你用MATLAB/Simulink把低通滤波器写成C代码(附差分方程推导避坑点)
从MATLAB到嵌入式C:工业级低通滤波器实现全解析 在电机控制、信号处理等嵌入式应用中,低通滤波器的实现质量直接影响系统性能。许多工程师习惯直接复制现成代码,却常遭遇数值不稳定、相位失真或计算效率低下等问题。本文将彻底拆解从S域传递函…...
