![](/img/trans.png)
[英]How to convert CNG key to OpenSSL EVP_PKEY (and vice versa)?
[英]How to send EVP_PKEY to other party?
目前我正在為 C++ 的 OpenSSL API 苦苦掙扎。 我正在使用 EVP 函數生成一個 RSA 密鑰對,然后用於加密用於加密數據(混合加密)的 AES 密鑰。
密鑰生成:
EVP_PKEY* keypair = NULL;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 4096);
EVP_PKEY_keygen(ctx, &keypair);
EVP_PKEY_CTX_free(ctx);
現在我有一個密鑰對。 通過 EVP_SealInit / EVP_SealUpdate / EVP_SealFinal 在我自己的機器上加密消息時沒有問題。 解密過程相同。 我只是將密鑰對作為 SealInit / OpenInit 函數的參數。
但是考慮到我想生成一個密鑰對並將公鑰或私鑰作為 char* 通過套接字發送給另一個人:我該怎么做?
我在 Internet 上找到的一種方法是使用 PEM_write_bio_PUBKEY 或 PEM_write_bio_PrivateKey 將密鑰轉換為 char*。 當嘗試它似乎工作。 但我仍然不是 100% 確定。 所以請查看我的代碼並告訴我這些功能是否可行:
unsigned char* publicKey;
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(bio, keypair);
RSAmakeString(&publicKey, bio);
unsigned char* privateKey;
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, keypair, NULL, NULL, 0, 0, NULL);
RSAmakeString(&privateKey, bio);
另一件事是如何將 char* 轉換回 EVP_PKEY*? 有什么功能嗎? 因為如果我想在另一台計算機上將 SealInit 與我的公鑰一起使用,我必須將它從 char* 轉換回 EVP_PKEY*,所以我可以在函數中使用它。 有什么建議?
但是考慮到我想生成一個密鑰對並將公鑰或私鑰作為 char* 通過套接字發送給另一個人:我該怎么做?
您需要一些用於序列化和有線格式或演示格式的東西。 您的公鑰和加密消息可能有0
字符,它們顯示為嵌入的NULL
。 因此,您需要同時擁有緩沖區和顯式長度。
使用 Google 的ProtocolBuffers 、 Binary JSON ,甚至 ASN.1/DER 編碼。 我認為 Google 的ProtocolBuffers
是面向消息的,因此在完整消息可用之前它們不會返回消息。
您也可以對它進行十六進制、Base32 或 Base64 編碼。 但是您仍然需要傳達一個長度,以便接收方知道他們收到了整個消息。 在本地 LAN 上,您可能永遠不會遇到問題。 在 Internet 上,您可能會偶爾遇到失敗,因為您有時會執行短讀操作。
您對PEM_write_bio_PUBKEY
想法PEM_write_bio_PUBKEY
是對PEM_write_bio_PUBKEY
進行 Base64 編碼,因此它遇到與 Hex、Base32 或 Base64 編碼相同的潛在問題。
我如何將 char* 轉換回 EVP_PKEY
好吧,根據上述更改,您可能不會使用char*
。 優化設計后,您可能應該提出一個新問題。
但是目前,如果您使用PEM_write_bio_PUBKEY
和PEM_write_bio_PrivateKey
保存了密鑰,那么您將分別使用PEM_read_bio_PUBKEY
或PEM_read_bio_PrivateKey
。 另請參閱 OpenSSL 的PEM
手冊頁。
與 C++ 相關,這里有一些使用 OpenSSL 時的技巧。 如果您使用的是 C++11,那么unique_ptr
確實可以輕松處理某些 OpenSSL 對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.