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

数字签名 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.xdnf.cn/news/19385.html

相关文章:

  • 年化225%,回撤9%,夏普4.32,3积分可查看参数
  • Java 常见异常系列:ClassNotFoundException 类找不到
  • Java 学习笔记(基础篇12)
  • 学习Python中Selenium模块的基本用法(10:浏览器操作)
  • 让演化可编程:XLang 与可逆计算的结构化范式
  • [ZJCTF 2019]NiZhuanSiWei
  • 第2节:项目前期准备
  • C++抽象类
  • 【Python 后端框架】总结
  • Nginx反向代理与负载均衡
  • 基于单片机指纹考勤系统/智能考勤
  • DeepSeek应用技巧-通过MCP打造数据分析助手
  • YOLOv11 训练参数全解析:一文掌握 epochs、batch、optimizer 调优技巧
  • kali下sqlmap更新失败问题
  • PB-重装系统后,重新注册ole控件,pb中窗口控件失效的问题。
  • 不用公网IP也能?cpolar实现Web-Check远程安全检测(1)
  • 2025年09月计算机二级MySQL选择题每日一练——第十二期
  • 数据结构 | 深度解析二叉树的基本原理
  • 云存储(参考自腾讯云计算工程师认证)
  • 整体设计 的语言设计:通用模型语言的标准模板语言的规格模式语言--含输出(腾讯元宝答问)
  • 漏洞挖掘-信息收集教程
  • 阿里云营业执照OCR接口的PHP实现与技术解析:从签名机制到企业级应用
  • Jdk动态代理 Cglib动态代理
  • Linux 定时器:工作原理与实现机制深入分析
  • STL库——list(类模拟实现)
  • 复制VMware虚拟机后的网络配置
  • 算法---动态规划(持续更新学习)
  • k230 按键拍照后,将摄像头拍照的1920*1080分辨率的图片以jpg文件格式,保存到板载TF存储卡的指定文件夹目录中
  • 营业执照经营范围行业提取工具库项目方案解读(php封装库)
  • 项目管理在企业中的作用