非对称加密、解密原理及openssl中的RSA示例代码

一、【原理简介】非对称加密

非对称加密,也被称为公钥加密,其中使用一对相关的密钥:一个公钥和一个私钥。公钥用于加密数据,私钥用于解密数据。公钥可以公开分享,而私钥必须保密。

  1. 密钥生成:

    • 当一个用户或设备希望使用非对称加密时,它首先会生成一对密钥:一个公钥和一个私钥。这两个密钥是数学上相关的,但从公钥中计算出私钥在计算上是不可行的。
  2. 加密过程:

    • 发送方使用接收方的公钥对消息进行加密。只有持有与那个公钥相对应的私钥的人(在这种情况下是接收方)才能解密这个消息。
  3. 解密过程:

    • 接收方使用其私钥对接收到的加密消息进行解密,以恢复原始消息。
  4. 安全性:

    • 即使攻击者知道公钥并且他们拦截了加密的消息,但由于他们没有私钥,所以他们不能解密那个消息。这提供了保密性。
    • 由于私钥不是公开的,因此无法用它来伪造加密的消息。
  5. 数字签名:

    • 除了保密性外,非对称加密还可以用于数字签名。发送方使用其私钥对消息的哈希进行加密,产生一个数字签名。
    • 接收方可以使用发送方的公钥来验证签名,确保消息是从发送方发出的,并且没有被修改。
  6. 主要算法:

    • RSA、ElGamal、ECC(椭圆曲线加密)是非对称加密的主要算法。
  7. 性能问题:

    • 与对称加密相比,非对称加密通常计算上更加昂贵,所以它在处理大量数据时可能不太实用。在实际场景中,经常使用非对称加密来交换一个对称密钥(如AES密钥),然后使用对称加密来加密实际的数据。
  8. 公钥基础设施(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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/79040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 毕业设计-基于SpringBoot的在线文档管理系统

基于SpringBoot的在线文档管理系统 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 技术栈简介 文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;sp…

MobaXterm工具软件使用介绍

大家好&#xff0c;我是虎哥&#xff0c;最近由于大部分嵌入式的系统都切换到了ubuntu20.04及更高版本的系统&#xff0c;导致我自己使用的Xshell也需要从5升级到7&#xff0c;但是Xshell7尽然开始收费了&#xff0c;网上也没有什么好用的破解版本&#xff0c;索性我就准备找个…

034:vue项目利用qrcodejs2生成二维码示例

第034个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

【C++】常用算术生成算法

0.前言 1.accumulate #include <iostream> using namespace std;// 常用算术生成算法 #include<vector> #include<numeric> //accumulate 的调用头文件void test01() {vector<int>v;for (int i 0; i < 100; i){v.push_back(i);}int total accumu…

Java 复习笔记 - Lambda 表达式 he 经典算法题

文章目录 Lambda表达式 概述&#xff08;一&#xff09;基本作用&#xff08;二&#xff09;特点 一&#xff0c;初识Java中的Lambda 表达式二&#xff0c;函数式编程三&#xff0c;省略写法四&#xff0c;练习&#xff1a;使用Lambda 表达式 简化Comparator接口的匿名形式综合…

TSINGSEE青犀视频AI算法助力构建城市市容·街面秩序管理解决方案

随着城市化进程加快&#xff0c;未经合理规划设置自然形成的马路市场越来越多&#xff0c;这不仅存在交通安全隐患&#xff0c;也造成了市容秩序混乱&#xff0c;严重影响城市市容面貌。 TSINGSEE青犀AI智能分析网关V3内部部署了几十种算法&#xff0c;包括人脸、人体、车辆、…

学习笔记:卸载nav2 navigation2导航

nav2二进制文件安装 nav2导航安装方式分为二进制文件安装和源码方式安装&#xff0c;如果想用最快的方式跑通代码&#xff0c;推荐二进制安装&#xff0c;不用编译&#xff0c;没有缺少依赖编译失败的烦恼&#xff0c; 安装命令&#xff1a; sudo apt install ros-$ROS_DISTR…

iTOP-RK3568开发板Linux 修改kernel logo

本文档配套资料在网盘资料“iTOP-3568 开发板\02_【iTOP-RK3568 开发板】开发资料\10_Linux 系统开发配套资料\05_Linux 修改内核 logo 配套资料”路径下。 5.3.1 准备 logo 系统默认内核 logo&#xff0c;如下图所示&#xff1a; 如 果 想 要 替 换 这 个 logo, 首 先 要 制…

神经网络-pytorch版本

pytorch神经网络基础 torch简介 torch和numpy import torch import numpy as np np_datanp.arange(6).reshape((2,3)) torch_datatorch.from_numpy(np_data) tensor2arraytorch_data.numpy() print(np_data,"\n",torch_data,"\n",tensor2array)torch的数…

2023年已过大半,光通信领域有哪些值得关注的技术趋势?

引言&#xff1a;上个星期&#xff0c;小枣君去深圳参加了CIOE中国光博会&#xff0c;获得了一些光通信领域的最新技术动态进展。今天&#xff0c;我来和大家做一个分享。 这次光博会&#xff0c;整个行业的参与热情很高。据主办方统计&#xff0c;为期三天的展会&#xff0c;现…

Android 11.0 系统system模块开启禁用adb push和adb pull传输文件功能

1.使用场景 在进行11.0的系统定制化开发中,在一些产品中由于一些开发的功能比较重要,防止技术点外泄在出货产品中,禁用 adb pull 和adb push等命令 来获取系统system下的jar 和apk 等文件,所以需要禁用这些命令 2.系统system模块开启禁用adb push和adb pull传输文件功能的…

球谐函数实现环境光照漫反射实践

该文章以及代码主要来自 图形学论文解析与复现&#xff1a;【论文复现】An Efficient Representation for Irradiance Environment Maps 作者&#xff1a;Monica的小甜甜 与原文的不同&#xff1a; 对一些有问题的地方进行了修改添加了注释对有疑问的地方添加了疑问点引入了其…

解决 Elasticsearch 分页查询记录超过10000时异常

查询结果中 hits.total.value 值最大为10000的限制 解决方法: 1、请求设置rest_total_hits_as_inttrue 注意参数需要放在请求头上 builder.addHeader("rest_total_hits_as_int","true"); 2、修改setting的值 #设置返回最大记录条数为1000000 PUT /in…

基于python解决鸡兔同笼问题

一、什么是鸡兔同笼问题&#xff1f; 鸡兔同笼问题是一个经典的数学问题。问题描述&#xff1a;鸡和兔子共有头数a和脚数b&#xff0c;求鸡和兔子的数量。 解析&#xff1a;设鸡的数量为x&#xff0c;兔子的数量为y&#xff0c;那么可以得到以下两个方程&#xff1a; 1. x y…

详解爬虫策略,反爬虫策略,反反爬爬虫策略

爬虫策略 爬取策略是网络爬虫在执行网页抓取任务时所遵循的规则或策略。这些策略决定了爬虫如何从一个页面转到另一个页面&#xff0c;什么时间进行抓取&#xff0c;以及应该抓取哪些内容。以下是几种常见的爬取策略&#xff1a; 深度优先搜索&#xff08;DFS&#xff09; 在…

对抗生成网络总结

对一些基本的对抗生成网络的总结。部分内容整理自Teeyohuang’s blog 文章目录 GAN (NeurIPS, 2014)CGANDCGANStackGANPix2Pix (CVPR, 2017)CycleGAN (ICCV, 2017)SRGAN (CVPR, 2017)StyleGAN (CVPR, 2019) GAN (NeurIPS, 2014) Generative adversarial nets m i n G m a x D …

leetcode top 100 (8)无重复字符的最长子串(滑动窗口

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 package TOP1_10;import java.util.HashMap; import java.…

Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角

Tokenview作为一家领先的多链区块浏览器&#xff0c;为了进一步优化区块链用户的使用体验&#xff0c;我们推出了X-ray&#xff08;余额透视&#xff09;功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程&#xff0c;以一种直观、简洁的方式呈现地址的进出账情况…

LCP 50.宝石补给

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCP 50. 宝石补给 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 模拟操作即可。 解题代码&#xff1a; class Solution {public int giveGem(int[] gem, int[][] operations) {for(int[…

002 Linux 权限

前言 本文将会向您介绍关于linux权限方面的内容&#xff0c;包括文件类型&#xff0c;如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的…