C - зашифровать и расшифровать строку с AES - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь понять, как использовать эту библиотеку c ( tiny-AES-c ). Как веб-разработчик, я ищу эквивалентный код C для этой скрипты JS .

Код JS прост:

// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123');


console.log("Encrypted: " + ciphertext.toString());

// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), 'secret key 123');
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log("Decrypted: " + plaintext);

Учитывая сообщение для шифрования и секрет, код генерирует зашифрованные данные и преобразовывает результаты в строку.


Мой код C:

int main()
{
    uint8_t in[]  = "my message";
    uint8_t key[] =  "secret key 123";

    struct AES_ctx ctx;

    AES_init_ctx(&ctx, key);
    printf("ORIG: %s",(char*) in);

    // Encrypt
    AES_ECB_encrypt(&ctx, in);
    printf("\nENC: %s",(char*) in);

    // Decrypt
    AES_ECB_decrypt(&ctx, in);
    printf("\nDEC: %s",(char*) in);

    return 0;
}

Выход:

ORIG: my message
ENC: ̤�+��5<n]EYK�ظ/����
DEC: my message%  

Я понимаю, что не должен пытаться печатать результат в виде строки, но не мог понять, как получить аналогичные (с JS) результаты, используя API tiny-AES-c Кроме того, когда я пытался использовать более длинные сообщения, я получал странные результаты, что наводило меня на мысль, что я использую эту библиотеку неправильно.

Q : Каким будет код C, эквивалентный вышеуказанному JS?

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Я являюсь первоначальным автором библиотеки AES, на которую вы ссылаетесь.

При использовании режимов работы ECB и CBC необходимо убедиться, что длина ключа, iv и блоков ввода / вывода составляет 16 байтов. Вам также необходимо решить, какую схему заполнения вы хотите использовать.

Вы можете использовать CTR-режим, чтобы избежать заполнения и перестать беспокоиться о размерах блоков. Как правило, это делает алгоритм AES намного проще в использовании, так как количество обработанных краев меньше.

Кстати, это также указано в проекте README:

Заполнение не предусмотрено, поэтому для CBC и ECB все буферы должны иметь кратные 16 байтов. Для прокладки рекомендуется PKCS7.

Режим ECB считается небезопасным для большинства применений и не реализован в потоковом режиме. Если вам нужен этот режим, вызывайте функцию для каждого блока из 16 байтов, который вам необходимо зашифровать. См. Статью Википедии о ЕЦБ для более подробной информации.

EDIT:

Если вы расширите свои массивы так, чтобы они были длиной 16 байт, и добавили их к нулю (или, наоборот, объявите их статическими, чтобы они автоматически инициализировались нулями), я думаю, это должно сработать для вас:)

0 голосов
/ 10 мая 2018

Как предложил @Morten Jensen, вы можете использовать IE в режиме CTR: AES_CTR_xcrypt_buffer

int main()
{
    uint8_t key[] = "secret key 123";
    uint8_t in[]  = "my message";
    uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };

    printf("Length: %lu",strlen((char*)in));

    struct AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);
    AES_CTR_xcrypt_buffer(&ctx, in, strlen((char*)in));
    printf("\nENC: %s",(char*) in); // don't use this string as an input

    AES_init_ctx_iv(&ctx, key, iv);
    AES_CTR_xcrypt_buffer(&ctx, in, strlen((char*)in));
    printf("\nDEC: %s",(char*) in);
    return 0;
}

Помните, что печать зашифрованных данных неверна, вы должны просмотреть выходные данные и преобразовать их в base64, если хотите соответствовать вашему примеру JS.

0 голосов
/ 09 мая 2018
uint8_t in[16]  = "my message";

ваш буфер должен быть кратным 16.

...