OpenSSL RSA签名和校验


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

#define RSA_DATA_MAX_SIZE     2048

static int RSAKeyGen(int bits, char *pem_key_name)
{
    int ret;
    printf("Gen Rsa Keypair...\n");
    EVP_PKEY_CTX *ctx;
    EVP_PKEY *pkey = NULL;
    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    if (!ctx) {
        /* Error occurred */
        printf("error1\n");
        return -1;
    }
    if (EVP_PKEY_keygen_init(ctx) <= 0) {
        /* Error */
        printf("error2\n");
        return -1;
    }
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
        /* Error */
        printf("error3\n");
        return -1;
    }

    /* Generate key */
    ret = EVP_PKEY_keygen(ctx, &pkey);// RSA_generate_key(bits, 65537, NULL, NULL);

    /* Save Keypair */
    BIO *bio = BIO_new_file(pem_key_name, "wb");
    if (pkey != NULL) {
        ret = PEM_write_bio_RSAPrivateKey(bio, pkey->pkey.rsa, NULL, NULL, 0, NULL, NULL);
//        ret = PEM_write_bio_RSA_PUBKEY(bio, pkey->pkey.rsa); //todo
    }
    printf("ret = %d, done\n", ret);
    BIO_free_all(bio);
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx);

    return ret;
}

static int RsaSign(char *pkey_file, char *in_file, char *out_file)
{
    int ret, i;
    BIO *bio;
    EVP_PKEY *pkey = NULL;
    int sig_len;
    EVP_MD_CTX  md_ctx, md2_ctx;
    FILE *in_fp, *out_fp;
    int inlen, outlen;
    unsigned  char inbuf [128];
    unsigned  char sig_buf [RSA_DATA_MAX_SIZE];

    printf("Get PEM KEY\n");
    bio = BIO_new(BIO_s_file());
    BIO_read_filename(bio, pkey_file);
    PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL);
    if (pkey == NULL) {
        printf("read prikey error \n");
        return -1;
    }
    printf("Get PEM KEY Done.\n");
    in_fp = fopen(in_file, "r");
    out_fp = fopen(out_file, "wb");

    inlen = fread(inbuf, 1, RSA_DATA_MAX_SIZE, in_fp);
    if (inlen <= 0) {
        return 0;
    }
    printf("Sign data...\n");
    /* Signature is siglen bytes written to buffer sig */
    EVP_SignInit(&md_ctx, EVP_sha256());
    EVP_SignUpdate(&md_ctx, inbuf, inlen);
    sig_len = sizeof(sig_buf);
    ret = EVP_SignFinal(&md_ctx, sig_buf, &sig_len,  pkey);
    if (ret > 0) {
        fwrite(sig_buf, 1, sig_len, out_fp);
        printf ("Ok.\n");
    }
    else {
        printf("Failed.\n");
    }
    EVP_PKEY_free (pkey);
}


static int RsaVerify(char *pkey_file, char *in_file, char *sign_file)
{
    int ret, i;
    BIO *bio;
    EVP_PKEY    *pkey = NULL;
    EVP_MD_CTX  md_ctx, md2_ctx;

    FILE  *in_fp, *sign_fp;
    int   inlen, sign_len;
    unsigned char inbuf[RSA_DATA_MAX_SIZE];
    unsigned char sign_buf[256];

    printf("Get PEM KEY\n");
    bio = BIO_new(BIO_s_file());
    BIO_read_filename(bio, pkey_file);
    PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL);
    if (pkey == NULL) {
        printf("read prikey error \n");
        return -1;
    }
    printf("Get PEM KEY Done.\n");

    in_fp = fopen(in_file, "r");
    sign_fp = fopen(sign_file, "r");

    inlen = fread(inbuf, 1, RSA_DATA_MAX_SIZE, in_fp);
    if (inlen <= 0) {
        printf("Get Plain data failed\n");
        return 0;
    }

    sign_len = fread(sign_buf, 1, RSA_DATA_MAX_SIZE, sign_fp);
    if (sign_len <= 0) {
        printf("Get Sign data failed\n");
        return 0;
    }

    printf("Verify data...\n");
    EVP_VerifyInit(&md2_ctx, EVP_sha256());
    EVP_VerifyUpdate(&md2_ctx, inbuf, inlen);
    ret = EVP_VerifyFinal(&md2_ctx, sign_buf, sign_len, pkey);
    if (ret > 0) {
        printf ("Ok.\n");
    } else {
        printf ("Failed.\n");
        //ERR_print_errors_fp(stdout);
    }
    EVP_PKEY_free (pkey);
}
int main (){
//    RSAKeyGen(1024,"key.pem");
//    RsaSign("key.pem","plain.txt","out.txt");
    RsaVerify("key.pem","plain.txt","out.txt");
    return 0;
}

#include <stdio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>

int main()
{
    int err;
    int sig_len;
    unsigned char sig_buf[4096];
    static char certfile[] = "../../openssl/sign/cert.pem";
    static char keyfile[] = "../../openssl/sign/key.pem";
    static char data[] = "I owe you...";
    EVP_MD_CTX md_ctx;
    EVP_PKEY *pkey;
    FILE *fp;
    X509 *x509;

    /*
     * Just load the crypto library error strings, SSL_load_error_strings()
     * loads the crypto AND the SSL ones
     */
    /* SSL_load_error_strings(); */
    ERR_load_crypto_strings();

    /* Read private key */

    fp = fopen(keyfile, "r");
    if (fp == NULL)
        exit(1);
    pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);

    if (pkey == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Do the signature */

    EVP_SignInit(&md_ctx, EVP_sha1());
    EVP_SignUpdate(&md_ctx, data, strlen(data));
    sig_len = sizeof(sig_buf);
    err = EVP_SignFinal(&md_ctx, sig_buf, &sig_len, pkey);

    if (err != 1) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    EVP_PKEY_free(pkey);

    /* Read public key */

    fp = fopen(certfile, "r");
    if (fp == NULL)
        exit(1);
    x509 = PEM_read_X509(fp, NULL, NULL, NULL);
    fclose(fp);

    if (x509 == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Get public key - eay */
    pkey = X509_get_pubkey(x509);
    if (pkey == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Verify the signature */

    EVP_VerifyInit(&md_ctx, EVP_sha1());
    EVP_VerifyUpdate(&md_ctx, data, strlen((char *)data));
    err = EVP_VerifyFinal(&md_ctx, sig_buf, sig_len, pkey);
    EVP_PKEY_free(pkey);

    if (err != 1) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    printf("Signature Verified Ok.\n");
    return (0);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值