• openssl -- 签名和验签函数调用,使用SHA1函数对原数据进行摘要计算 -- 代码


    示例代码:

    #include <stdio.h>
    #include <openssl/rsa.h>
    #include <openssl/pem.h>
    #include <openssl/sha.h>
    #include <stddef.h>
    #include <string.h>

    #define OPENSSLKEY "../priv.key"
    #define PUBLICKEY "../pub.key"

    int my_sign(char *path_key, char *data, unsigned int len_data, char ** p_sign, unsigned int * len_sign);
    int my_verify(char *path_key, char *data, unsigned int len_data, char *p_sign, unsigned int len_sign);
    void drump_hex(char * data, unsigned int len_data);
    int main()
    {
    printf("first ");
    char data[] = "MY name is my";

    char * p_sign = NULL;
    int len_sign = 0;
    int len_data = 0;

    char * ptr = data;
    while(*(ptr ++))
    {
    len_data++;
    }

    printf("Len_data: %d ",len_data);


    if(my_sign(OPENSSLKEY, data,len_data, &p_sign, &len_sign))
    {
    printf("Ha Ha sign succeed!!!! ");
    }

    #if 1
    printf(" The signer is : ");
    drump_hex(p_sign, len_sign);
    #endif // 1


    if(my_verify(PUBLICKEY, data, len_data, p_sign,len_sign))
    {
    printf("Ha Ha Verify succeed!!!! ");
    }

    return 0;
    }


    int my_sign(char *path_key, char *data, unsigned int len_data, char ** p_sign, unsigned int * len_sign)
    {
    FILE *p_file = NULL;
    RSA * p_rsa = NULL;
    unsigned char SHA[SHA_DIGEST_LENGTH] = "";


    if((p_file = fopen(path_key, "r")) == NULL)
    {
    perror("the file open fail");
    return 0;
    }

    if((p_rsa = PEM_read_RSAPrivateKey(p_file, NULL, NULL, NULL)) == NULL)
    {
    //ERR_print_errors_fp(stdout);
    printf("RSA 私钥读取失败!");
    goto error;
    }
    fclose(p_file);
    /*
    原型:
    unsigned char * SHA1(const unsigned char * d, size_t n, unsigned char *md);
    计算从d开始的n个字节的sha1摘要值,然后存储到md
    (md所指像的空间大小时SHA_DIGEST_LENGTH = 20字节)

    返回哈希值的指针
    */


    if(SHA1(data, len_data, SHA) == NULL)
    {
    printf("Hash error!! ");
    goto error;
    }

    #if 1
    printf(" The First SHA1 data is: ");
    drump_hex(SHA, SHA_DIGEST_LENGTH);
    #endif // 1


    *len_sign = RSA_size(p_rsa);
    *p_sign = (char *)malloc((*len_sign) + 1);
    memset(*p_sign, 0, (*len_sign) + 1);

    /*
    原型:
    int RSA_sign(int type, unsigned char *m, unsigned int m_len,
    unsigned char* sigret, unsigned int *siglen, RSA *rsa);

    使用PKCS #1 v2.0中指定的私有密钥rsa对大小m_len的消息摘要m进行签名。
    它将签名存储在sigret中,将签名大小存储在siglen中。sigret必须指向内存的RSA_size(rsa)字节。

    type表示生成消息m所使用的摘要算法。它通常是NID_sha1,NID_ripemd160和NID_md5.

    成功返回1,否则返回0.
    */

    if((RSA_sign(NID_sha1, SHA, SHA_DIGEST_LENGTH, *p_sign ,len_sign, p_rsa)) != 1)
    {
    printf("RSA_sign() error! ");
    goto error;
    }

    return 1;

    error:
    if(p_file != NULL)
    fclose(p_file);
    if(p_rsa != NULL)
    RSA_free(p_rsa);
    if(*p_sign != NULL)
    free(*p_sign);

    return 0;
    }

    int my_verify(char *path_key, char *data, unsigned int len_data, char *p_sign, unsigned int len_sign)
    {
    FILE *p_file;
    RSA *p_rsa;
    unsigned char SHA[SHA_DIGEST_LENGTH] = "";

    if((p_file = fopen(path_key, "r")) == NULL)
    {
    perror("the file open fail ");
    return 0;
    }

    if((p_rsa = PEM_read_RSA_PUBKEY(p_file, NULL, NULL, NULL)) == NULL)
    {
    //ERR_print_errors_fp(stdout);
    printf("RSA Private key read error! ");
    goto error;
    }
    fclose(p_file);

    if(SHA1(data, len_data, SHA) == NULL)
    {
    printf("Hash error!! ");
    goto error;
    }

    #if 1
    printf(" The second SHA1 data is: ");
    drump_hex(SHA, SHA_DIGEST_LENGTH);
    #endif // 1

    /*
    int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
    unsigned char * sigbuf, unsigned int siglen, RSA *rsa);
    RSA_verify()验证大小为siglen的签名sigbuf是否匹配大小为m_len的给定消息摘要m。
    type表示用于生成签名的消息摘要算法。rsa是签名者的公钥。

    */
    if(RSA_verify(NID_sha1, SHA, SHA_DIGEST_LENGTH, p_sign ,len_sign, p_rsa) != 1)
    {
    printf("RSA_sign() error! ");
    goto error;
    }
    else
    {
    return 1;
    }
    error:
    if(p_file != NULL)
    fclose(p_file);
    if(p_rsa != NULL)
    RSA_free(p_rsa);
    if(p_file != NULL)
    fclose(p_file);

    }

    void drump_hex(char * data, unsigned int len_data)
    {
    for(int i = 0; i < len_data; i++)
    {
    if(i % 8 == 0)
    {
    printf(" %08d : ", i/8);
    }
    printf("%02X ", (unsigned char)data[i]);
    }
    }

    //在linux下编译的时候,记得要加链接 -lcrypto。  例如:gcc RSA_sign_verify_my.c -o sign3 -lcrypto

  • 相关阅读:
    C++编程中的小规范(转)
    windows的消息大全(收集)
    C中的一些好玩的事(一)转
    C++ 温故而知新(三)
    C++温故而知新(二)
    C++的内存分布(一)转
    C++ 温故而知新(一)
    C++反射机制模拟
    VS2010 下配置opeNGL遇到的问题
    SharedPreference.Editor的apply和commit方法异同
  • 原文地址:https://www.cnblogs.com/ruigelwang/p/12750343.html
Copyright © 2020-2023  润新知