数字签名 digital signature

文章目录

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库:

c 复制代码
#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;
    
    // 初始化OpenSSL
    OpenSSL_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算法的数学困难性(大数分解问题)

4.实际应用:

  • SSL/TLS证书验证
  • 软件分发验证
  • 区块链交易签名
  • 安全电子邮件(S/MIME)

5、安全注意事项

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

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

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

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

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

总结

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

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

相关推荐
默辨16 小时前
密码学基础
密码学·非对称加密·数字签名·对称加密·摘要加密
weiwei228442 个月前
secp256k1算法详解一
区块链·数字签名·源码编译·elliptic curve
佛祖让我来巡山3 个月前
【非对称加密】详解及Java实现
非对称加密·数字签名·rsa
胡耀超4 个月前
对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础
密码学·数据安全·数字签名·秘钥交换·密码学协议·后量子密码学
shenmu846 个月前
itsdangerous加解密源码分析|BUG汇总
数字签名·itsdangeous
安 当 加 密7 个月前
【安当产品应用案例100集】034-安当KSP支持密评中存储数据的机密性和完整性
数据安全·加密系统·数字签名·密钥管理·透明加密·加密技术
阿达_优阅达10 个月前
常见问题 | 数字签名如何保障电子商务交易安全?
安全·企业数字化转型·数字签名·合同管理·协议管理
racent锐成信息1 年前
代码签名证书如何为软件签名?代码签名证书签名指南
数字签名·软件安全·代码签名证书·代码签名·软件数字签名
闲人编程1 年前
Python 实现 SHA-1 数字摘要签名算法
开发语言·python·算法·密码学·加解密·数字签名·sha