Key generation
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
RSA *rsa: output key handle;
int bits: length of key
BIGNUM *e: e
BN_GENCB *cb: callback, can be NULL.
Sample code:
void rasTest()
{
RSA *rsa;
int iBits = 1024; // key length
int nid = NID_sha1; // sign alg
unsigned long e = RSA_F4; // here we use classical 0x010001
BIGNUM *bne; // store e
unsigned char bData[100] = {0};
unsigned char bSign[200] = {0};
int iSignlen = sizeof(bData);
int iDatalen = sizeof(bSign);
int ret = 0;
bne=BN_new();
ret=BN_set_word(bne,e);
r=RSA_new();
ret=RSA_generate_key_ex(rsa,bits,bne,NULL);
if(ret!=1)
{
printf("RSA_generate_key_ex err!/n");
return -1;
}
ret=RSA_sign(nid,bData,iDatalen,bSignt,(unsigned int *)&iSignlen,rsa);
if(ret!=1)
{
printf("RSA_sign err!/n");
RSA_free(r);
return -1;
}
ret=RSA_verify(nid,data,datalen,bSign,iSignlen,rsa);
if(ret!=1)
{
printf("RSA_verify err!/n");
RSA_free(r);
return -1;
}
RSA_free(r);
printf("test ok!/n");
return 0;
}
About the RAS sign and verify.
Just call the two functions
/* The following 2 functions sign and verify a X509_SIG ASN1 object
* inside PKCS#1 padded RSA encryption */
int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
The type defines the hash algorithm.
We need to pay attention that the length of input data.
with the PKCS#1 padding mode, the max length of encrypted data is 128 – 11 = 117 bytes. When signing, the data will be transferred into X509_SIG ASN1 object, so the length of signed data should be less than 103. and if the type(define the hash algorithm ) is NID_md5_sha1, the signed data should be 36.
RSA key pair output and input
We may use the two functions:
len=i2d_RSAPublicKey(r,&p); // when output, the pointer p step the length of len forward.
pub_rsa=d2i_RSAPublicKey(NULL,(const unsigned char **)&p,(long )len);
as long as the len is longer than buf, the Key will be inputed, and also the pointer p will step forward.
We can also output the key into an encrypted PEM file.
And the APIs is easy to use.
PEM_write_bio_RSAPrivateKey
PEM_write_bio_RSAPublicKey
PEM_read_bio_RSAPrivateKey
PEM_read_bio_RSAPublicKey
Sample code:
int testRSAOutput(RSA *r)
{
int ret;
BIO *out,*in;
RSA *read;
OpenSSL_add_all_algorithms();
enc=EVP_des_ede3_ofb();
out=BIO_new_file("pri.pem","w");
ret=PEM_write_bio_RSAPrivateKey(out,r,enc,NULL,0,NULL,"123456");
if(ret!=1)
{
RSA_free(r);
BIO_free(out);
return -1;
}
BIO_flush(out);
BIO_free(out);
out=BIO_new_file("pub.pem","w");
ret=PEM_write_bio_RSAPublicKey(out,r);
if(ret!=1)
{
RSA_free(r);
BIO_free(out);
return -1;
}
BIO_flush(out);
BIO_free(out);
in=BIO_new_file("pri.pem","rb");
read=RSA_new();
read=PEM_read_bio_RSAPrivateKey(in,&read,NULL,"123456");
if(read->d!=NULL)
printf("test ok!/n");
else
printf("err!/n");
RSA_free(read);
BIO_free(in);
return 0;
}