天天看點

openssl庫的PEM_read_bio_RSAPublicKey和PEM_read_bio_RSA_PUBKEY API之間的差别

本文章參考:http://www.manongjc.com/article/57939.html

本文記錄openssl庫實作rsa加解密之PEM_read_bio_RSAPublicKey() 和 PEM_read_bio_RSA_PUBKEY()兩個API的異同。

RSA加密的public key格式有多種,常見的有兩種,一種密鑰頭為 ‘-----BEGIN RSA PUBLIC KEY-----’ ,一種開頭為 ‘-----BEGIN PUBLIC KEY-----’,二者分别對應RSA的PKCS#1和PKCS#8格式。使用openssl庫加載RSA的公鑰時,使用的函數也不同。以字元串公鑰為例,對PKCS#1格式的密鑰加載使用PEM_read_bio_RSAPublicKey()函數,對PKCS#8格式公鑰的加載使用PEM_read_bio_RSA_PUBKEY()函數。對于不那麼熟悉rsa的同學,使用時注意區分者,可以減少不必要的麻煩。

string Base64Encode_std(const string& encodeStr){
//ignore
}
string rsaEncode(const unsigned char * in, int len, const char *pubKey){
	BIO *bio=NULL;
	RSA *rsa = NULL;
	char szOut[512] = {0};
	string pkcs1_header = "-----BEGIN RSA PUBLIC KEY-----";
	string pkcs8_header = "-----BEGIN PUNLIC KEY-----";
	bio = BIO_bew(BIO_s_mem());
	if (NULL == bio) return "";
	BIO_puts(bio,pubKey);
	if( 0 == strncmp(pubKey,pkcs8_header.c_str(),pkcs8.size())){
		rsa = PEM_read_bio_RSA_PUBKEY(bio,NULL,NULL,NULL);
	}
	else if(0 == strncmp(pubKey,pkcs1_header.c_str(),pkcs1.size())){
		rsa = PEM_read_bio_RSAPublicKey(bio,NULL,NULL,NULL);
	}
	if(NULL == rsa) return "";
	int ret = RSA_public_encrypt(len,in,(unsigned char*)szOut,rsa,RSA_PKCS1_PADDING);
	if (ret < 0 ) return "";
	string encrypt_data = string(szOut,ret);
	string resultStr = Base64Encode_std(encrypt_data);
	if(bio) BIO_free(bio);
	if(rsa) RSA_free(rsa);
	return resultStr;
}
           

上面代碼中加了一點兒判斷,區分了一下pkcs#8和pkcs#1的格式,完全的情況還有一些其他的格式。

StackOverflow上有個關于這個的回答,寫的比較詳細,有興趣的可以參考。

https://stackoverflow.com/questions/18039401/how-can-i-transform-between-the-two-styles-of-public-key-format-one-begin-rsa/29707204#29707204

要了解rsa加密的算法原理,可以參考這個知乎的文章

https://zhuanlan.zhihu.com/p/45317622

繼續閱讀