2012-05-04 74 views

回答

2
RSA_print_fp(stdout, x, 0); 

http://linux.die.net/man/3/rsa_print_fp

+0

謝謝您的回答,但請你詳細瞭解此解釋。我對此沒有足夠的瞭解。 –

+0

正如文檔所述,此函數將給定'RSA *'對象'x'的字符串表示形式寫入給定的'FILE *'流。 'stdout'具有'FILE *'類型'並代表您的控制檯。當你寫入這個「文件」時,數據顯示在程序標準輸出中。 –

4
#include <iostream> 
using std::cout; 
using std::endl; 

#include <string> 
using std::string; 

#include <memory> 
using std::unique_ptr; 

#include <openssl/bn.h> 
#include <openssl/rsa.h> 
#include <openssl/bio.h> 
#include <openssl/buffer.h> 

#include <cassert> 
#define ASSERT assert 

using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>; 
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>; 
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 

int main(int argc, char* argv[]) 
{ 
    int rc; 

    RSA_ptr rsa(RSA_new(), ::RSA_free); 
    BN_ptr bn(BN_new(), ::BN_free); 
    BIO_MEM_ptr bio(BIO_new(BIO_s_mem()), ::BIO_free); 

    rc = BN_set_word(bn.get(), RSA_F4); 
    ASSERT(rc == 1); 

    rc = RSA_generate_key_ex(rsa.get(), 2048, bn.get(), NULL); 
    ASSERT(rc == 1); 

    rc = RSA_print(bio.get(), rsa.get(), 0); 
    ASSERT(rc == 1); 

    BUF_MEM* mem = NULL; 
    BIO_get_mem_ptr(bio.get(), &mem); 
    ASSERT(mem != NULL); 

    string s; 
    if(mem->data && mem->length) 
     s.assign(mem->data, mem->length); 

    if(s.length()) 
     cout << s << endl; 
    else 
     cout << "Failed to retrieve key" << endl; 

    return 0; 
} 

一個典型的運行:

$ ./test-openssl.exe 
Private-Key: (1024 bit) 
modulus: 
    00:9e:44:ab:26:da:2d:42:3f:ea:06:1f:3b:80:22: 
    39:0f:89:ee:38:ba:f9:49:a6:7d:69:be:f7:b8:43: 
    30:db:7b:32:82:09:89:c4:84:43:af:75:33:22:40: 
    07:ad:43:c8:56:54:f3:c5:6e:a5:bc:a6:b2:83:49: 
    a4:07:8e:d3:b8:a1:5b:c9:55:04:0a:01:73:12:85: 
    93:ef:20:0b:29:2e:a8:2d:4f:4a:1d:ad:31:b8:81: 
    dd:57:49:3c:d1:57:71:29:c3:34:1c:cf:ba:31:86: 
    cb:d6:d7:92:b9:3c:84:ca:2e:f6:fa:85:0a:86:e4: 
    b1:e0:1e:00:86:d9:c6:14:37 
publicExponent: 65537 (0x10001) 
privateExponent: 
    5e:1d:7f:99:af:0c:52:e5:27:09:54:f1:51:15:08: 
    d1:90:b8:34:cc:1b:0a:0d:13:6f:1a:bc:bc:ba:58: 
    07:6c:8f:70:7c:b3:8c:45:0a:ea:ff:ca:d4:87:37: 
    09:75:d1:60:65:4c:41:0f:b7:47:23:e9:eb:e0:92: 
    c6:5b:cc:d2:82:d5:f3:42:75:d4:88:95:35:20:62: 
    f9:9a:18:df:6b:5b:ff:6c:97:11:63:d6:24:2c:86: 
    bb:be:c1:ed:a3:87:8e:78:70:7a:c8:fc:73:9c:53: 
    70:eb:ff:06:b9:91:be:81:56:a5:25:71:d3:54:09: 
    04:ea:8d:1e:8e:48:eb:c1 
prime1: 
    00:cc:25:66:b7:dc:66:64:eb:5c:f2:15:9f:7b:66: 
    c0:9e:8d:51:63:e0:8b:15:73:64:54:d2:62:35:a6: 
    14:29:20:ba:92:3e:dc:d4:32:6a:c6:ba:45:56:94: 
    3e:77:e1:ab:e0:60:cf:12:2b:09:1f:45:0e:2c:b2: 
    49:1e:85:66:ef 
prime2: 
    00:c6:78:0f:44:19:cc:74:22:32:58:d1:ee:a7:6f: 
    fa:b4:57:a4:4a:7c:7a:52:53:c8:52:48:34:05:b4: 
    59:3f:18:a3:88:17:fd:ae:2e:54:d7:83:2c:a9:bf: 
    52:7b:f4:e9:af:02:61:99:fa:35:4a:b0:e4:a0:8c: 
    5f:f8:d8:67:39 
exponent1: 
    00:a3:41:7d:c5:a7:72:13:5e:cd:b3:a3:6b:28:ca: 
    61:5b:ea:73:9e:45:e1:b4:43:d5:86:a7:c0:76:5a: 
    dc:60:8f:95:e4:82:75:23:15:36:a2:ba:2f:dd:2f: 
    2c:4d:be:a1:2f:0c:fc:4b:f1:32:98:59:27:1e:c3: 
    6d:0a:05:70:ed 
exponent2: 
    00:97:d5:de:08:01:9c:b2:f4:3e:84:49:07:45:bd: 
    9b:95:40:bf:85:e4:b9:48:26:a4:c8:9e:48:7e:5c: 
    bd:32:52:4d:39:9e:f1:0a:c2:93:51:d5:1e:e4:36: 
    64:8a:44:92:4a:bb:8d:a3:d9:11:d0:34:88:94:73: 
    10:31:36:8d:b1 
coefficient: 
    1d:97:1c:37:72:66:87:6f:a8:10:5d:bf:02:31:3d: 
    69:bb:a8:13:78:cb:20:d7:70:ee:f9:ba:1e:a9:e1: 
    ca:5b:db:a8:12:64:39:32:4f:0b:b8:0e:0f:fc:2c: 
    ec:89:25:06:bf:84:d7:94:e5:18:bd:80:f4:74:ba: 
    5e:0a:4c:24 

如果你不喜歡這樣的輸出,你可以直接訪問RSA成員。例如:

// RSA object 'owns' the BIGNUM. Don't destroy it. 
BIGNUM* n = rsa.get()->n; 
BIGNUM* e = rsa.get()->e; 
BIGNUM* d = rsa.get()->d; 

string s; 

BIO_reset(bio.get()); 
mem = NULL; 

rc = BN_print(bio.get(), n); 
ASSERT(rc == 1); 

BIO_get_mem_ptr(bio.get(), &mem); 
if(mem && mem->data && mem->length) 
    s.assign(mem->data, mem->length); 

if(s.length()) 
    cout << "Modulus: " << endl << s << endl; 
else 
    cout << "Failed to retrieve modulus" << endl; 

BIO_reset(bio.get()); 
mem = NULL; 

rc = BN_print(bio.get(), e); 
ASSERT(rc == 1); 

BIO_get_mem_ptr(bio.get(), &mem); 
if(mem && mem->data && mem->length) 
    s.assign(mem->data, mem->length); 

if(s.length()) 
    cout << "Public exponent: " << endl << s << endl; 
else 
    cout << "Failed to retrieve public exponent" << endl; 

BIO_reset(bio.get()); 
mem = NULL; 

rc = BN_print(bio.get(), d); 
ASSERT(rc == 1); 

BIO_get_mem_ptr(bio.get(), &mem); 
if(mem && mem->data && mem->length) 
    s.assign(mem->data, mem->length); 

if(s.length()) 
    cout << "Private exponent: " << endl << s << endl; 
else 
    cout << "Failed to retrieve private exponent" << endl; 

輸出將類似於:

Modulus: 
E00226E63C7BE6A23990592F3F861393B1F563D7CF57699619E6ED558EFA6D64C326203825E163EF 
28B7B3608C68B8A9F1A5952FA8E4C42A4F6066BE6D1502D20894577C91DB94F6F596891DCF9532E2 
19FBAEA1201215E014DEE8A270BEABDFC7D00860BF3C08A26707CADAECCF9A2229984C23F198691E 
B59D26D4AC8460BD 
Public exponent: 
10001 
Private exponent: 
3D3E99600D5D5ABB33BDD184677BC2D278AF3CB2FE4F49E0EE08030F875DD496DDFC08871164442C 
591790856F1E1A8EEC30774F667FD55A34058951BB052995BC24A80AAA547E1764FB33500007A743 
C9B41F376F655EB8BDD729172F8592886C299994565F9F72A0235CBB22AA33BD1A2D20AF07DCBAC5 
6DB22E4DCBC4DCC1 

如果你喜歡的第一個例子的格式(用冒號分隔的八位字節),然後看看ASN1_bn_print 。您可以使用它依次打印RSA成員。 RSA_printRSA_print_fp內部呼叫ASN1_bn_print。有一個例子在OpenSSL command in c to get Modulus of a public Key in the RSA

BIGNUM* n = rsa.get()->n; 

int req = BN_num_bytes(n) + 4; 
unsigned char* ptr = (unsigned char*)OPENSSL_malloc(req); 

rc = ASN1_bn_print(bio.get(), "Modulus:", n, ptr, 0); 
ASSERT(rc == 1); 

BIO_get_mem_ptr(bio.get(), &mem); 
if(mem && mem->data && mem->length) 
    s.assign(mem->data, mem->length); 

if(s.length()) 
    cout << s << endl; 
else 
    cout << "Failed to retrieve modulus" << endl; 

它會產生類似的輸出:

Modulus: 
    00:bf:49:fa:f2:30:21:42:de:91:60:f3:02:37:87: 
    86:f4:eb:85:2c:95:86:42:69:6f:bc:cf:3f:27:9e: 
    17:b6:44:06:5f:e7:ea:9f:e8:38:a7:5a:d5:da:9f: 
    4b:26:df:78:15:d7:df:22:c0:16:12:77:f9:18:aa: 
    85:01:21:3a:b0:ae:39:b8:07:cd:d4:2c:a3:0b:1c: 
    df:be:09:03:09:76:5f:a1:1e:c0:00:8e:bf:b2:40: 
    e2:3c:eb:d1:85:6f:7a:ab:35:c3:3a:c4:23:db:39: 
    0c:d0:2b:39:b3:a5:a5:08:a2:e4:00:d5:0b:b0:87: 
    62:ae:7c:a4:6c:e6:1c:d6:c9 

您還可以使用BN_bn2dec和朋友。例如:

BIGNUM* n = rsa.get()->n; 
cout << "BN_bn2dec:" << endl; 
cout << BN_bn2dec(n) << endl; 

它會產生:

BN_bn2dec: 
12243739000135209335165415265342326792394455644180015057748915050940947919482400 
64106225312022889083399949792870649447719809295883754268473265926413766309145047 
08000254475023744104439182803717332048247971986885955229841406443364223719542912 
385690146029374797423322891147172613041161904860242946608474463378207 
+0

太棒了!謝謝。 – MasterPiece

相關問題