Шифрование OpenSSL RSA, возвращающее гиббери sh. C ++ - PullRequest
0 голосов
/ 15 апреля 2020

Я новичок в программировании сокетов, так что будьте добры:)

Я пишу клиент-серверное приложение на C ++ и использую OpenSSL. До сих пор я генерировал публичные c -приватные ключи для клиента и сервера и обменивал их по сети. Теперь это часть, где я хочу зашифровать сообщение моего клиента с помощью ключа сервера publi c. Но моя функция public_encrypt возвращает gibberi sh. Я знаю, что методы, которые я использую, устарели, и есть лучшие методы, но цель состоит в том, чтобы только испачкать руки.

Ниже приведена функция, которая вызывает API шифрования. (Игнорируйте часть if, это для отправки ключам publi c клиентов)

#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: простите за такой длинный пост.

1 Ответ

1 голос
/ 15 апреля 2020

Выход RSA - это случайное значение между 0 и модулем закрытого ключа RSA, закодированное как беззнаковая строка октета без знака (строка октетов - это просто другое имя байтового массива, char[] в C / C ++). Он содержит байты с любым значением, и поэтому, безусловно, не является ASCII. Если вы хотите ASCII, вам нужно зашифровать код зашифрованного текста 64.

Однако, довольно часто зашифрованный текст «строковый» вообще без веской причины, поэтому делайте это только в том случае, если это необходимо в вашем протоколе / системе. Строки Python делают вас более читабельными благодаря среде выполнения Python. Я не уверен, хорошо это или нет - копировать эту строку, конечно, не очень хорошая идея, поскольку она является Python проприетарной.

C не так уж простительно, если вы относитесь к В двоичном массиве в виде текста у вас возникнут проблемы, так как он может содержать любой символ, включая управляющие символы и символ NUL (00), которые могут играть в ад с такими функциями, как strlen и многими другими, которые ожидают текстовый строка вместо массива байтов (оба обычно основаны на char в C / C ++).

...