gpt4 book ai didi

c - 在 C 中读取和写入 rsa key 到 pem 文件

转载 作者:太空狗 更新时间:2023-10-29 16:33:51 26 4
gpt4 key购买 nike

我正在编写一个 C 程序来为 RSA 生成 key 并将它们写入一个文件,然后从中读取。作业要求我以 openssl 格式生成文件。所以,我选择了PEM。现在,我有以下创建文件的功能

rsa = RSA_new();
// These 3 keys are generated beforehand
rsa->e = e;
rsa->n = n;
rsa->d = d;

fp = fopen(pubkey_file, "w");
if(!PEM_write_RSAPublicKey(fp, rsa))
{
printf("\n%s\n", "Error writing public key");
}
fflush(fp);
fclose(fp);

fp = fopen(privkey_file, "w");
// pRsaKey = EVP_PKEY_new();
// EVP_PKEY_assign_RSA(pRsaKey, rsa);
if(!PEM_write_RSAPrivateKey(fp, rsa, NULL, 0, 0, NULL, NULL))
// if (!PEM_write_PrivateKey(fp, pRsaKey, NULL, NULL, 0, 0, NULL))
{
printf("\n%s\n", "Error writing private key");
}
fflush(fp);
fclose(fp);

这是读取文件的函数

rsa = RSA_new();
fp = fopen(pubkey_file, "r");
if(PEM_read_RSAPublicKey(fp, &rsa, NULL, NULL) == NULL)
{
printf("\n%s\n", "Error Reading public key");
return;
}

fclose(fp);
BN_bn2bin(rsa->n, (unsigned char *)modulus);
BN_bn2bin(rsa->e, (unsigned char *)exp);
printf("\n%s\n%s\n", exp, modulus);
RSA_free(rsa);

// pRsaKey = EVP_PKEY_new();
fp = fopen(privkey_file, "r");
if(fp)
// if((PEM_read_PrivateKey(fp, &pRsaKey, NULL, NULL)) == NULL)
if((PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL)) == NULL)
{
printf("\n%s\n", "Error Reading private key");
return;
}
// rsa = RSA_new();
// rsa = EVP_PKEY_get1_RSA(pRsaKey);
fclose(fp);

公钥按要求写入和读取,但provate key失败。我试过同时使用 rsa 和 evp(在上面的代码中有注释)来编写。但是,两者都失败了。我无法理解为什么会发生这种情况,也无法尝试找到调试此问题的位置。任何人都可以为此提供一些指示吗?

最佳答案

RSA key 是对称的,您可以将它们中的任何一个用作私钥或公钥,这只是您选择的问题(但 DSA key 不是对称的)。下面的程序生成两个 2048 位长的 RSA key ,然后将它们保存到文件中并将它们读回内存。这应该会让您知道如何去做。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

const char* pcszPassphrase = "open sezamee";

static void gen_callback(int iWhat, int inPrime, void* pParam);
static void init_openssl(void);
static void cleanup_openssl(void);
static int passwd_callback(char *pcszBuff,int size,int rwflag, void *pPass);
static EVP_PKEY* create_rsa_key(void);
static void handle_openssl_error(void);

int main(int argc, char **argv)
{
int iRet = EXIT_SUCCESS;
EVP_PKEY* pPrivKey = NULL;
EVP_PKEY* pPubKey = NULL;
FILE* pFile = NULL;
const EVP_CIPHER* pCipher = NULL;
init_openssl();

pPrivKey = create_rsa_key();
pPubKey = create_rsa_key();

if(pPrivKey && pPubKey)
{/* Save the keys */
if((pFile = fopen("privkey.pem","wt")) && (pCipher = EVP_aes_256_cbc()))
{

if(!PEM_write_PrivateKey(pFile,pPrivKey,pCipher,
(unsigned char*)pcszPassphrase,
(int)strlen(pcszPassphrase),NULL,NULL))
{
fprintf(stderr,"PEM_write_PrivateKey failed.\n");
handle_openssl_error();
iRet = EXIT_FAILURE;
}
fclose(pFile);
pFile = NULL;
if(iRet == EXIT_SUCCESS)
{
if((pFile = fopen("pubkey.pem","wt")) && PEM_write_PUBKEY(pFile,pPubKey))
fprintf(stderr,"Both keys saved.\n");
else
{
handle_openssl_error();
iRet = EXIT_FAILURE;
}
if(pFile)
{
fclose(pFile);
pFile = NULL;
}
}
}
else
{
fprintf(stderr,"Cannot create \"privkey.pem\".\n");
handle_openssl_error();
iRet = EXIT_FAILURE;
if(pFile)
{
fclose(pFile);
pFile = NULL;
}
}
if(iRet == EXIT_SUCCESS)
{/* Read the keys */
EVP_PKEY_free(pPrivKey);
pPrivKey = NULL;
EVP_PKEY_free(pPubKey);
pPubKey = NULL;

if((pFile = fopen("privkey.pem","rt")) &&
(pPrivKey = PEM_read_PrivateKey(pFile,NULL,passwd_callback,(void*)pcszPassphrase)))
{
fprintf(stderr,"Private key read.\n");
}
else
{
fprintf(stderr,"Cannot read \"privkey.pem\".\n");
handle_openssl_error();
iRet = EXIT_FAILURE;
}
if(pFile)
{
fclose(pFile);
pFile = NULL;
}

if((pFile = fopen("pubkey.pem","rt")) &&
(pPubKey = PEM_read_PUBKEY(pFile,NULL,NULL,NULL)))
{
fprintf(stderr,"Public key read.\n");
}
else
{
fprintf(stderr,"Cannot read \"pubkey.pem\".\n");
handle_openssl_error();
iRet = EXIT_FAILURE;
}
}
}

if(pPrivKey)
{
EVP_PKEY_free(pPrivKey);
pPrivKey = NULL;
}
if(pPubKey)
{
EVP_PKEY_free(pPubKey);
pPubKey = NULL;
}
cleanup_openssl();
return iRet;
}

EVP_PKEY* create_rsa_key(void)
{
RSA *pRSA = NULL;
EVP_PKEY* pKey = NULL;
pRSA = RSA_generate_key(2048,RSA_3,gen_callback,NULL);
pKey = EVP_PKEY_new();
if(pRSA && pKey && EVP_PKEY_assign_RSA(pKey,pRSA))
{
/* pKey owns pRSA from now */
if(RSA_check_key(pRSA) <= 0)
{
fprintf(stderr,"RSA_check_key failed.\n");
handle_openssl_error();
EVP_PKEY_free(pKey);
pKey = NULL;
}
}
else
{
handle_openssl_error();
if(pRSA)
{
RSA_free(pRSA);
pRSA = NULL;
}
if(pKey)
{
EVP_PKEY_free(pKey);
pKey = NULL;
}
}
return pKey;
}

void gen_callback(int iWhat, int inPrime, void* pParam)
{
char c='*';
switch(iWhat)
{
case 0: c = '.'; break;
case 1: c = '+'; break;
case 2: c = '*'; break;
case 3: c = '\n'; break;
}
fprintf(stderr,"%c",c);
}

int passwd_callback(char *pcszBuff,int size,int rwflag, void *pPass)
{
size_t unPass = strlen((char*)pPass);
if(unPass > (size_t)size)
unPass = (size_t)size;
memcpy(pcszBuff, pPass, unPass);
return (int)unPass;
}

void init_openssl(void)
{
if(SSL_library_init())
{
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
RAND_load_file("/dev/urandom", 1024);
}
else
exit(EXIT_FAILURE);
}

void cleanup_openssl(void)
{
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
ERR_remove_thread_state(0);
EVP_cleanup();
}

void handle_openssl_error(void)
{
ERR_print_errors_fp(stderr);
}

关于c - 在 C 中读取和写入 rsa key 到 pem 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12647220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com