當前位置:編程學習大全網 - 源碼下載 - OpenSSL之RSA用法

OpenSSL之RSA用法

RSA公開密鑰密碼體制是壹種使用不同的加密密鑰與解密密鑰,“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制 。在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密算法E和解密算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK 。

正是基於這種理論,1978年出現了著名的RSA算法,它通常是先生成壹對RSA密鑰,其中之壹是保密密鑰,由用戶保存;另壹個為公開密鑰,可對外公開,甚至可在網絡服務器中註冊。為提高保密強度,RSA密鑰至少為500位長,壹般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送信息時,常采用傳統加密方法與公開密鑰加密方法相結合的方式,即信息采用改進的DES或IDEA對話密鑰加密,然後使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息後,用不同的密鑰解密並可核對信息摘要 。

RSA算法是壹個廣泛使用的公鑰算法。其密鑰包括公鑰和私鑰。它能用於數字簽名、身份認證以及密鑰交換。RSA密鑰長度壹般使用1024位或者更高。RSA密鑰信息主要包括:

n:模數

e:公鑰指數

d:私鑰指數

p:最初的大素數

q:最初的大素數

其中,公鑰為n和e;私鑰為n和d。

本文假設妳已經安裝好了OpenSSL,並且持有壹份1.1.1的源碼。

RSA相關的頭文件在rsa.h中、源文件在crypto/rsa目錄中。

這個結構定義了RSA內部數據信息。主要字段含義:

version —— 版本。

meth —— RSA運算抽象方法集合。

n,e,d,p,q,dmp1,dmq1,iqmp —— 密鑰相關的大數。

這個結構定義了RSA內部各種運算抽象方法集合。主要字段含義:

name —— 名稱描述。

rsa_pub_enc —— 公鑰加密方法。

rsa_pub_dec —— 公鑰解密方法。

rsa_priv_enc —— 私鑰加密方法。

rsa_priv_dec —— 公鑰解密方法。

rsa_sign —— 簽名方法。

rsa_verify —— 驗簽方法。

rsa_keygen —— 生成密鑰對方法。

在1.1.1中,大多數的數據結構已經不再向使用者開放,從封裝的角度來看,這是更合理的。如果妳在頭文件中找不到結構定義,不妨去源碼中搜壹搜。

RSA *RSA_new(void);

生成壹個RSA密鑰結構,采用默認的rsa_pkcs1_ossl_meth方法。

void RSA_free(RSA *r);

釋放RSA結構。

RSA *RSA_generate_key(int bits, unsigned long e, void (*callback) (int, int, void *), void *cb_arg);

生成RSA密鑰(舊版本)。

bits為密鑰位數,e為公鑰指數。

callback為密鑰生成過程中的幹預回調函數,通常傳入NULL。cb_arg為回調參數。

成功返回RSA指針,失敗返回NULL。

int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);

生成RSA密鑰(新版本)。

rsa為RSA對象指針。bits為密鑰位置,e為公鑰指數的大數形式指針。cb為幹預回調函數,通常傳入NULL。

成功返回1,失敗返回0。

關於公鑰指數e,主要有兩個取值:

# define RSA_3 0x3L

# define RSA_F4 0x10001L

RSA *RSAPublicKey_dup(RSA *rsa);

復制RSA公鑰部分。

成功返回RSA指針,失敗返回NULL。

RSA *RSAPrivateKey_dup(RSA *rsa);

復制RSA私鑰部分。

成功返回RSA指針,失敗返回NULL。

int RSA_bits(const RSA *rsa);

獲取RSA密鑰位數。

int RSA_size(const RSA *rsa);

獲取RSA密鑰長度。

int RSA_check_key(const RSA *);

int RSA_check_key_ex(const RSA *, BN_GENCB *cb);

檢查RSA的有效性,必須為完整的密鑰對。

成功返回1,失敗返回0。

int RSA_print(BIO *bp, const RSA *r, int offset);

int RSA_print_fp(FILE *fp, const RSA *r, int offset);

將RSA信息輸出到bp/fp中,off為輸出信息在bp/fp中的偏移量,比如是屏幕bp/fp,則表示打印信息的位置離左邊屏幕邊緣的距離。

int RSA_public_encrypt(int flen, const unsigned char *from,

unsigned char *to, RSA *rsa, int padding);

RSA公鑰加密。

成功返回密文的長度,失敗返回-1。

int RSA_public_decrypt(int flen, const unsigned char *from,

unsigned char *to, RSA *rsa, int padding);

RSA公鑰解密。

成功返回明文的長度,失敗返回-1。

int RSA_private_encrypt(int flen, const unsigned char *from,

unsigned char *to, RSA *rsa, int padding);

RSA私鑰加密。

成功返回密文的長度,失敗返回-1。

int RSA_private_decrypt(int flen, const unsigned char *from,

unsigned char *to, RSA *rsa, int padding);

RSA私鑰解密。

成功返回明文的長度,失敗返回-1。

關於padding填充方式,取值:

其中PKCS1填充大小為11字節,所以加密明文長度必須不大於(密鑰大小-11字節)。

# define RSA_PKCS1_PADDING_SIZE 11

int RSA_sign(int type, const unsigned char *m, unsigned int m_length,

unsigned char *sigret, unsigned int *siglen, RSA *rsa);

對數據m生成RSA簽名,生成的簽名長度與key的長度相同,如512位密鑰生成64字節簽名。

type指定摘要算法的NID,如NID_sha1。

成功返回1,失敗返回0。

int RSA_verify(int type, const unsigned char *m, unsigned int m_length,

const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

對數據m驗證RSA簽名。

type指定摘要算法的NID,如NID_sha1。

成功返回1,失敗返回0。

以下函數在x509.h中定義:

int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)

{

return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);

}

將RSA公鑰轉換為DER編碼,並寫入到bp抽象IO中。

成功返回1,失敗返回0。

RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)

{

return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);

}

從bp抽象IO中讀取DER編碼,並轉換為rsa結構私鑰。

成功返回有效指定,失敗返回NULL。

int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)

{

return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);

}

將RSA公鑰轉換為DER編碼,並寫入到bp抽象IO中。

成功返回1,失敗返回0。

RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)

{

return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);

}

從bp抽象IO中讀取DER編碼,並轉換為rsa結構公鑰。

成功返回有效指定,失敗返回NULL。

下面這個例子演示了RSA密鑰對的生成、公私鑰的復制、公鑰加密和私鑰解密的用法。

輸出:

下面這個例子演示了公私鑰的分開保存、讀取,以及使用公私鑰加解密。

輸出:

RSA_generate_key_ex() ret:1

i2d_RSAPrivateKey_bio() ret:1

i2d_RSAPublicKey_bio() ret:1

copy' private key size:64

copy' public key size:64

RSA_public_encrypt() ret:64

RSA_private_decrypt() ret:10

text:[1234567890]

下面這個例子演示了簽名的生成和驗證操作。

輸出:

ret:1

RSA_sign() ret:1

sign 64

4ec0af099c49646b72fda88a4fb11e8deb3898da9c3f611a5f25f05d9d005631858239bbb732cd5060dbc975363fc1b9cdfdc5a04554115a916f06f98163189f

RSA_verify() ret:1

  • 上一篇:清朝皇帝打賞的金瓜子是幹什麽用的?對此妳怎麽看?
  • 下一篇:ubuntu怎麽安裝tar.gz(以flashget為例)
  • copyright 2024編程學習大全網