C语言rsa验签(源文件,模数,指数,签名文件\签名数据)

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
相关推荐
祁思妙想9 分钟前
10.《滑动窗口篇》---②长度最小的子数组(中等)
leetcode·哈希算法
做人不要太理性2 小时前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
飞升不如收破烂~17 小时前
redis的map底层数据结构 分别什么时候使用哈希表(Hash Table)和压缩列表(ZipList)
算法·哈希算法
wzx_Eleven2 天前
【课堂笔记】隐私计算实训营第四期:隐私求交PSI
笔记·算法·哈希算法
好睡凯3 天前
大数据的left_join
数据结构·c++·算法·leetcode·排序算法·哈希算法
飞升不如收破烂~3 天前
hash表和B树
b树·算法·哈希算法
飞升不如收破烂~3 天前
redis的双重hash作用
数据库·redis·哈希算法
小奕同学A3 天前
坚如磐石的安全堡垒
算法·安全·哈希算法
夜泉_ly4 天前
数据结构 -hash table
数据结构·哈希算法·散列表
cdut_suye4 天前
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅
数据库·c++·人工智能·python·深度学习·机器学习·哈希算法