openssl版本:1.1.1
C语言rsa验签SHA256+rsa4096+PSS
输入:源文件,模数,指数,签名数据
c
/*****************************
* SHA256+rsa4096+PSS
* 文件输入 源文件、模数和指数、签名数据
* 注:可以处理大源文件
*
*
* ***************************** */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
int verify_signature(BIGNUM *modulus, BIGNUM *exponent, const char *data_file) {
EVP_PKEY *public_key = EVP_PKEY_new();
FILE *data_file_ptr, *signature_file_ptr;
unsigned char buffer[4096];
unsigned char buffer_1[512] = {0x00, 0x3d, 0xf7, 0xf6, 0x34, 0x67, 0xdd, 0x8d, 0x13, 0x3e, 0xa0, 0xed, 0xb5, 0xd2, 0xa3, 0xf1
, 0x68, 0xd5, 0xb4, 0x87, 0xa6, 0x71, 0xc2, 0x45, 0xc5, 0x60, 0x8e, 0x5a, 0x98, 0x36, 0x7f, 0xae
, 0xb8, 0x7c, 0x6d, 0x42, 0xa2, 0x98, 0x5e, 0xfc, 0x53, 0x4c, 0x01, 0xaa, 0xc9, 0x01, 0x9c, 0x3e
, 0x7f, 0x38, 0x2b, 0x56, 0xc4, 0xd3, 0xa1, 0x38, 0x85, 0x3c, 0x04, 0x21, 0x79, 0xa6, 0xc9, 0xc0
, 0xff, 0xa7, 0xfa, 0xc0, 0x07, 0xe2, 0x7e, 0x07, 0x67, 0x3a, 0xf9, 0x55, 0xd8, 0xe8, 0xa3, 0xea
, 0xbe, 0xcd, 0x8b, 0x2e, 0x4f, 0x0c, 0x04, 0xef, 0x18, 0xcf, 0x40, 0x42, 0x8d, 0x3f, 0x5a, 0x2a
, 0x7c, 0xa8, 0xeb, 0xdc, 0x55, 0xc2, 0x08, 0xaf, 0x5e, 0xc7, 0xdd, 0xf7, 0x6d, 0xbb, 0x5d, 0x68
, 0x44, 0x91, 0xc1, 0x8e, 0x89, 0x63, 0x5e, 0xb8, 0x91, 0xf1, 0x6e, 0x76, 0xfb, 0xf8, 0x78, 0x19
, 0xef, 0xa1, 0x99, 0x69, 0x6a, 0x43, 0x45, 0xf6, 0x29, 0x30, 0x73, 0x6a, 0x6a, 0x09, 0x70, 0x9f
, 0x0b, 0x46, 0xe7, 0x28, 0xb6, 0xaf, 0x2a, 0x2d, 0x07, 0xef, 0x17, 0xd5, 0x80, 0x21, 0x19, 0xff
, 0x5c, 0x00, 0x26, 0x5c, 0xc4, 0xef, 0x73, 0x00, 0x2a, 0x18, 0x28, 0xd9, 0x32, 0x64, 0xc5, 0x2a
, 0xd2, 0xc4, 0x83, 0xce, 0x33, 0x9d, 0x4e, 0xb9, 0x70, 0x55, 0x43, 0xd0, 0x94, 0xf0, 0x80, 0x7f
, 0x4f, 0x2d, 0x7a, 0x71, 0x59, 0x8b, 0xd3, 0x59, 0x77, 0xd2, 0xb9, 0x9c, 0x7d, 0xdf, 0x5f, 0x91
, 0x41, 0xa4, 0x4f, 0x2d, 0x6e, 0xce, 0xd3, 0xda, 0x5f, 0xfd, 0x50, 0x1f, 0x08, 0xb0, 0xc1, 0x02
, 0x5e, 0x3e, 0xff, 0x37, 0x8c, 0xcc, 0xbe, 0x02, 0xb2, 0x81, 0x24, 0x59, 0x26, 0x90, 0xd3, 0x17
, 0x49, 0xe5, 0xb0, 0x23, 0xb3, 0xca, 0x8b, 0xa9, 0x9b, 0xe7, 0x34, 0x0c, 0xdb, 0xad, 0x61, 0x72
, 0xe4, 0x3d, 0x38, 0xb4, 0x47, 0xd2, 0xa8, 0x39, 0xad, 0xdc, 0x25, 0xa6, 0x1a, 0x86, 0x5d, 0x61
, 0x02, 0xa5, 0xcb, 0x22, 0xf2, 0x38, 0x4e, 0x2b, 0x17, 0xc7, 0xf2, 0x41, 0x08, 0xe8, 0x81, 0x72
, 0x02, 0x30, 0xce, 0x97, 0xca, 0x78, 0xa6, 0x26, 0x30, 0xa9, 0x8b, 0x3e, 0x1b, 0xd9, 0x82, 0x3d
, 0xbe, 0x80, 0x0b, 0xb8, 0xc7, 0xa6, 0x02, 0x66, 0x92, 0xf8, 0x5b, 0x76, 0x0f, 0x00, 0xea, 0x49
, 0xe4, 0x85, 0x04, 0x7c, 0x57, 0x49, 0x30, 0x22, 0xf2, 0x2c, 0x50, 0x26, 0x45, 0xfa, 0x74, 0x85
, 0x5d, 0xc4, 0xe7, 0x42, 0xe9, 0x6d, 0x41, 0xa5, 0x5f, 0x30, 0xef, 0x20, 0x55, 0x79, 0x45, 0xca
, 0x9d, 0xbb, 0x18, 0x2a, 0x81, 0x99, 0x88, 0x65, 0xdf, 0xf2, 0x27, 0xa7, 0x48, 0x7f, 0x30, 0xb6
, 0xbf, 0x76, 0x3b, 0xff, 0x65, 0xaa, 0x74, 0x2d, 0xde, 0x74, 0x3e, 0x76, 0xeb, 0x5d, 0x97, 0xa1
, 0x76, 0x72, 0x61, 0xc5, 0xae, 0x49, 0xed, 0x59, 0xc7, 0xf1, 0xb3, 0xba, 0xac, 0x1c, 0x15, 0xe5
, 0xbc, 0xf5, 0x91, 0xd5, 0x18, 0x54, 0x00, 0xfe, 0x8d, 0x15, 0xa3, 0xc9, 0x8b, 0x0a, 0x2f, 0x86
, 0x6b, 0xc1, 0x5d, 0x33, 0xe5, 0xe7, 0x77, 0xbb, 0x1d, 0x5c, 0x40, 0xde, 0xd3, 0x7a, 0x9b, 0xcf
, 0x03, 0x3c, 0xce, 0x8f, 0xcd, 0x88, 0xa0, 0x0a, 0x80, 0xd1, 0x83, 0x87, 0xad, 0xd9, 0x89, 0xc6
, 0x9e, 0xbb, 0xde, 0x2b, 0xaa, 0x24, 0x1e, 0x98, 0x75, 0xb9, 0x10, 0x4b, 0x38, 0xa3, 0xfa, 0xaf
, 0xa0, 0xf1, 0x9c, 0x9c, 0x84, 0xbc, 0x43, 0xfc, 0xa8, 0xa4, 0x0f, 0x0a, 0xfc, 0xf8, 0x80, 0x14
, 0x8a, 0x77, 0x25, 0x62, 0x4f, 0x7c, 0xb3, 0x24, 0x0e, 0x13, 0xef, 0x44, 0x46, 0x17, 0x0a, 0x1c
, 0xd1, 0x33, 0x64, 0xd1, 0xcf, 0x82, 0xba, 0xdc, 0x03, 0xef, 0xb6, 0x21, 0xa9, 0x56, 0xf3, 0x5f};
size_t len;
EVP_MD_CTX *md_ctx;
EVP_PKEY_CTX *pkey_ctx;
int ret;
RSA *rsa = NULL;
// Step 1: Create RSA key from modulus and exponent
rsa = RSA_new();
if (!rsa) {
printf("Error creating RSA key\n");
if (public_key) EVP_PKEY_free(public_key);
}
if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
printf("Error setting RSA key components\n");
if (public_key) EVP_PKEY_free(public_key);
}
// Step 2: Assign RSA key to EVP_PKEY
if (EVP_PKEY_assign_RSA(public_key, rsa) <= 0) {
printf("Error assigning RSA to EVP_PKEY\n");
if (public_key) EVP_PKEY_free(public_key);
}
/* 打开数据文件和签名文件 */
data_file_ptr = fopen(data_file, "rb");
if (!data_file_ptr) {
perror("Error opening data file");
EVP_PKEY_free(public_key);
return -1;
}
/* 初始化上下文 */
md_ctx = EVP_MD_CTX_new();
if (!md_ctx) {
perror("Error creating EVP_MD_CTX");
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
/* 使用RSA-PSS进行初始化 */
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, EVP_sha256(), NULL, public_key) <= 0) {
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
/* 设置PSS参数,这里以SHA256为例,salt长度默认为hash长度 */
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) <= 0) { // -1 表示自动设置为散列函数的输出长度
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
/* 读取数据并验证签名 */
while ((len = fread(buffer, 1, sizeof(buffer), data_file_ptr)) > 0) {
if (EVP_DigestVerifyUpdate(md_ctx, buffer, len) <= 0) {
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
}
if(ferror(data_file_ptr)) {
perror("Error reading data file");
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
/* 读取签名并验证 */
// rewind(signature_file_ptr);
// if (fread(buffer, 1, EVP_PKEY_size(public_key), signature_file_ptr) != EVP_PKEY_size(public_key)) {
// perror("Error reading signature file");
// EVP_MD_CTX_free(md_ctx);
// EVP_PKEY_free(public_key);
// fclose(data_file_ptr);
// fclose(signature_file_ptr);
// return -1;
// }
ret = EVP_DigestVerifyFinal(md_ctx, buffer_1, EVP_PKEY_size(public_key));
if (ret == 1) {
printf("Signature verified successfully.\n");
} else if (ret == 0) {
printf("Signature verification failed.\n");
} else {
ERR_print_errors_fp(stderr);
}
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return ret;
}
int main() {
const char *data_file_path = "data.txt";
BIGNUM *modulus = BN_new(); // Populate this with your actual modulus
BIGNUM *exponent = BN_new(); // Populate this with your actual exponent
char *n_str = "F1E148093CB89606C0E4B02F523857A7495D674BBA20ABD4E19715D5BCE18EC1C83C296F871B8893ACE01E453744FBD4FF78F745AC9DD466ABF8D5A3329EA325E88B5992300AF47C21F4E3262D3E10BE956627B077C9215C157AA66869BA7655C2CFB515A71F8FB3B7CF6AEF315F89C8DD68ECB3396BDD9D9EF4F9FD1B551D86891FECE88A14118BA459DEC75DEDFCC58B1696391628CF01953D33EE152CDB3F14FED2C54313A2B4EDEF370CE669F7DB48DBF72626B6DEC4B57BBBF35B67ABAE9F7AA9CD29B35F2EA42D5D730AB16C86E6EA5A42A2043DF075BE71B4DA35EB11480B4421BF09B8D8DF066AD0A67924004AB61805D3F46976099E036AAB5D9FB30D6A1486C8D5F37156931149C4954B08852DE0C84759574636253BCF16A78D0CDFE81D1F121CBF0AAB306B5C11CEE3CBF574379DE493711B9DE3255A57FA3BB1A847E1AC37465BF737AC0B8816C560F557770EF377B72447D6951DB9E74E2BC31214AA9AA47A6E1A630F5AE9A1F8D77B8405EC98E03D722C4B2EE52741B013FA52A5FBE3FB5544CE10F0E9DE4AC3F0C4FC348C263B3E90375200A720BE2ED6D4840866F4B2F5D5BFE6E54872B7ECD768E4229436ADBF3F65FF59FFF35B1747A60C927E1CF8E78666BFEA555AF96EE995152792D1514CB6EC3F6F9B6A654A23528E9983FE14C73215CA2199C5514D9C33B1C74BE23D60F78E0B472606DC12A903";
char *e_str = "010001";
// 这里仅作示例,实际应使用正确的值设置n和e
BN_hex2bn(&modulus, n_str);
BN_hex2bn(&exponent, e_str);
if (verify_signature(modulus, exponent, data_file_path) != 1) {
fprintf(stderr, "Verification failed or error occurred.\n");
return 1;
}
return 0;
}
C语言rsa验签SHA256+rsa4096+PSS
输入:源文件,公钥文件,签名文件
c
/*****************************
* SHA256+rsa4096+PSS
* 文件输入 源文件、公钥文件、签名文件
* 注:
*
*
* ***************************** */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
int print_NE_from_EVP_PKEY(EVP_PKEY *pkey) {
RSA *rsa_key = NULL;
int result = 0;
BIGNUM *modulus;
BIGNUM *public_exponent;
// 首先检查给定的EVP_PKEY是否是RSA类型
if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
// 获取RSA密钥结构
rsa_key = EVP_PKEY_get1_RSA(pkey);
if (rsa_key != NULL) {
// 从RSA结构中提取模数和公钥指数
modulus = BN_dup(RSA_get0_n(rsa_key));
public_exponent = BN_dup(RSA_get0_e(rsa_key));
if (modulus != NULL && public_exponent != NULL) {
result = 1; // 成功
} else {
// 如果复制失败,需要释放之前分配的资源
BN_free(modulus);
BN_free(public_exponent);
modulus = NULL;
public_exponent = NULL;
result = 0; // 失败
}
// 由于EVP_PKEY_get1_RSA增加了引用计数,我们需要用EVP_PKEY_free_RSA来减少
RSA_free(rsa_key);
} else {
// EVP_PKEY_get1_RSA失败
ERR_print_errors_fp(stderr);
}
} else {
fprintf(stderr, "The provided EVP_PKEY is not of type RSA.\n");
}
char *n_str = BN_bn2hex(modulus);
char *e_str = BN_bn2hex(public_exponent);
printf("Modulus (n): %s\n", n_str);
printf("Public exponent (e): %s\n", e_str);
return result;
}
int verify_signature(const char *public_key_file, const char *data_file, const char *signature_file) {
EVP_PKEY *public_key = NULL;
FILE *pubkey_file, *data_file_ptr, *signature_file_ptr;
unsigned char buffer[4096];
size_t len;
EVP_MD_CTX *md_ctx;
EVP_PKEY_CTX *pkey_ctx;
int ret;
/* 读取公钥 */
pubkey_file = fopen(public_key_file, "r");
if (!pubkey_file) {
perror("Error opening public key file");
return -1;
}
public_key = PEM_read_PUBKEY(pubkey_file, NULL, NULL, NULL);
fclose(pubkey_file);
if (!public_key) {
ERR_print_errors_fp(stderr);
return -1;
}
print_NE_from_EVP_PKEY(public_key);
/* 打开数据文件和签名文件 */
data_file_ptr = fopen(data_file, "rb");
if (!data_file_ptr) {
perror("Error opening data file");
EVP_PKEY_free(public_key);
return -1;
}
signature_file_ptr = fopen(signature_file, "rb");
if (!signature_file_ptr) {
perror("Error opening signature file");
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
return -1;
}
/* 初始化上下文 */
md_ctx = EVP_MD_CTX_new();
if (!md_ctx) {
perror("Error creating EVP_MD_CTX");
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
/* 使用RSA-PSS进行初始化 */
if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, EVP_sha256(), NULL, public_key) <= 0) {
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
/* 设置PSS参数,这里以SHA256为例,salt长度默认为hash长度 */
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1) <= 0) { // -1 表示自动设置为散列函数的输出长度
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
/* 读取数据并验证签名 */
while ((len = fread(buffer, 1, sizeof(buffer), data_file_ptr)) > 0) {
if (EVP_DigestVerifyUpdate(md_ctx, buffer, len) <= 0) {
ERR_print_errors_fp(stderr);
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
}
if(ferror(data_file_ptr)) {
perror("Error reading data file");
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
/* 读取签名并验证 */
rewind(signature_file_ptr);
if (fread(buffer, 1, EVP_PKEY_size(public_key), signature_file_ptr) != EVP_PKEY_size(public_key)) {
perror("Error reading signature file");
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return -1;
}
ret = EVP_DigestVerifyFinal(md_ctx, buffer, EVP_PKEY_size(public_key));
if (ret == 1) {
printf("Signature verified successfully.\n");
} else if (ret == 0) {
printf("Signature verification failed.\n");
} else {
ERR_print_errors_fp(stderr);
}
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(public_key);
fclose(data_file_ptr);
fclose(signature_file_ptr);
return ret;
}
int main() {
const char *public_key_path = "public_key.pem";
const char *data_file_path = "data.txt";
const char *signature_file_path = "signature.bin";
if (verify_signature(public_key_path, data_file_path, signature_file_path) != 1) {
fprintf(stderr, "Verification failed or error occurred.\n");
return 1;
}
return 0;
}
编译:
c
gcc check_sign_by_sourceFile_sig_value_NE.c -lcrypto -o a_sig_PSS