Skip to content

Instantly share code, notes, and snippets.

@tusharbapte
Forked from byronhe/ecdsa_demo.cpp
Created May 5, 2020 04:33
Show Gist options
  • Save tusharbapte/bb5a05034cd333f9732066db1da3e98b to your computer and use it in GitHub Desktop.
Save tusharbapte/bb5a05034cd333f9732066db1da3e98b to your computer and use it in GitHub Desktop.
ecdsa key generate / sign / verify demo
#include <openssl/ecdsa.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
//EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(NID_ecdsa_with_SHA256,NULL);
//EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen);
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen);
int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
BIO *BIO_new_fd(int fd, int close_flag);
BIO *BIO_new_fp(FILE *stream, int close_flag);
BIO *BIO_new_mem_buf(void *buf, int len);
DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x,
pem_password_cb *cb, void *u);
RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x,
pem_password_cb *cb, void *u);
int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
RSA *PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x,
pem_password_cb *cb, void *u);
RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x,
pem_password_cb *cb, void *u);
int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x);
int PEM_write_RSAPublicKey(FILE *fp, RSA *x);
void generate_key_pair(string & pub_key, string & priv_key){
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
assert(1==EC_KEY_generate_key(ec_key));
assert(1==EC_KEY_check_key(ec_key));
BIO * bio = BIO_new_fp(stdout,0);
//assert(1==EC_KEY_print(bio, ec_key, 0));
BIO_free(bio);
{
FILE * f = fopen(pub_key.c_str(),"w");
PEM_write_EC_PUBKEY(f, ec_key);
//PEM_write_bio_EC_PUBKEY(bio, ec_key);
fclose(f);
}
{
FILE * f = fopen(priv_key.c_str(),"w");
PEM_write_ECPrivateKey(f,ec_key, NULL,NULL,0,NULL,NULL);
//PEM_write_bio_ECPrivateKey(bio,ec_key, NULL,NULL,0,NULL,NULL);
fclose(f);
}
EC_KEY_free(ec_key);
}
void sign_buff(const string & priv_key_file_path, const unsigned char * buff, int buff_len, string & sig){
FILE * f = fopen(priv_key_file_path.c_str(), "r");
EC_KEY *ec_key = PEM_read_ECPrivateKey(f,NULL,NULL,NULL);
fclose(f);
assert(1==EC_KEY_check_key(ec_key));
EVP_PKEY * key = EVP_PKEY_new();
assert(1==EVP_PKEY_assign_EC_KEY(key, ec_key));
EVP_PKEY_CTX * key_ctx = EVP_PKEY_CTX_new(key,NULL);
assert(1==EVP_PKEY_sign_init(key_ctx));
assert(1==EVP_PKEY_CTX_set_signature_md(key_ctx, EVP_sha256()) );
size_t sig_len=0;
assert(1==EVP_PKEY_sign(key_ctx,NULL,&sig_len, buff , buff_len));
sig.assign(sig_len,0);
assert(1==EVP_PKEY_sign(key_ctx,(unsigned char *) &sig[0],&sig_len, buff, buff_len));
EVP_PKEY_CTX_free(key_ctx);
EVP_PKEY_free(key);
}
bool verify_sig_of_buff(const string & pub_key_file_path, const unsigned char * buff, size_t buff_len, const string & sig){
FILE * f = fopen(pub_key_file_path.c_str(), "r");
EC_KEY *ec_key = PEM_read_EC_PUBKEY(f, NULL, NULL, NULL);
fclose(f);
EVP_PKEY * key = EVP_PKEY_new();
assert(1==EVP_PKEY_assign_EC_KEY(key, ec_key));
EVP_PKEY_CTX * key_ctx = EVP_PKEY_CTX_new(key,NULL);
assert(1==EVP_PKEY_verify_init(key_ctx));
assert(1==EVP_PKEY_CTX_set_signature_md(key_ctx, EVP_sha256()) );
size_t sig_len=0;
const int ret=EVP_PKEY_verify(key_ctx, (unsigned char * )&sig[0],sig.size(), buff , buff_len);
EVP_PKEY_CTX_free(key_ctx);
EVP_PKEY_free(key);
cout<<ret<<endl;
return ret;
}
int main(){
string pub, priv;
pub="ec.public_key.pem";
priv="ec.private_key.pem";
generate_key_pair(pub,priv);
string sig;
unsigned char buff[]= "to be or not to be ,that is the problem.";
sign_buff(priv,&buff[0], sizeof(buff), sig);
cout<<sig.size()<<"\t"<<sig<<endl;
verify_sig_of_buff(pub,&buff[0],sizeof(buff), sig);
//sig.insert(sig.begin()+2,' ');
//sig="dasdas"+sig;
cout<<sig.size()<<"\t"<<sig<<endl;
verify_sig_of_buff(pub,&buff[0],sizeof(buff), sig);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment