openssl+ RSA + linux 签名校验开发实例(C++)

文章目录

  • 一、RSA签名校验
  • 二、RSA签名校验开发实例

一、RSA签名校验

RSA签名校验是一种用于验证数字签名的过程,它确保签名是由拥有相应私钥的合法实体创建的。以下是RSA签名校验的理论知识点:

  1. RSA密钥对: RSA签名使用一对公钥和私钥。公钥用于验证签名,私钥用于创建签名。

  2. 数字签名过程:

    • 消息哈希: 对要签名的消息进行哈希运算,通常使用SHA-256等哈希算法,以确保消息的唯一性和完整性。
    • 私钥签名: 使用私钥对消息的哈希值进行加密,形成数字签名。
  3. 数字签名校验过程:

    • 消息哈希: 接收到签名后,对原始消息进行相同的哈希运算,得到消息的哈希值。
    • 公钥验证: 使用签名者的公钥对数字签名进行解密,得到解密后的哈希值。
    • 比较哈希值: 将解密后的哈希值与原始消息的哈希值进行比较。如果相同,则签名验证通过,否则失败。
  4. RSA签名验证的数学基础:

    • RSA签名验证的关键是使用签名者的公钥进行解密。只有持有相应私钥的实体才能正确地对消息进行签名。
    • RSA的安全性基于大整数分解问题的难解性。在没有私钥的情况下,从签名中分解出原始哈希值的难度使得其他实体无法伪造合法的签名。
  5. 填充方案: 在实际应用中,为增加安全性,通常使用填充方案对消息进行填充。常见的填充方案包括PKCS#1 v1.5和OAEP。

  6. 常见错误:

    • 签名长度: 确保签名长度与RSA密钥长度相匹配。签名长度超过密钥长度时可能导致验证失败。
    • 密钥匹配: 使用正确的公钥进行验证,确保公钥和私钥匹配。
  7. 安全性注意事项:

    • 使用足够长的RSA密钥长度,通常建议使用2048位或更长的密钥。
    • 定期更新密钥对,以防止安全性降低。

理解以上理论知识有助于正确实现和使用RSA签名,并在应用中确保数据的安全性和完整性。

二、RSA签名校验开发实例

下面是一个简单的示例,演示如何使用OpenSSL库在Linux环境下进行RSA签名和验证。在这个示例中,我们使用PEM格式的密钥对进行签名和验证。

#include <iostream>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>// 用于读取PEM格式的私钥文件
RSA* readPrivateKey(const char* privateKeyFile) {FILE* file = fopen(privateKeyFile, "r");if (!file) {perror("Error opening private key file");return nullptr;}RSA* rsa = PEM_read_RSAPrivateKey(file, nullptr, nullptr, nullptr);fclose(file);if (!rsa) {ERR_print_errors_fp(stderr);}return rsa;
}// 对消息进行RSA签名
bool signMessage(const char* message, RSA* privateKey, unsigned char* signature, unsigned int* signatureLength) {EVP_PKEY* pkey = EVP_PKEY_new();EVP_PKEY_set1_RSA(pkey, privateKey);EVP_MD_CTX* ctx = EVP_MD_CTX_new();if (!ctx) {perror("Error creating context");EVP_PKEY_free(pkey);return false;}if (EVP_DigestSignInit(ctx, nullptr, EVP_sha256(), nullptr, pkey) != 1) {perror("Error initializing sign context");EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return false;}if (EVP_DigestSignUpdate(ctx, message, strlen(message)) != 1) {perror("Error updating sign context");EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return false;}if (EVP_DigestSignFinal(ctx, signature, signatureLength) != 1) {perror("Error finalizing sign context");EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return false;}EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return true;
}// 验证RSA签名
bool verifySignature(const char* message, RSA* publicKey, const unsigned char* signature, unsigned int signatureLength) {EVP_PKEY* pkey = EVP_PKEY_new();EVP_PKEY_set1_RSA(pkey, publicKey);EVP_MD_CTX* ctx = EVP_MD_CTX_new();if (!ctx) {perror("Error creating context");EVP_PKEY_free(pkey);return false;}if (EVP_DigestVerifyInit(ctx, nullptr, EVP_sha256(), nullptr, pkey) != 1) {perror("Error initializing verify context");EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return false;}if (EVP_DigestVerifyUpdate(ctx, message, strlen(message)) != 1) {perror("Error updating verify context");EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return false;}int result = EVP_DigestVerifyFinal(ctx, signature, signatureLength);EVP_MD_CTX_free(ctx);EVP_PKEY_free(pkey);return (result == 1);
}int main() {// 读取私钥const char* privateKeyFile = "private_key.pem";RSA* privateKey = readPrivateKey(privateKeyFile);if (!privateKey) {std::cerr << "Error loading private key" << std::endl;return 1;}// 待签名的消息const char* message = "Hello, RSA!";// 计算签名unsigned char signature[2048];  // 2048是RSA密钥长度unsigned int signatureLength;if (signMessage(message, privateKey, signature, &signatureLength)) {std::cout << "Signature created successfully" << std::endl;} else {std::cerr << "Error creating signature" << std::endl;RSA_free(privateKey);return 1;}// 读取公钥const char* publicKeyFile = "public_key.pem";RSA* publicKey = readPrivateKey(publicKeyFile);if (!publicKey) {std::cerr << "Error loading public key" << std::endl;RSA_free(privateKey);return 1;}// 验证签名if (verifySignature(message, publicKey, signature, signatureLength)) {std::cout << "Signature verified successfully" << std::endl;} else {std::cerr << "Error verifying signature" << std::endl;}// 释放资源RSA_free(privateKey);RSA_free(publicKey);return 0;
}

确保替换 private_key.pempublic_key.pem 为实际的私钥和公钥文件。这个示例中包含了签名和验证两个步骤。签名的结果可以被验证,以确保消息的完整性和真实性。

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

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

相关文章

RPCS3(PlayStation 3游戏模拟器)汉化教程

RPCS3 RPCS3 是一款PlayStation 3 模拟器&#xff0c;可让 Windows、Linux 或 BSD 系统的用户运行索尼 PlayStation 3 游戏。 安装教程 包含 Windows/Linux版本 详细安装汉化教程请查看文章 RPCS3&#xff08;PS3模拟器&#xff09;安装及汉化教程 1.首先下载最新版 RPCS3模…

classifier-free-guidance 扩散模型引导生成

浅谈扩散模型的有分类器引导和无分类器引导 - 知乎这篇文章主要比较一下扩散模型的引导生成的三种做法的区别。它们分别是用显式分类器引导生成的做法&#xff0c;用隐式无分类器引导的做法和用CLIP计算跨模态间的损失来引导生成的做法。 Classifier-Guidance: Diffusion Mode……

浏览器是什么

浏览器是什么 本文简要介绍浏览器的功能和组成。 浏览器&#xff08;Web Browser&#xff09;是一种用于访问和浏览互联网上的网页和资源的软件应用程序。它是用户与互联网交互的主要工具之一。 浏览器通过使用网络协议&#xff08;如HTTP、HTTPS等&#xff09;与远程服务器通…

从0开始学习JavaScript--JavaScript数据类型与数据结构

JavaScript作为一门动态、弱类型的脚本语言&#xff0c;拥有丰富的数据类型和数据结构&#xff0c;这些构建了语言的基础&#xff0c;为开发者提供了灵活性和表达力。本文将深入探讨JavaScript中的各种数据类型&#xff0c;包括基本数据类型和复杂数据类型&#xff0c;并介绍常…

nginx知识梳理及配置详解

软件开发全文档获取&#xff1a;点我获取 nginx安装 #nginx安装 yum -y install gcc pcre-devel openssl-devel #依赖包 useradd -s /sbin/nologin nginx ./configure --prefix/usr/local/nginx #指定安装目录 --usernginx #指定用户 --with-http_ss…

【数据库篇】关系模式的表示——(1)问题的提出

1、关系模式的表示 R&#xff1a;表示关系的名字比如&#xff1a;sc选课表&#xff0c;student学生表。 U&#xff1a;表示一个关系模式的所有属性&#xff0c;比如student表&#xff1a;U&#xff08;sno&#xff0c;sname&#xff0c;sage&#xff0c;ssex&#xff09;。 …

LedControl 库说明文档

LedControl 库最初是为基于 8 位 AVR 处理器的 Arduino 板编写的。但由于该代码不使用处理器的任何复杂的内部功能&#xff0c;因此具有高度可移植性&#xff0c;并且应该在任何支持 和 功能的 Arduino&#xff08;类似&#xff09;板上pinMode()运行digitalWrite() 。 单个 M…

C练习题_3

一、单项选择题&#xff08;本大题共20小题&#xff0c;每小题2分&#xff0c;共40分。在每小题给出的四个备选项中,选出一个正确的答案&#xff0c;并将所选项前的字母填写在答题纸的相应位置上。 以下正确的C语言自定义标识符是() A. la B. 2a C. do D. a.12 2.在C语言中,错…

C# 之对象与Xml序列化工具类

写在前面 一个常用的对象与Xml序列化工具类&#xff0c;使用系统类库System.Xml&#xff0c;序列化时需要注意只能将对象的公共字段和读/写属性转换为 XML。不转换方法、索引器、私有字段或只读属性。另外XmlSerializer 类无法序列化ArrayList数组和List<T>数组。 using…

3、Qt使用windeploy工具打包可执行文件

新建一个文件夹&#xff0c;把要打包的可执行文件exe拷贝过来 点击输入框&#xff0c;复制一下文件夹路径 点击电脑左下角&#xff0c;找到Qt文件夹&#xff0c; 点击打开 “Qt 5.12.0 for Desktop” &#xff08;我安装的是Qt 5.12.0版本&#xff09; 输入“cd bin”&#xff…

springsecurity5.7.x和springsecurity6.x配置文件对比

springsecurity5和springsecurity6如何要实现多种登录方式&#xff0c;自定义登录方式都是一样的操作步骤&#xff0c;主要有四个步骤。 一、自定义登录用户实体实现springsecurity中的UserDetails接口 二、自定义登录用户实现类实现springsecurity中的UserDetailsService接口 …

vivado产生报告阅读分析20-QOR

Report QoR Suggestions report_qor_suggestions 命令是处理 QoR 建议对象时使用的主要命令。 QoR 建议对象会创建命令和属性来改善设计的时序性能&#xff08; 欲知详情 &#xff0c; 请参阅 QoR 建议 &#xff09; 。 report_qor_suggestions 命令可执行两项任务 &am…

代码随想录-刷题第七天

454. 四数相加II 题目链接&#xff1a;454. 四数相加II 思路&#xff1a;哈希法。使用map集合&#xff0c;key存放ab的值&#xff0c;value存放ab出现的次数。使用两层循环&#xff0c;循环前两个数组&#xff0c;找出ab&#xff0c;对map赋值。再用两层循环&#xff0c;遍历…

唯创知音WT2605C-A001音频蓝牙语音芯片:小巧体积,高品质音频播放的创新

在现今的科技繁荣时代&#xff0c;音频技术作为人类感知世界的重要方式&#xff0c;已经变得越来越重要。唯创知音WT2605C-A001音频蓝牙语音芯片&#xff0c;以其卓越的特性和创新性&#xff0c;正在为音频技术领域带来一场革命。 首先&#xff0c;这款芯片以其极小的体积—仅…

chatGPT4机器学习数据后最终保留在机器里的是什么? 机器是怎么产生智能的? TensorFlow没有直接开发出类似GPT-4这样的模型

机器学习数据后最终保留在机器里的是机器学习模型。机器学习模型是机器学习系统中的核心&#xff0c;它是机器学习系统能够进行推理和预测的基础。 机器学习模型通常由参数组成。参数是机器学习模型的权重和偏差。机器学习系统通过训练来学习这些参数。训练是指让机器学习系统…

webpack 打包优化

在vue.config.js中配置 下载 uglifyjs-webpack-plugin 包 const { defineConfig } require("vue/cli-service"); var path require("path");module.exports defineConfig({transpileDependencies: true,filenameHashing: false, // 去除Vue打包后.cs…

0003Java程序设计-ssm基于微信小程序的家教信息管理系统

文章目录 摘要目 录系统实现开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘要 本文讲述了基于微信小程序的家教信息管理系统的设计与实现。结合线上管理的特点&#xff0c;分析了家教信息管理系统的现状&#xff0c;给出…

外汇天眼:香港监管机构对AMTD Global Markets Limited启动法律诉讼

香港证监会&#xff08;SFC&#xff09;已经启动了法律程序&#xff0c;要求首次审裁法院调查AMTD Global Markets Limited&#xff08;AMTD&#xff0c;目前以orientiert XYZ Securities Limited为名&#xff09;及其前高管在与首次公开发行&#xff08;IPO&#xff09;相关的…

【经典小练习】修改文件中的数据

文章目录 &#x1f339;例子&#x1f33a;思路&#x1f6f8;方法一✨报错解决 &#x1f6f8;方法二 &#x1f339;例子 文本文件中有下面的数据 2-1-9-4-7-8 将文件中的数据进行排序&#xff0c;变成下面的数据 1-2-4-7-8-9 &#x1f33a;思路 要对这些数据进行排序&#xf…

智慧楼宇可视化视频综合管理系统,助力楼宇高效安全运行

随着互联网技术的进步和发展&#xff0c;智能化的楼宇建设也逐步成为人们选择办公场所是否方便的一个重要衡量因素。在智能化楼宇中&#xff0c;安全管理也是重要的一个模块。得益于互联网新兴技术的进步&#xff0c;安防视频监控技术也得到了快速发展并应用在楼宇的安全管理中…