2013-06-20 35 views
1

這是我參考其他用戶從here詢問的堆棧溢出問題所使用的代碼。但是當我試圖使用PEM_write_PrivateKey()函數將私鑰寫入文件。它沒有這樣做。此功能調用後,控制檯屏幕會自動關閉。 private.pem文件不包含任何內容。PEM_write_PrivateKey()函數未將私鑰RSA保存在private.pem文件中

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <openssl/evp.h> 
#include <openssl/rsa.h> 
#include <openssl/bio.h> 
#include <openssl/pem.h> 
#include <openssl/objects.h> 
#include <openssl/err.h> 
#include <openssl/x509.h> 

int main() 
{ 

// 
// Local variables definition 
// 
EVP_PKEY_CTX *evp_ctx = NULL; 
EVP_PKEY  *ppkey  = NULL; 
FILE   *fpPri  = NULL; 
FILE   *fpPub  = NULL; 
int    retValue = 1; 

for (;;) 
{ 
    // 
    // Function allocates public key algorithm context using the algorithm 
    // specified by id 
    // 
    evp_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); 
    if (NULL == evp_ctx) 
    { 
     printf("RSA Public key algorithm context is not allocated\n"); 
     break; 
    } // if 
    printf("RSA Public key algoritm context allocated\n"); 

    // 
    // Function initializes a public key algorithm context using key pkey 
    // for a key genration operation 
    // 
    retValue = EVP_PKEY_keygen_init(evp_ctx); 
    if (1 != retValue) 
    { 
     printf("Initialization of public key alogorithm context failed\n"); 
     break; 
    } // if 
    printf("Public key alogorithm context initialized\n"); 

    // 
    // Setting RSA key bit to 2048 
    // 
    retValue = EVP_PKEY_CTX_set_rsa_keygen_bits(evp_ctx, 2048); 
    if (1 != retValue) 
    { 
     printf("RSA key bits not set to 2048\n"); 
     break; 
    } // if 
    printf("RSA key bits set to 2048\n"); 

    // 
    // Function performs a key generation operation 
    // 
    retValue = EVP_PKEY_keygen(evp_ctx, &ppkey); 
    if (1 != retValue) 
    { 
     printf("Key generation operation failed\n"); 
     break; 
    } // if 
    printf("Key generated successfully\n"); 

    // 
    // Creating a file to store RSA private key 
    // 
    fpPri = fopen("./private.pem", "w+"); 
    if (NULL == fpPri) 
    { 
     printf("File pointer of private.pem file is not opened\n"); 
     break; 
    } // if 
    printf("File pointer or private.pem file opened\n"); 

    retValue = PEM_write_PrivateKey(fpPri, ppkey, NULL, NULL, 0, 0, NULL); 
    if (1 != retValue) 
    { 
     printf("Private key is not written to file private.pem\n"); 
     break; 
    } // if 
    printf("Private key written to file private.pem\n"); 

    // 
    // Final break statement 
    // 
    break; 
} // for 

// 
// Releasing all the memory allocations and the handles 
// 

getchar(); 

return 0; 
} 
+0

insted的PEM_write_PrivateKey()是您使用的是Windows「控制檯上都會自動關閉」 ......?問題可能與您的代碼無關。 – Will

+0

是的。我在Visual Studio 2010上使用此代碼 – Ankit

+0

執行該函數後,調用PEM_write_PrivateKey()程序自動關閉。 – Ankit

回答

0

也許是因爲您從未調用SSL_library_init()。

另外,在程序退出之前,您的緩衝文件可能不會被刷新。節目結束之前,您應該撥打:

fflush(fpPri); 
+0

Ty @jcoffland進行回覆,在我的代碼中同時使用SSL_library_init();和fflush(fpPri);但仍遇到同樣的問題。 – Ankit

2

我不能完全肯定這是關係到你的問題,但我遇到了類似的問題,結束了該網頁,同時也試圖找出這個問題可能是什麼是。所以我想我會分享我的發現,希望它能幫助別人。我還在其他一些論壇上看到,人們遇到了我遇到的同樣的問題。

問題:退出應用程序沒有任何錯誤代碼時使用VS2010編譯時調用PEM_write_PrivateKey上使用Visual Studio 2015的同一應用程序和代碼編譯的應用程序工作正常。

我第一次發現微軟對VS2015中的FILE句柄做了一些改變。

FILE封裝在以前的版本,文件類型被完全限定 ,所以這是可能的用戶代碼,達到成 文件並修改它的內部。 stdio庫已更改爲 隱藏實施細節。作爲其中的一部分, 中定義的FILE現在是一種不透明類型,其成員從CRT本身之外的 不可訪問。 https://msdn.microsoft.com/en-us/library/bb531344%28v=vs.140%29.aspx?f=255&MSPPError=-2147217396

通過OpenSSL的調試我想通了,處理程序「APPLINK_FSETMOD」設置爲「不支持」。這讓我閱讀了OpenSSL中的AppLink技術實現。

這使我發現我的問題的解決方案是在我的應用程序中添加下面的代碼。

#include "openssl/applink.c" 

重要:必須把包括.exe文件的源文件之一,因爲的GetModuleHandle傳遞NULL。

1

使用PEM_write_bio_RSAPrivateKey()用於寫入的私鑰文件

BIO* pOut = BIO_new_file("key.pem", "w"); 
    if (!pOut) 
    { 
     return false; 
    } 
    /* Write the key to disk. */ 
    if(!PEM_write_bio_RSAPrivateKey(pOut, pRSA, NULL, NULL, 0, NULL, NULL)) 
    { 
     return false; 
    } 
    BIO_free_all(pOut); 
    /* Open the PEM file for writing the certificate to disk. */ 
    BIO * x509file = BIO_new_file("cer.pem", "w"); 
    if (!x509file) 
    { 
     return false; 
    } 
    if (!PEM_write_bio_X509(x509file, pX509Cert)) 
    { 
     return false; 
    } 
    BIO_free_all(x509file);