C++ OpenSSL写入公钥到文件后读取不一致问题求助
用户代码如下:
// Put the public key inside a pem file ofstream file("temppubkey.pem"); file.close(); FILE * pemFile = fopen("temppubkey.pem", "w"); PEM_write_PUBKEY(pemFile, servTempPubKey); fclose(pemFile); // Retreive key from pem file as a test FILE * pem = fopen("temppubkey.pem", "r"); EVP_PKEY * key = EVP_PKEY_new(); PEM_read_PUBKEY(pem, &key, NULL, NULL); fclose(pem); // TEST cout << "Pub key:\n"; BIO_dump_fp(stdout, (const char *) servTempPubKey, tempKeySize); cout << "test key:\n"; BIO_dump_fp(stdout, (const char *) key, tempKeySize);
生成的PEM文件内容:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmHKT/jXk5CwCVheWcWE2
DrIHml4EsO/IQ5/sDdbrzakryB4YLmu+z90ShE5sYKixHq2oDrjnDbrTL2RYJSrC
xQmUOztztFXqvh6yWaKlA0la/ehsCQSW8o2OONu84d9Pr3ZgQz4gTdjIeKqF96qm
hhyLTrVA5qQD0aUgJRTxSbnESQBBvipdNFzGLT/I0kMK3lCbDfANDuhNL8iX8jp8
KNd6KqrOf3FfzYOII0uIvwVO0OCSm4rXCtIK2euskmCOEVYQZEbWgnzVf/Uos/9J
bIEDKFks9pcia7uAhlPA/2CZjClQjHde/PcCFq7hRKwn4okoiM5zB9wl688uL/iX
LQIDAQAB
-----END PUBLIC KEY-----
错误原因
核心问题是错误使用了BIO_dump_fp:servTempPubKey和key都是EVP_PKEY*类型的结构体指针,并非公钥的原始字节数组。直接将它们强制转换为const char*传入BIO_dump_fp,实际打印的是EVP_PKEY结构体本身的内存数据,而非公钥的实际内容。前16-32字节看似一致,只是因为结构体的前几个成员布局相同,后续内存结构差异导致内容不同。
正确测试方式
要验证两个公钥是否一致,需将它们序列化为相同格式(如PEM或DER)后再对比,而非直接dump结构体内存。修正后的测试代码如下:
// 输出原公钥的PEM格式 cout << "Pub key:\n"; BIO* bio1 = BIO_new_fp(stdout, BIO_NOCLOSE); PEM_write_bio_PUBKEY(bio1, servTempPubKey); BIO_free(bio1); // 输出读取后公钥的PEM格式 cout << "\ntest key:\n"; BIO* bio2 = BIO_new_fp(stdout, BIO_NOCLOSE); PEM_write_bio_PUBKEY(bio2, key); BIO_free(bio2);
这样输出的两份PEM内容若完全一致,说明写入和读取流程是正确的。
另外,代码开头的ofstream file("temppubkey.pem"); file.close();属于冗余操作,fopen以w模式打开时会自动创建或清空文件,可直接删除。
内容的提问来源于stack exchange,提问作者djolopez

