【问题标题】:OpenSSL RSA Encryption returning gibberish. C++OpenSSL RSA 加密返回乱码。 C++
【发布时间】:2020-04-14 22:26:29
【问题描述】:

我是套接字编程的新手,所以请善待:)

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

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

#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;}

请查看链接https://i.stack.imgur.com/WJn7e.png 以查看我的输出。 PS:抱歉发了这么长的帖子。

【问题讨论】:

  • 定义“乱码”。你没想到密文是可读的,是吗?为什么不使用 TLS?
  • 当然,我希望密文是可读的。字符仍将是 ASCII 对吗?另外,我很确定我已经发现 Python 中的 RSA 加密更早可读。
  • 胡言乱语,我的意思是非 ASCII 字符。这个“乱码”字符串的解密出来是一个长度为0的字符串
  • 嗯?密文是加密的。意味着是一个无意义的字节序列。如果没有解密密钥,它不仅不可读,而且无法恢复。你的问题没有意义。而且,我再说一遍,你为什么不使用 TLS?
  • @user207421 我现在明白了。我应该打印单个字节以查看它是否至少被加密而不是字符串化版本。我只是在尝试我在网上找到的一种方法,因此不使用 TLS。

标签: c++ encryption openssl rsa


【解决方案1】:

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

然而,密文经常被“字符串化”,根本没有充分的理由,所以只有在你的协议/系统中有必要时才这样做。 Python 字符串通过 Python 运行时为您提供了一定程度的可读性。我不确定这是否是一件好事 - 复制该字符串肯定不是一个好主意,因为它只是 Python 专有的。

C 没有那么宽容,如果你把二进制数组当作文本,你会遇到麻烦,因为它可以包含任何字符,包括控制字符和 NUL 字符 (00),它可以玩得很开心函数,例如 strlen 和许多其他需要文本字符串而不是字节数组的函数(两者通常都基于 C/C++ 中的 char)。

【讨论】:

  • 我花了一段时间才感谢您的回答。 “可以和 strlen 玩得开心”这部分正是我遇到麻烦的地方。我在加密字符串上使用它。非常感谢。
  • 不客气。如果它解决了您的问题,请随时接受答案 - 始终是在 StackOverflow 上表示感谢的最佳方式:)
猜你喜欢
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
相关资源
最近更新 更多