OpenSSL RSA签名和校验


#include 
#include 
#include 
#include 

#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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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);
}

你可能感兴趣的:(网络安全,ssl)