2014-06-12 13 views
5

Sto cercando di caricare una chiave RSA privata da un std::string che contiene la chiave privata in formato PEM, in questo modo:carico RSA chiave privata da un PEM codificato chiave privata

-----BEGIN RSA PRIVATE KEY----- 
MIIBOgIBAAJBAK8Q+ToR4tWGshaKYRHKJ3ZmMUF6jjwCS/u1A8v1tFbQiVpBlxYB 
paNcT2ENEXBGdmWqr8VwSl0NBIKyq4p0rhsCAQMCQHS1+3wL7I5ZzA8G62Exb6RE 
INZRtCgBh/0jV91OeDnfQUc07SE6vs31J8m7qw/rxeB3E9h6oGi9IVRebVO+9zsC 
IQDWb//KAzrSOo0P0yktnY57UF9Q3Y26rulWI6LqpsxZDwIhAND/cmlg7rUz34Pf 
SmM61lJEmMEjKp8RB/xgghzmCeI1AiEAjvVVMVd8jCcItTdwyRO0UjWU4JOz0cnw 
5BfB8cSIO18CIQCLVPbw60nOIpUClNxCJzmMLbsrbMcUtgVS6wFomVvsIwIhAK+A 
YqT6WwsMW2On5l9di+RPzhDT1QdGyTI5eFNS+GxY 
-----END RSA PRIVATE KEY----- 

E mi chiedo se qualcuno può aiutarmi a usare questa chiave invece di generare un casuale con la seguente dichiarazione.

CryptoPP::RSA::PrivateKey rsaPrivate; 
rsaPrivate.GenerateRandomWithKeySize (rnd, 512); 
+0

La password della chiave privata è protetta? – jww

+0

No, l'ho preso da un'altra fonte e lo metto in questa std :: string –

+0

La tua domanda è stata aggiunta alla wiki di Crypto ++ su [Tasti e formati, Chiavi codificati PEM] (http://www.cryptopp.com/ wiki/Keys_and_Formats # PEM_Encoded_Keys) – jww

risposta

7

Il codice è codificato PEM. È necessario rimuovere l'intestazione e il piè di pagina PEM, quindi convertire da Base64 indietro a DER/BER e infine utilizzare lo BERDecodePrivateKey di Crypto ++.

C'è qualche lettura sull'argomento nel wiki Crypto ++ sotto Keys and Formats. Di seguito è riportato il codice per eseguire la conversione (non credo che Stack Overflow ne abbia un esempio funzionante in Crypto ++).

string RSA_PRIV_KEY = 
    "-----BEGIN RSA PRIVATE KEY-----\n" 
    "MIIBOgIBAAJBAK8Q+ToR4tWGshaKYRHKJ3ZmMUF6jjwCS/u1A8v1tFbQiVpBlxYB\n" 
    "paNcT2ENEXBGdmWqr8VwSl0NBIKyq4p0rhsCAQMCQHS1+3wL7I5ZzA8G62Exb6RE\n" 
    "INZRtCgBh/0jV91OeDnfQUc07SE6vs31J8m7qw/rxeB3E9h6oGi9IVRebVO+9zsC\n" 
    "IQDWb//KAzrSOo0P0yktnY57UF9Q3Y26rulWI6LqpsxZDwIhAND/cmlg7rUz34Pf\n" 
    "SmM61lJEmMEjKp8RB/xgghzmCeI1AiEAjvVVMVd8jCcItTdwyRO0UjWU4JOz0cnw\n" 
    "5BfB8cSIO18CIQCLVPbw60nOIpUClNxCJzmMLbsrbMcUtgVS6wFomVvsIwIhAK+A\n" 
    "YqT6WwsMW2On5l9di+RPzhDT1QdGyTI5eFNS+GxY\n" 
    "-----END RSA PRIVATE KEY-----"; 

static string HEADER = "-----BEGIN RSA PRIVATE KEY-----"; 
static string FOOTER = "-----END RSA PRIVATE KEY-----"; 

size_t pos1, pos2; 
pos1 = RSA_PRIV_KEY.find(HEADER); 
if(pos1 == string::npos) 
    throw runtime_error("PEM header not found"); 

pos2 = RSA_PRIV_KEY.find(FOOTER, pos1+1); 
if(pos2 == string::npos) 
    throw runtime_error("PEM footer not found"); 

// Start position and length 
pos1 = pos1 + HEADER.length(); 
pos2 = pos2 - pos1; 
string keystr = RSA_PRIV_KEY.substr(pos1, pos2); 

// Base64 decode, place in a ByteQueue 
ByteQueue queue; 
Base64Decoder decoder; 

decoder.Attach(new Redirector(queue)); 
decoder.Put((const byte*)keystr.data(), keystr.length()); 
decoder.MessageEnd(); 

// Write to file for inspection 
FileSink fs("decoded-key.der"); 
queue.CopyTo(fs); 
fs.MessageEnd(); 

try 
{ 
    CryptoPP::RSA::PrivateKey rsaPrivate; 
    rsaPrivate.BERDecodePrivateKey(queue, false /*paramsPresent*/, queue.MaxRetrievable()); 

    // BERDecodePrivateKey is a void function. Here's the only check 
    // we have regarding the DER bytes consumed. 
    ASSERT(queue.IsEmpty()); 
} 
catch (const Exception& ex) 
{ 
    cerr << ex.what() << endl; 
    exit (1); 
} 

Dopo aver caricato la chiave, è possibile convalidare con:

AutoSeededRandomPool prng; 
bool valid = rsaPrivate.Validate(prng, 3); 
if(!valid) 
    cerr << "RSA private key is not valid" << endl; 

e stamparlo con:

cout << "N: " << rsaPrivate.GetModulus() << endl << endl; 
cout << "E: " << rsaPrivate.GetPublicExponent() << endl << endl; 
cout << "D: " << rsaPrivate.GetPrivateExponent() << endl << endl; 

Se la chiave è protetto da password, quindi Crypto ++ non può decodificare esso. La libreria non ha il supporto per eseguire la decodifica. In questo caso, è possibile convertirlo in BER/DER utilizzando il seguente comando OpenSSL. Quindi puoi usare il materiale chiave con Crypto ++.

openssl pkcs8 -nocrypt -in rsa-key.pem -inform PEM -topk8 -outform DER -out rsa-key.der 

Il programma di esempio scritto la chiave di file con questo:

FileSink fs("decoded-key.der"); 
queue.CopyTo(fs); 
fs.MessageEnd(); 

Il CopyTo lascia i byte nella queue per un uso successivo. È possibile scaricare il file con uno strumento ASN.1, ad esempio dumpasn1 di Gutmann:

$ dumpasn1 decoded-key.der 
    0 314: SEQUENCE { 
    4 1: INTEGER 0 
    7 65: INTEGER 
     :  00 AF 10 F9 3A 11 E2 D5 86 B2 16 8A 61 11 CA 27 
     :  76 66 31 41 7A 8E 3C 02 4B FB B5 03 CB F5 B4 56 
     :  D0 89 5A 41 97 16 01 A5 A3 5C 4F 61 0D 11 70 46 
     :  76 65 AA AF C5 70 4A 5D 0D 04 82 B2 AB 8A 74 AE 
     :  1B 
74 1: INTEGER 3 
77 64: INTEGER 
     :  74 B5 FB 7C 0B EC 8E 59 CC 0F 06 EB 61 31 6F A4 
     :  44 20 D6 51 B4 28 01 87 FD 23 57 DD 4E 78 39 DF 
     :  41 47 34 ED 21 3A BE CD F5 27 C9 BB AB 0F EB C5 
     :  E0 77 13 D8 7A A0 68 BD 21 54 5E 6D 53 BE F7 3B 
143 33: INTEGER 
     :  00 D6 6F FF CA 03 3A D2 3A 8D 0F D3 29 2D 9D 8E 
     :  7B 50 5F 50 DD 8D BA AE E9 56 23 A2 EA A6 CC 59 
     :  0F 
178 33: INTEGER 
     :  00 D0 FF 72 69 60 EE B5 33 DF 83 DF 4A 63 3A D6 
     :  52 44 98 C1 23 2A 9F 11 07 FC 60 82 1C E6 09 E2 
     :  35 
213 33: INTEGER 
     :  00 8E F5 55 31 57 7C 8C 27 08 B5 37 70 C9 13 B4 
     :  52 35 94 E0 93 B3 D1 C9 F0 E4 17 C1 F1 C4 88 3B 
     :  5F 
248 33: INTEGER 
     :  00 8B 54 F6 F0 EB 49 CE 22 95 02 94 DC 42 27 39 
     :  8C 2D BB 2B 6C C7 14 B6 05 52 EB 01 68 99 5B EC 
     :  23 
283 33: INTEGER 
     :  00 AF 80 62 A4 FA 5B 0B 0C 5B 63 A7 E6 5F 5D 8B 
     :  E4 4F CE 10 D3 D5 07 46 C9 32 39 78 53 52 F8 6C 
     :  58 
     : } 

0 warnings, 0 errors. 
+0

jww, apprezzo l'aiuto, grazie mille, ha funzionato correttamente. –

+0

Grazie a @EstebanE. Potresti anche voler dare un'occhiata a [Come accetta una risposta?] (Https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). Così com'è, la tua domanda è ufficialmente senza risposta. – jww

+0

grazie ancora, ma per la mia mancanza di reputazione non posso votare la tua risposta. –

Problemi correlati