使用 OpenSSL 生成私钥
Generate private key with OpenSSL
我正在尝试使用 openssl 生成一个私有 RSA 密钥,到目前为止效果很好。我想在 PEM 中获取密钥的格式。将密钥写入文件时,格式似乎很好,但是当我将密钥保存在 PEM 中的字符数组中时,它似乎与写入文件的密钥不同!?下面是一个编译的简短示例:
#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::cout 的输出是:
-----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-----
在文件中写了这个结构:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }
而在pem_key
中,它仅存储PrivateKey
上述结构的一部分,因此:
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);
相关文章:
- 如何在openssl-ecc中获取十六进制格式的私钥
- 如何在C++中使用X509证书模在令牌中查找私钥
- 私钥解密代码使用公共接口说明符到 BSAFE 库 v6.0?
- 从字符串 Crypto++ 导入 RSA 公钥/私钥
- 将私钥和证书存储在C++/OpenSSL中
- 区块链超级账本私钥错误
- 博坦加载现有的 RSA 私钥
- C 从XML导入CAPI/CNG中的RSA私钥
- 使用密码将 RSA 私钥写入 PEM 文件
- 一代 RSA-2048 密钥(公钥和私钥)
- 如何获取PCCERT_CONTEXT私钥的NCRYPT_KEY_HANDLE?
- 将ECDSA Keypair的公共和私钥分开
- 使用 openssl libcrypto 解密具有 RSA 私钥的数据时RSA_NO_PADDING的使用
- OpenSSL AES_CFB128_ENCRYPT公共/私钥C
- 使用 OpenSSL 生成私钥
- 无法在 OpenSSL 中设置公钥/私钥
- 通过OpenSSL(c++)以XML(w3c)格式保存RSA公钥和私钥
- 如何使用openssl-lib-pem_read从字符串中读取公钥/私钥
- 将windows存储中的私钥转换为PEM(适用于OpenSSL)
- OpenSSL私钥读取错误(PEM_read_bio_RSAPPrivateKey)