2017-01-23 18 views
1

Я пытаюсь сгенерировать закрытый ключ RSA с openssl, который работает до сих пор. Я хотел бы получить формат ключа в PEM. При записи ключа в файл формат кажется прекрасным, но когда я сохраняю ключ в PEM в массиве символов, он кажется отличным от того, который был записан в файл !? Вот краткий пример компилируется с:Создайте закрытый ключ с OpenSSL

#include <iomanip> 
#include <string> 
#include <string.h> 
#include <iostream> 
#include <openssl/pem.h> 
#include <openssl/x509.h> 

int main() { 
    EVP_PKEY *pkey = EVP_PKEY_new(); 
    if (!pkey) { 
     return 0; 
    } 

    RSA *rsa = RSA_generate_key(2048, 3, NULL, NULL); 
    if (!EVP_PKEY_assign_RSA(pkey, rsa)) { 
     return 0; 
    } 

    BIO *bio = BIO_new(BIO_s_mem()); 
    PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL); 

    int pem_pkey_size = BIO_pending(bio); 
    char *pem_pkey = (char*) calloc((pem_pkey_size)+1, 1); 
    BIO_read(bio, pem_pkey, pem_pkey_size); 


    FILE *pkey_file = fopen("key.pem", "wb"); 
    if (!pkey_file) { 
     std::cerr << "Unable to open \"key.pem\" for writing." << std::endl; 
     return false; 
    } 

    bool ret = PEM_write_PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL); 
    fclose(pkey_file); 

    if(!ret) { 
     std::cerr << "Unable to write private key to disk." << std::endl; 
     return false; 
    } 


    std::cout << pem_pkey << std::endl; 

    return 0; 
} 

Собран с

g++ -std=c++11 test.cpp -o test -lssl -lcrypto 

Но печатный ключ и один сохраняется в файл не совпадает !?

В результате в файле выглядит следующим образом

-----BEGIN PRIVATE KEY----- 
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCpV8dtaMtTy3AO 
Oa+yKuZVHATDScyNtuqIdVuQlF5iJfIWLgZK2gKykNdVCVIdFcPpaPF6NmNvmCSM 
YyLdCuTZXFyEXM61uOvBcCDazUCZsSsFgt31bh9qvuxZufSRuHoEFgOiE9CgESyF 
KgM1h0UugwHfDyE6UA1+Vbm4Oh4+pgqK5n+gYXxn4Cj8jsKDfF5A1MBV1fCnHnrX 
c/1Tpr5pG4dBY2E1MgMA27MbRxxdkNeFCXM41uR4ncSGhaovI2bgUwIm4WyLLco/ 
xzR/D6pfiTuzlROGXfdTt+36NXCsj9BhKw59spxlZCrASRMVyAYguCctdJw2yaGB 
kTiu3gndAgEDAoIBAHDlL55F3OKHoAl7ynbHRDi9WIIxMwkknFr457W4PuwZTA7J 
WYc8Acxgj44GNr4OgpubS6bO7PUQGF2XbJNcmJDoPa2TNHkl8oD1azyI1bvLcgOs 
k/j0FPHUnZEmowvQUVgOrRa34Gq2Ha4cAiOvg3RXVpS0wNGKs6mOe9AmvtRtm31t 
APTEdYUnsvUPRXGqysxDn8GvAO1aQReKu5TI6866z2mRWUxwRw8ly/fBIhwHB/n6 
78Pzo5V0tf9DKkyCNXvk+qgOp3Kv+vkcdBAqfGXmO+OFBirePTxgiYfbjMCQ3PXf 
RCU8s3/DsV5jBIPZKSpeZVwK2VObFfyLgcSRVxMCgYEA3j39bvIvd91CWkS4dhoC 
KlWlEV/+ml+4i4pwEeySiimyHUHEW0w5wGXQArPu25nOUnKP1l3TJSf1eeN6nlRU 
rTeirobgfnAeYbemVCO8TZNIh9RxsoE1GdOZKoJ0RTv+b+LT9oYiYxJKN2BHjxM4 
SHcSu97eAkiWzB5dAqpLiusCgYEAwxDFjz8LVELiQkg/ZD76A7jKP1NQ1ONejamz 
0gfm0olRMuFE//ZP2ARS/nO2jZm3+RuBNTUWSfB5OaQmTGgLaW7Y26Pq8u8HcBJ2 
MkMTojNnWgnb18TbgaWN9Sv32E+4FQ2IMb+1LBN0aVJs/TzJ/+oX00SGU/DKNGhi 
8124fFcCgYEAlClTn0wfpT4sPC3QTrwBcY5uC5VUZup7B7GgC/MMXBvME4EtkjLR 
Ku6KrHf0kmaJjExf5D6Mw2/4++z8aY2NyM/Bya9AVEq+68/EOBfS3mIwWo2hIat4 
u+JmHFb4Lif+9UHipFlsQgwxekAvtLd62voMfT8+rDBkiBQ+AcbdB0cCgYEAggsu 
X39c4tdBgYV/mCn8Ansxf4zgjezps8Z34VqZ4bDgzJYt//mKkALh/vfPCRElUL0A 
ziNkMUr7e8LEMvAHm587PRfx90oE9WGkIYINFszvkVvn5S3nq8Oz+Mf6kDUlY15a 
y9Ujcrei8OGd/iiGqpwP4i2u4qCGzZrsoj56/Y8CgYBeht5y3wey/ZsDXXd5MXwW 
TWmhEQWbifn/P4rmydnVtYVJMaWdFPiPc9U4JFtkxKlxmtihy+0O/rTYUfiv6dzZ 
kJApv+H1r2S6Hx7a8DFkug8DKFcfVZC3UYdYoirQ2IvOVMK+hD8vnNDXefRk31UJ 
+us47+a7yXn3T5m8cSqm7g== 
-----END PRIVATE KEY----- 

, тогда как выход из станд :: соиЬ является:

-----BEGIN RSA PRIVATE KEY----- 
MIIEogIBAAKCAQEAqVfHbWjLU8twDjmvsirmVRwEw0nMjbbqiHVbkJReYiXyFi4G 
StoCspDXVQlSHRXD6WjxejZjb5gkjGMi3Qrk2VxchFzOtbjrwXAg2s1AmbErBYLd 
9W4far7sWbn0kbh6BBYDohPQoBEshSoDNYdFLoMB3w8hOlANflW5uDoePqYKiuZ/ 
oGF8Z+Ao/I7Cg3xeQNTAVdXwpx5613P9U6a+aRuHQWNhNTIDANuzG0ccXZDXhQlz 
ONbkeJ3EhoWqLyNm4FMCJuFsiy3KP8c0fw+qX4k7s5UThl33U7ft+jVwrI/QYSsO 
fbKcZWQqwEkTFcgGILgnLXScNsmhgZE4rt4J3QIBAwKCAQBw5S+eRdzih6AJe8p2 
x0Q4vViCMTMJJJxa+Oe1uD7sGUwOyVmHPAHMYI+OBja+DoKbm0umzuz1EBhdl2yT 
XJiQ6D2tkzR5JfKA9Ws8iNW7y3IDrJP49BTx1J2RJqML0FFYDq0Wt+Bqth2uHAIj 
r4N0V1aUtMDRirOpjnvQJr7UbZt9bQD0xHWFJ7L1D0VxqsrMQ5/BrwDtWkEXiruU 
yOvOus9pkVlMcEcPJcv3wSIcBwf5+u/D86OVdLX/QypMgjV75PqoDqdyr/r5HHQQ 
Knxl5jvjhQYq3j08YImH24zAkNz130QlPLN/w7FeYwSD2SkqXmVcCtlTmxX8i4HE 
kVcTAoGBAN49/W7yL3fdQlpEuHYaAipVpRFf/ppfuIuKcBHskoopsh1BxFtMOcBl 
0AKz7tuZzlJyj9Zd0yUn9Xnjep5UVK03oq6G4H5wHmG3plQjvE2TSIfUcbKBNRnT 
mSqCdEU7/m/i0/aGImMSSjdgR48TOEh3Erve3gJIlsweXQKqS4rrAoGBAMMQxY8/ 
C1RC4kJIP2Q++gO4yj9TUNTjXo2ps9IH5tKJUTLhRP/2T9gEUv5zto2Zt/kbgTU1 
FknweTmkJkxoC2lu2Nuj6vLvB3ASdjJDE6IzZ1oJ29fE24GljfUr99hPuBUNiDG/ 
tSwTdGlSbP08yf/qF9NEhlPwyjRoYvNduHxXAoGBAJQpU59MH6U+LDwt0E68AXGO 
bguVVGbqewexoAvzDFwbzBOBLZIy0Sruiqx39JJmiYxMX+Q+jMNv+Pvs/GmNjcjP 
wcmvQFRKvuvPxDgX0t5iMFqNoSGreLviZhxW+C4n/vVB4qRZbEIMMXpAL7S3etr6 
DH0/PqwwZIgUPgHG3QdHAoGBAIILLl9/XOLXQYGFf5gp/AJ7MX+M4I3s6bPGd+Fa 
meGw4MyWLf/5ipAC4f73zwkRJVC9AM4jZDFK+3vCxDLwB5ufOz0X8fdKBPVhpCGC 
DRbM75Fb5+Ut56vDs/jH+pA1JWNeWsvVI3K3ovDhnf4ohqqcD+ItruKghs2a7KI+ 
ev2PAoGAXobect8Hsv2bA113eTF8Fk1poREFm4n5/z+K5snZ1bWFSTGlnRT4j3PV 
OCRbZMSpcZrYocvtDv602FH4r+nc2ZCQKb/h9a9kuh8e2vAxZLoPAyhXH1WQt1GH 
WKIq0NiLzlTCvoQ/L5zQ13n0ZN9VCfrrOO/mu8l590+ZvHEqpu4= 
-----END RSA PRIVATE KEY----- 
+0

Как вы можете сказать? Вы пишете в двоичный файл. – pSoLT

+0

Название указанного дубликата не делает ничего очевидным, но dup предоставляет все четыре формата RSA для вас из программы на C++. Эти четыре типа являются перекрестными произведениями {PEM, ASN.1/DER} x {Public Key, Subject Public Key Info}. * «Открытый ключ» * - это «BEGIN PRIVATE KEY» или «BEGIN PUBLIC KEY», а * «Subject Public Key Info» * - это «BEGIN RSA PRIVATE KEY» или «BEGIN RSA PUBLIC KEY». Здесь также обсуждался * ad nauseam *. – jww

ответ

2

В файле записывается эта структура:

PrivateKeyInfo ::= SEQUENCE { 
    version     Version, 
    privateKeyAlgorithm  PrivateKeyAlgorithmIdentifier, 
    privateKey    PrivateKey, 
    attributes   [0] IMPLICIT Attributes OPTIONAL } 

в то время как в pem_key хранится только PrivateKey часть от вышеупомянутой структуры utre, таким образом:

RSAPrivateKey ::= SEQUENCE { 
     version   Version, 
     modulus   INTEGER, -- n 
     publicExponent INTEGER, -- e 
     privateExponent INTEGER, -- d 
     prime1   INTEGER, -- p 
     prime2   INTEGER, -- q 
     exponent1   INTEGER, -- d mod (p-1) 
     exponent2   INTEGER, -- d mod (q-1) 
     coefficient  INTEGER, -- (inverse of q) mod p 
     otherPrimeInfos OtherPrimeInfos OPTIONAL 
    } 

Если вы хотите сохранить первую структуру, то вам нужно сохранить EVP_PKEY *pkey. Назовите что-то вроде этого:

PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, 0, NULL); 
+0

Вот что я искал, thx! – wasp256