openssl genrsa -out private.key 1024
openssl rsa -in private.key -pubout -out public.key
????????BIO?
*
key?
=
?NULL;?
????????RSA?
*
r?
=
?NULL;?
????????key?
=
?BIO_new(BIO_s_file());?
????????BIO_read_filename(key,?
"
c:\\private.key
"
);?
????????r?
=
?PEM_read_bio_RSAPrivateKey(key,?NULL,?NULL,?NULL);?
????????BIO_free_all(key);
讀取 private key?讀取正常,r 并不返回空
使用同樣方法讀取 public key
????????BIO?*key?=?NULL;?
????????RSA?*r?=?NULL;?
????????key?=?BIO_new(BIO_s_file());?
????????BIO_read_filename(key,?"c:\\public.key");?
????????r?=?PEM_read_bio_RSAPublicKey(key,?NULL,?NULL,?NULL);?
????????BIO_free_all(key);
不正常, r 總是返回 NULL,很不爽,將函數(shù)改一下 PEM_read_bio_RSA_PUBKEY
??BIO *key1=NULL;
??RSA *r1=NULL;
??key1=BIO_new(BIO_s_file());
??if(BIO_read_filename(key1,"c:\\public.key") <= 0 )
??{
???printf("error\n");
??}
??
??r1 = PEM_read_bio_RSA_PUBKEY(key1, NULL,NULL,NULL);
??BIO_free_all(key1);
??openssl_to_keys(r, 1024, priv, pub);
r1 讀取成功
?具體原因未知
作者:?playmud??時間:?2009-08-24?11:53:00
讓我們先來看一下pem.h頭文件中的定義:
?
#define?PEM_read_RSAPrivateKey(fp,x,cb,u)?(RSA?*)PEM_ASN1_read(?\
????????(char?*(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char?**)x,cb,u)
#define?PEM_read_RSAPublicKey(fp,x,cb,u)?(RSA?*)PEM_ASN1_read(?\
????????(char?*(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char?**)x,cb,u)
????????
#define?PEM_read_bio_RSAPrivateKey(bp,x,cb,u)?(RSA?*)PEM_ASN1_read_bio(?\
????????(char?*(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char?**)x,cb,u)
#define?PEM_read_bio_RSAPublicKey(bp,x,cb,u)?(RSA?*)PEM_ASN1_read_bio(?\
????????(char?*(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char?**)x,cb,u)?
?
?
對應(yīng)的很工整是不是,你生成一個私鑰,然后用它生成一個公鑰。
openssl?genrsa?-out?private.pem?1024?
openssl?rsa?-in?priv.pem?-pubout?-out?public.pem?
用任何一種方法打開私鑰,讀取私鑰信息,得到RSA,查看RSA,ok,沒有問題,一切都還看起來比較正常。
然后用任何一種方法打開公鑰,讀取公鑰信息,問題出現(xiàn)了:RSA對象為空,你失敗了。
?
通過openssl的手冊和幫助,你會發(fā)現(xiàn)兩個函數(shù):
PEM_read_bio_RSA_PUBKEY()
PEM_read_RSA_PUBKEY()
他們才是你要找的對應(yīng)的,而上面兩個函數(shù)是從任何.h里面找不到的,但是他們的確是真實存在的符號連接,在對應(yīng)的.o文件中用objdump可以查看到他們的符號,很詭異!
現(xiàn)象描述完了,還未探其究竟。
附加讀取 PEM file 的code
????????BIO?*key?=?NULL;?
????????RSA?*r?=?NULL;?
????????key?=?BIO_new(BIO_s_file());?
????????BIO_read_filename(key,?"c:\\private.key");?
????????r?=?PEM_read_bio_RSAPrivateKey(key,?NULL,?NULL,?NULL);?
????????BIO_free_all(key);
????????
????????R_RSA_PRIVATE_KEY?priv;
????????R_RSA_PUBLIC_KEY??pub;
????????openssl_to_keys(r,?1024,?priv,?pub);
????????BIO?*key1=NULL;?
????????RSA?*r1=NULL;?
????????key1=BIO_new(BIO_s_file());?
????????if(BIO_read_filename(key1,"c:\\public.key")?<=?0?)
????????{
????????????printf("error\n");
????????}?
????????
????????r1?=?PEM_read_bio_RSA_PUBKEY(key1,?NULL,NULL,NULL);?
????????BIO_free_all(key1);
????????openssl_to_keys(r,?1024,?priv,?pub);
static?void?bn_to_bin(BIGNUM*?bn,?unsigned?char*?bin,?int?n)?{
????memset(bin,?0,?n);
????int?m?=?BN_num_bytes(bn);
????BN_bn2bin(bn,?bin+n-m);
}
void?openssl_to_keys(
?????????????????????RSA*?rp,?int?nbits,?R_RSA_PRIVATE_KEY&?priv,?R_RSA_PUBLIC_KEY&?pub
?????????????????????)?{
????pub.bits?=?nbits;
????bn_to_bin(rp->n,?pub.modulus,?sizeof(pub.modulus));
????bn_to_bin(rp->e,?pub.exponent,?sizeof(pub.exponent));
????
????memset(&priv,?0,?sizeof(priv));
????priv.bits?=?nbits;
????bn_to_bin(rp->n,?priv.modulus,?sizeof(priv.modulus));
????bn_to_bin(rp->e,?priv.publicExponent,?sizeof(priv.publicExponent));
????bn_to_bin(rp->d,?priv.exponent,?sizeof(priv.exponent));
????bn_to_bin(rp->p,?priv.prime[0],?sizeof(priv.prime[0]));
????bn_to_bin(rp->q,?priv.prime[1],?sizeof(priv.prime[1]));
????bn_to_bin(rp->dmp1,?priv.primeExponent[0],?sizeof(priv.primeExponent[0]));
????bn_to_bin(rp->dmq1,?priv.primeExponent[1],?sizeof(priv.primeExponent[1]));
????bn_to_bin(rp->iqmp,?priv.coefficient,?sizeof(priv.coefficient));
}