简体   繁体   English

PEM_write_PrivateKey()函数未将RSA私钥存储在private.pem文件中

[英]PEM_write_PrivateKey() function is not storing the RSA private key in private.pem file

This is the code i am using by taking reference of stack overflow questions asked by other users from here . 这是我使用的代码,参考其他用户从这里询问的堆栈溢出问题。 But when i am trying to use PEM_write_PrivateKey() function to write the private keys into the file. 但是当我尝试使用PEM_write_PrivateKey()函数将私钥写入文件时。 It is not doing it. 它不是这样做的。 The console screen get closed automatically after this function call. 在此函数调用后,控制台屏幕将自动关闭。 And the private.pem file doesn't contains anything. 而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;
 }

I'm not exactly sure this is related to your issue but I encountered a similar problem and ended up on this page while trying to figure out what the problem could be. 我不确定这是否与您的问题有关,但我遇到了类似的问题,最终在此页面上试图弄清楚问题可能是什么。 So I thought I'd share my findings hoping it will help someone. 所以我想我会分享我的发现,希望能帮助别人。 I also saw on some other forums that people ran into the same issue I encountered. 我还在其他一些论坛上看到人们遇到了我遇到的同样问题。

The issue: The application exits without any error code when calling PEM_write_PrivateKey on an application compiled using Visual Studio 2015. The same application and code works fine when compiled with VS2010. 问题:在使用Visual Studio 2015编译的应用程序上调用PEM_write_PrivateKey时,应用程序退出时没有任何错误代码。使用VS2010编译时,相同的应用程序和代码工作正常。

I first discovered that Microsoft did some breaking changes to the FILE handle in VS2015. 我首先发现微软对VS2015中的FILE句柄做了一些重大修改。

FILE Encapsulation In previous versions, the FILE type was completely defined in , so it was possible for user code to reach into a FILE and modify its internals. FILE封装在以前的版本中,FILE类型已完全定义,因此用户代码可以访问FILE并修改其内部。 The stdio library has been changed to hide implementation details. stdio库已更改为隐藏实现详细信息。 As part of this, FILE as defined in is now an opaque type and its members are inaccessible from outside of the CRT itself. 作为其中的一部分,现在定义的FILE是一个不透明类型,其成员无法从CRT本身外部访问。 https://msdn.microsoft.com/en-us/library/bb531344%28v=vs.140%29.aspx?f=255&MSPPError=-2147217396 https://msdn.microsoft.com/en-us/library/bb531344%28v=vs.140%29.aspx?f=255&MSPPError=-2147217396

By debugging in OpenSSL I figured out that the handler "APPLINK_FSETMOD" was set to "unsupported". 通过在OpenSSL中调试,我发现处理程序“APPLINK_FSETMOD”设置为“不支持”。 This led me to read on the AppLink technology implemention in OpenSSL. 这让我了解了OpenSSL中的AppLink技术实现。

This led me to discover that the solution to my problem was to add the following code in my application. 这让我发现我的问题的解决方案是在我的应用程序中添加以下代码。

#include "openssl/applink.c" 

Important: You must put the include in one of the .exe source file because GetModuleHandle is passed NULL. 重要说明:您必须将include包含在.exe源文件之一中,因为GetModuleHandle传递为NULL。

use PEM_write_bio_RSAPrivateKey() insted of PEM_write_PrivateKey() for writing private key to a file 使用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 );

Perhaps it's because you never called SSL_library_init(). 也许是因为你从未调用过SSL_library_init()。

Also, your buffered file is probably not getting flushed before the program exits. 此外,您的缓冲文件可能在程序退出之前不会被刷新。 Before the end of the program you should call: 在程序结束之前,您应该致电:

fflush(fpPri);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM