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
) .
我是套接字编程的新手,所以请多关照:)
我正在用 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
) .