OpenSSL RSA 加密返回乱码。 C++

OpenSSL RSA Encryption returning gibberish. C++

我是套接字编程的新手,所以请多关照:)

我正在用 C++ 编写客户端-服务器应用程序并使用 OpenSSL。到目前为止,我已经为客户端和服务器生成了 public-私钥,并通过网络交换了它。现在是我想使用服务器的 public 密钥加密客户端消息的部分。但是我的 public_encrypt 函数 returns 乱码。我知道我正在使用的方法已被弃用,并且有更好的方法,但目的只是弄脏手。

下面是调用加密的函数API。 (忽略 if 部分,它用于发送客户端 public 密钥)

#define RSA_SIZE 256
void sendMessage(int clientFD, uint16_t type, char *data, serverState *server){
uint16_t length = strlen(data);
unsigned char message[MESSAGE_SIZE];

if (server->state == 0)
{
    memcpy(message, (char *)&length, sizeof(length));
    memcpy(message + 2, (char *)&type, sizeof(type));
    memcpy(message + 4, data, length);
    send(clientFD, message, 4 + length, 0);
    server->state = 1;
}
else
{
    unsigned char encrypted[RSA_SIZE] = {0};
    length = public_encrypt(reinterpret_cast<unsigned char *>(data), length, server->key, encrypted);
    assert(length != -1);
    printf("%s\n", encrypted);

    memcpy(message, (char *)&length, sizeof(length));
    memcpy(message + 2, (char *)&type, sizeof(type));
    memcpy(message + 4, encrypted, length);
    send(clientFD, message, 4 + length, 0);
}}

这是加密的代码

int padding = RSA_PKCS1_OAEP_PADDING;

RSA *createRSA(unsigned char *key, int pub){
RSA *rsa = NULL;
BIO *keybio;
keybio = BIO_new_mem_buf(key, -1);
if (keybio == NULL)
{
    printf("Failed to create key BIO");
    return 0;
}
if (pub)
{
    rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
}
else
{
    rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
}
if (rsa == NULL)
{
    printf("Failed to create RSA");
}
return rsa;}

int public_encrypt(unsigned char *data, int data_len, unsigned char *key, unsigned char *encrypted){
    printf("Data:%s\n:", data);
    printf("Data Length:%d\n:", data_len);
    printf("Server's Key:\n%s\n:", key);

    RSA *rsa = createRSA(key, 1);
    int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);
    return result;}

请查看 link https://i.stack.imgur.com/WJn7e.png 以查看我的输出。 PS:很抱歉这么长post。

RSA 的输出是一个介于 0 和 RSA 私钥模数之间的随机值,编码为无符号大端八位字节串(八位字节串只是字节数组的另一个名称,char[] C / C++)。它包含具有任何值的字节,因此它肯定不是 ASCII。如果你想要 ASCII,你必须对密文进行 base 64 编码。

然而,密文通常是 "stringified" 根本没有充分的理由,所以只有在您的协议/系统有必要时才这样做。 Python 字符串在 Python 运行 时对您来说有些可读性。我不确定这是否是一件好事 - 复制该字符串当然不是一个好主意,因为它只是 Python 专有的。

C 不那么宽容,如果你把二进制数组当作文本你会 运行 惹麻烦,因为它可以包含任何字符,包括控制字符和 NUL 字符 (00 ), 它可以与 strlen 等函数一起玩得很开心,还有许多其他期望文本字符串而不是字节数组的函数(两者通常都基于 C/C++ 中的 char) .