2

这是我通过参考其他用户从这里提出的堆栈溢出问题来使用的代码。但是当我尝试使用 PEM_write_PrivateKey() 函数将私钥写入文件时。它没有这样做。调用此函数后,控制台屏幕会自动关闭。并且 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;
 }
4

3 回答 3

3

我不确定这与您的问题有关,但我遇到了类似的问题,并在试图找出问题所在时最终出现在此页面上。所以我想我会分享我的发现,希望它会对某人有所帮助。我还在其他一些论坛上看到人们遇到了我遇到的同样问题。

问题:在使用 Visual Studio 2015 编译的应用程序上调用 PEM_write_PrivateKey 时,应用程序退出时没有任何错误代码。使用 VS2010 编译时,相同的应用程序和代码工作正常。

我首先发现微软在 VS2015 中对 FILE 句柄进行了一些重大更改。

FILE 封装 在以前的版本中,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。

于 2017-07-10T19:33:00.177 回答
2

使用 PEM_write_bio_RSAPrivateKey() 插入 PEM_write_PrivateKey() 将私钥写入文件

    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 );
于 2017-08-31T09:58:17.967 回答
0

也许是因为您从未调用过 SSL_library_init()。

此外,在程序退出之前,您的缓冲文件可能不会被刷新。在程序结束之前,您应该调用:

fflush(fpPri);
于 2013-07-14T07:30:40.273 回答