Что делает libgcrypt иначе при вызове шифра aes128 с 256-битным ключом?
Это продолжение моего предыдущего вопроса ( расшифровка RSA).
Изменить: ответ ниже был ясным и кратким. Ниже я добавил пример кода, который помог мне проверить, что, по моему мнению, происходит. Я проверю сегодня и отправлю обратно. Клиентское приложение создает 256-битный ключ, но когда оно вызывает gcry_cipher_setkey, оно использует длину ключа, возвращенную из алгоритма. Поэтому я предполагаю, что setkey усекает 256-битный ключ до 128-битного. Достаточно легко проверить.
Я пытаюсь расшифровать файл, который был зашифрован с использованием libgcrypt с aes128 / cbc / no padding. Есть два разных приложения, которые выполняют шифрование, оба из которых я не могу контролировать. Один использует 128-битный ключ AES, а другой использует 256-битный ключ. В остальном все внутренние звонки одинаковы.
Редактировать: Вот код псевдо-шифрования: Редактировать 2: Исправлен порядок и добавлены комментарии для будущих пользователей:
#define AES_KEY_SIZE 32
char AESKey[AES_KEY_SIZE+1];
GenerateAESKey(AESKey);
Error = gcry_cipher_open(AesHandle, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
// this is always 128bits (16 bytes)
BlockLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES128);
// this should return 128bits (16 bytes)
KeyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES128);
Error = gcry_cipher_setiv(AesHandle, NULL, 0);
// AESKey is a 32byte (256bit) char array & KeyLength is 128bits (16bytes)
// so gcry_cipher_setkey only uses the first 'KeLength' bytes of 'AESKey'
// which in this case is the first 16 bytes of 'AESKey'
Error = gcry_cipher_setkey(*AesHandle, AESKey, KeyLength);
Error = gcry_cipher_encrypt(AesHandle, Encrypted, BlockLength, ToEncrypt, BlockLenth);
void GenerateAESKey( char * AESKey ) {
int i;
srand(time(NULL));
for ( i = 0; i < AES_KEY_SIZE; i++ ) {
AESKey[i] = (rand() % 93)+33;
}
AESKey[AES_KEY_SIZE] = '\0';
}
Так что в моем коде C# я делаю это прежде, чем начать расшифровывать:
var aesKey = DecryptAesKey(s);
if (aesKey.Length == 32)
{
var tempKey = new byte[16];
Buffer.BlockCopy(aesKey,0,tempKey,0,16);
aesKey = tempKey;
}
Я использую C# & Bouncycastle для расшифровки файлов. Я успешно расшифровал файлы, которые были зашифрованы с 128-битным ключом. Но не удается, когда ключ 256 бит. Ошибка означает, что вывод искажен.
Я проверил, что ключ AES правильно расшифровывается для обоих источников.
У меня вопрос, что Либгрипт делает по-другому, когда ключ 256 бит? Или это даже правильный путь, чтобы узнать, почему моя расшифровка терпит неудачу? Спасибо за любую информацию или направление вы можете указать мне.
Брайан
1 ответ
Я полагаю, у вас есть
- 2 разных ключа (128 и 256 бит)
- 2 разных источника зашифрованного текста (1:
AES128
2:AES256
И то и другое:CBC/No Padding
) - Может расшифровать 128 шифротекста
- Сбой с 256 (все искажено и ничего из открытого текста не расшифровано).
Основным отличием является длина ключа 128 или 256 бит. Он определяет количество повторений раундов преобразования, которые преобразуют входные данные. Вам, вероятно, никогда не понадобятся внутренние детали реализации. AES использует больше раундов с большими ключами. 10 для 128-битных ключей, 14 для 256-битных ключей.
Важной частью является то, что размер блока всегда 128 бит для 128 и 256 CBC AES.
И AES-128-CBC, и AES-256-CBC используют 128-битный IV.
Так что мое дикое предположение (не видя вашего кода AES256) заключается в том, что в вашем коде AES256 может быть ошибка где-то размера блока или IV.
Если вы просто установили ключ на 128AES с помощью этой функции, проверьте эту документацию
gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t h, const void *k, size_t l)
Длина l (в байтах) ключа k должна соответствовать требуемой длине алгоритма, установленного для этого контекста, или находиться в допустимом диапазоне для алгоритмов с переменным размером ключа. Функция проверяет это и возвращает ошибку, если есть проблема. Вызывающий всегда должен проверять наличие ошибок.
И вы обычно не хотите использовать CBC с NoPadding (если только ваш размер данных не кратен 16 байтам), но проблемы с заполнением искажают только последний 16-байтовый блок открытого текста.