OpenSSL提供了强大的数据签名功能,可以用于验证数据的完整性和真实性。以下是使用OpenSSL实现数据签名的详细方法:
首先需要一对公私钥:
# 生成RSA私钥(2048位)
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
# 从私钥提取公钥
openssl rsa -pubout -in private_key.pem -out public_key.pem
# 对文件进行签名(SHA256哈希算法)
openssl dgst -sha256 -sign private_key.pem -out signature.bin data.txt
# 计算SHA256摘要
openssl dgst -sha256 -binary -out data.hash data.txt
# 对摘要进行签名
openssl pkeyutl -sign -in data.hash -inkey private_key.pem -out signature.bin -pkeyopt digest:sha256
# 方法1:直接验证
openssl dgst -sha256 -verify public_key.pem -signature signature.bin data.txt
# 方法2:分步验证
openssl dgst -sha256 -binary -out data.hash data.txt
openssl pkeyutl -verify -in data.hash -sigfile signature.bin -inkey public_key.pem -pubin -pkeyopt digest:sha256
# 生成ECDSA密钥对
openssl ecparam -name prime256v1 -genkey -noout -out ecdsa_private.pem
openssl ec -in ecdsa_private.pem -pubout -out ecdsa_public.pem
# 签名
openssl dgst -sha256 -sign ecdsa_private.pem -out ecdsa_signature.bin data.txt
# 验证
openssl dgst -sha256 -verify ecdsa_public.pem -signature ecdsa_signature.bin data.txt
# 生成Ed25519密钥对
openssl genpkey -algorithm ED25519 -out ed25519_private.pem
openssl pkey -pubout -in ed25519_private.pem -out ed25519_public.pem
# 签名
openssl pkeyutl -sign -in data.txt -inkey ed25519_private.pem -out ed25519_signature.bin
# 验证
openssl pkeyutl -verify -in data.txt -sigfile ed25519_signature.bin -inkey ed25519_public.pem -pubin
#include <openssl/evp.h>
#include <openssl/pem.h>
int sign_data(const char* private_key_path, const char* data, size_t data_len, unsigned char** signature, size_t* sig_len) {
FILE* fp = fopen(private_key_path, "r");
if (!fp) return 0;
EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if (!pkey) return 0;
EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
if (!md_ctx) {
EVP_PKEY_free(pkey);
return 0;
}
if (EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) <= 0) {
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
return 0;
}
// 确定签名长度
if (EVP_DigestSign(md_ctx, NULL, sig_len, (const unsigned char*)data, data_len) <= 0) {
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
return 0;
}
*signature = malloc(*sig_len);
if (!*signature) {
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
return 0;
}
if (EVP_DigestSign(md_ctx, *signature, sig_len, (const unsigned char*)data, data_len) <= 0) {
free(*signature);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
return 0;
}
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
return 1;
}
通过以上方法,您可以在Linux环境下使用OpenSSL实现各种数据签名需求。