ghy*_*ur7 5 c++ encryption openssl rsa char
我试图在将私钥和公钥存储在字符向量上的同时加密和解密消息。我已经尝试过 d2i_PublicKey(...) 并在 EVP_set1_RSA(...) 中使用 EVP_PKEY 对象。我也不知道 EVP_set1_RSA(...) 中的所有参数是什么。请帮忙。这是我的代码:
#include <stdio.h>
//RSA
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <arpa/inet.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#define RSA_KEY_LENGTH 2048
#define PUB_EXP     3
#define PRINT_KEYS
//RSA
int main()
{
    printf("\ngenerating keys...\n");
    RSA *keypair = RSA_generate_key(RSA_KEY_LENGTH, PUB_EXP, NULL, NULL);
    // ---------
    printf("Converting Keys to char array..\n");
    char   *pri_key = NULL;           // Private key
    char   *pub_key = NULL;           // Public key
    size_t pri_len;            // Length of private key
    size_t pub_len;            // Length of public key
    BIO *pri = BIO_new(BIO_s_mem());
    BIO *pub = BIO_new(BIO_s_mem());
    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);
    pri_len = BIO_pending(pri);
    pub_len = BIO_pending(pub);
    pri_key = (char*)malloc(pri_len + 1);
    pub_key = (char*)malloc(pub_len + 1);
    BIO_read(pri, pri_key, pri_len);
    BIO_read(pub, pub_key, pub_len);
    pri_key[pri_len] = '\0';
    pub_key[pub_len] = '\0';
    // ---------
    char msg[RSA_KEY_LENGTH/8] = "HOLA, ESPERO QUE ME ENCRIPTES";
    char   *encrypt = NULL;    // Encrypted message
    char   *decrypt = NULL;    // Decrypted message
    printf("encrypting: %s\n", msg);
/*
* Here I want to obtain an RSA *PublicKey to use it for the encryption 
*/
    int encrypt_len;
    err = (char*)malloc(130);
    printf("++++\n");
    if((encrypt_len = RSA_public_encrypt(strlen(msg), (unsigned char*)msg, (unsigned char*)encrypt, PublicKey, RSA_PKCS1_OAEP_PADDING)) == -1) {
        printf("err++++\n");
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
    我在其他 Stack-Overflow 帖子中找到了此问题的解决方案,即此处:Reading Public/Private Key from Memory with OpenSSL
@SquareRootOfTwentyThree 回答了您正在寻找的答案,这是他的最后一行代码,
将公钥提取到名为 pub 的 BIO 变量中后:
PEM_write_bio_RSAPublicKey(pub, keypair);
创建一个 RSA 变量并将 pub 放入其中:
RSA *keypair2 = NULL; 
PEM_read_bio_RSAPublicKey( pub, &keypair2, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
完成此操作后,您可以像往常一样使用 keypair2 成功加密消息:
加密:
encrypt = (char*)malloc(RSA_size(keypair));
int encrypt_len;
err = (char*)malloc(130);
if((encrypt_len = RSA_public_encrypt(strlen(msg)+1, (unsigned char*)msg, (unsigned char*)encrypt,    keypair2   ,RSA_PKCS1_OAEP_PADDING)) == -1) {
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    fprintf(stderr, "Error encrypting message: %s\n", err);
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以像往常一样使用原始密钥对对其进行解密,而不必在第一次加密时使用它
解密:
decrypt = (char*)malloc(encrypt_len);
if(RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned char*)decrypt, keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    fprintf(stderr, "Error decrypting message: %s\n", err);
}
Run Code Online (Sandbox Code Playgroud)
如果您想通过网络传输“pub”变量,使用它来加密消息,然后将加密的数据发送回原始计算机以将其解密,这可能会有所帮助。
如果您确实想使用 char 变量,正如您在问题中所说,您当然可以使用 将内存作为原始数据复制到 char 变量(从 BIO 变量)memcpy,但不要忘记添加“\0”最后,这篇文章应该有所帮助:  将公钥和私钥与 RSA 密钥对变量分开