当前位置: 首页 > news >正文

数字签名 digital signature

文章目录

    • 1、严谨的定义
    • 2、技术原理:如何工作?
      • 第一步:发送者 - 签名过程
      • 第二步:接收者 - 签名验证过程
    • 3、C语言实现示例
    • 4、关键技术要点
    • 5、安全注意事项
    • 6、最重要的应用:TLS/SSL 与网站安全


1、严谨的定义

数字签名是一种利用非对称密码学(公钥密码学)技术来验证数字信息、软件或文件的真实性完整性不可否认性的数学方案。

它解决了三个核心安全问题:

  1. 认证:这条信息确实来自声称的发送者。
  2. 完整性:信息在传输过程中没有被篡改过。
  3. 不可否认性:发送者事后无法否认他发送过这条信息。

2、技术原理:如何工作?

数字签名基于非对称加密,它使用一对数学上相关的密钥:

  • 私钥:由所有者严格保密,绝不泄露。用于创建签名。
  • 公钥:可以公开发布给任何人。用于验证签名。

其工作流程分为两大步:签名验证

第一步:发送者 - 签名过程

原始消息
哈希函数 Hash Function
e.g. SHA-256
得到固定长度的消息摘要
Message Digest
用发送者的私钥
加密消息摘要
生成数字签名
将数字签名附加在
原始消息后面一起发送

为什么先哈希再加密?

  1. 效率:非对称加密非常慢,而哈希函数很快。加密一个短的摘要(如256位)比加密整个大文件(几个GB)要高效得多。
  2. 通用性:非对称加密算法有输入长度限制,而哈希后的摘要长度是固定的,适用于所有加密算法。

第二步:接收者 - 签名验证过程

接收消息+签名
验证流程
分离出原始消息和数字签名
用发送者的公钥
解密数字签名
得到 解密后的摘要H1
对收到的原始消息
使用同样的哈希函数 SHA-256
得到 计算出的摘要H2
对比 H1 == H2?
验证成功
消息完整且真实
验证失败
消息被篡改或签名无效

3、C语言实现示例

以下是一个简化的数字签名实现示例,使用OpenSSL库:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/sha.h>#define KEY_LENGTH 2048
#define PUB_EXP 3// 生成RSA密钥对
RSA *generate_rsa_keypair() {RSA *rsa = RSA_new();BIGNUM *bn = BN_new();if (!BN_set_word(bn, PUB_EXP)) {fprintf(stderr, "Error setting exponent\n");return NULL;}if (!RSA_generate_key_ex(rsa, KEY_LENGTH, bn, NULL)) {fprintf(stderr, "Error generating RSA key\n");return NULL;}BN_free(bn);return rsa;
}// 生成消息的SHA-256哈希
int generate_hash(const unsigned char *message, unsigned char *hash) {if (!message || !hash) return 0;SHA256_CTX sha256;if (!SHA256_Init(&sha256)) return 0;if (!SHA256_Update(&sha256, message, strlen((char *)message))) return 0;if (!SHA256_Final(hash, &sha256)) return 0;return 1;
}// 使用私钥创建签名
int create_signature(RSA *private_rsa, const unsigned char *hash, unsigned char **signature, unsigned int *sig_len) {if (!private_rsa || !hash || !signature || !sig_len) return 0;*signature = (unsigned char *)malloc(RSA_size(private_rsa));if (!*signature) return 0;// 使用私钥加密哈希值(即签名)if (RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH, *signature, sig_len, private_rsa) != 1) {free(*signature);return 0;}return 1;
}// 使用公钥验证签名
int verify_signature(RSA *public_rsa, const unsigned char *hash, const unsigned char *signature, unsigned int sig_len) {if (!public_rsa || !hash || !signature) return 0;// 使用公钥验证签名if (RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature, sig_len, public_rsa) != 1) {return 0; // 验证失败}return 1; // 验证成功
}// 示例使用
int main() {const char *message = "这是一条需要签名的重要消息";unsigned char hash[SHA256_DIGEST_LENGTH];unsigned char *signature = NULL;unsigned int sig_len = 0;// 初始化OpenSSLOpenSSL_add_all_algorithms();ERR_load_crypto_strings();// 生成密钥对RSA *rsa_keypair = generate_rsa_keypair();if (!rsa_keypair) {fprintf(stderr, "密钥对生成失败\n");return 1;}printf("1. 生成SHA-256哈希...\n");if (!generate_hash((unsigned char *)message, hash)) {fprintf(stderr, "哈希生成失败\n");return 1;}printf("2. 使用私钥创建签名...\n");if (!create_signature(rsa_keypair, hash, &signature, &sig_len)) {fprintf(stderr, "签名创建失败\n");return 1;}printf("3. 使用公钥验证签名...\n");if (verify_signature(rsa_keypair, hash, signature, sig_len)) {printf("✅ 签名验证成功!消息完整且真实。\n");} else {printf("❌ 签名验证失败!消息可能被篡改。\n");}// 清理资源free(signature);RSA_free(rsa_keypair);EVP_cleanup();ERR_free_strings();return 0;
}

4、关键技术要点

  1. 哈希函数的作用:SHA-256将任意长度消息转换为固定长度摘要,确保效率和安全性
  2. 非对称加密:私钥签名,公钥验证,实现身份认证
  3. 安全性依赖:
  • 哈希函数的抗碰撞性
  • RSA算法的数学困难性(大数分解问题)
  1. 实际应用:
  • SSL/TLS证书验证
  • 软件分发验证
  • 区块链交易签名
  • 安全电子邮件(S/MIME)

5、安全注意事项

  • 私钥必须安全存储,最好使用硬件安全模块(HSM)
  • 使用足够长的密钥(RSA推荐2048位以上)
  • 定期更新密钥对
  • 使用安全的随机数生成器

数字签名是现代网络安全的基础构建块,为数字通信提供了不可或缺的真实性、完整性和不可否认性保障。

6、最重要的应用:TLS/SSL 与网站安全

当你用浏览器访问 https:// 开头的网站时,就会用到数字签名。

  1. 网站服务器会把它公钥和身份信息(域名等)打包成一个 SSL 证书
  2. 这个证书需要由证书颁发机构用 CA 的私钥进行数字签名
  3. 你的电脑和浏览器里预装了受信任的 CA 的公钥
  4. 浏览器收到网站证书后,用内置的 CA 公钥去验证证书上的签名。
  • 验证成功:说明此证书真实有效,且未被篡改。你就能确信你连接的就是 google.com,而不是一个钓鱼网站。随后才会开始加密通信。
  • 验证失败:浏览器就会弹出巨大的红色警告,阻止你继续访问。

总结

特性如何实现
真实性只有用发送者的私钥才能生成能被其公钥成功解开的签名。
完整性签名的生成依赖于原始消息的哈希值,任何改动都会导致哈希值巨变,使验证失败。
不可否认性由于私钥由发送者唯一持有,成功验证的签名可以作为法律证据,证明发送者确实生成了该签名。

简单来说,数字签名是现实世界中手写签名和印章在数字世界的终极升级版,它不仅证明了签署者的身份,还保证了被签署内容本身一丝一毫都未被改变

http://www.dtcms.com/a/358621.html

相关文章:

  • 第三十一天:数列求和取模
  • 达梦数据库-报错-03-viosocket_peer_addr getpeername error: 107
  • USB4 vs USB3.0:一场接口技术的革命性飞跃
  • 软件IIC与硬件IIC的区别
  • Visual Studio内置环境变量有哪些
  • 毕业项目推荐:47-基于yolov8/yolov5/yolo11的焊缝质量检测识别系统(Python+卷积神经网络)
  • 2025年- H102-Lc210--3658.奇数和与偶数和的最大公约数(gcd最大公约数)--Java版
  • OpenCV 轮廓分析实战:从检测到形状匹配的完整指南
  • 图像结构化拆分与格式标准化方案
  • 复现 RoboDK 机械臂几何校准(Staubli TX2‑90L / TX200)
  • 基于轴重转移补偿和多轴协调的粘着控制方法研究
  • 基于STM32单片机的OneNet物联网云平台农业土壤湿度控制系统
  • 【lua】模块基础及应用
  • 无网络安装来自 GitHub 的 Python 包
  • DETR:用Transformer革新目标检测的新范式
  • REST-assured 接口测试编写指南
  • 平衡树的左旋
  • 在 WSL2-NVIDIA-Workbench 中安装Anaconda、CUDA 13.0、cuDNN 9.12 及 PyTorch(含完整环境验证)
  • 第二十六天-ADC基本原理
  • 学习大模型,还有必要学习机器学习,深度学习和数学吗
  • 苍穹外卖项目笔记day02
  • 嵌入式学习笔记--LINUX系统编程--DAY03进程控制
  • 在 .NET Core 中实现基于策略和基于角色的授权
  • 【系列10】端侧AI:构建与部署高效的本地化AI模型 第9章:移动端部署实战 - iOS
  • SpringAI应用开发面试剧本与技术知识全解析:RAG、向量数据库、多租户与企业落地场景
  • 【工具类】ssh使用案例
  • 26届秋招开始啦
  • UE5多人MOBA+GAS 56、WSL + Docker 编排 Linux 服务器与 Windows 客户端
  • 【PCIE系列】1---PCIE系统拓扑结构分析
  • 基于TCN-BiLSTM-SelfAttention神经网络的多输入单输出回归预测【MATLAB】