2017-01-23 134 views
1

我试图生成使用OpenSSL的私人RSA密钥,工作正常,到目前为止私钥。 我想获得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----- 

而从STD输出::法院是:

-----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从C++程序为您提供了所有四种RSA格式。这四种类型是{PEM,ASN.1/DER} x {公钥,主题公钥信息}的叉积。 * “公钥” *是一个以'BEGIN PRIVATE KEY'或'进行公众KEY',而* “主题的公共密钥信息” *是一个以'BEGIN RSA PRIVATE KEY'或'BEGIN RSA公共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

相关问题