Как ключ DES генерируется из ключевой фразы в C?
(Не путать с генерацией подраздела алгоритма DES)
(редактировать: больше примеров)
Объяснение проблемы:
Я делаю это как часть школьного задания, где мне нужно перекодировать части OpenSSL в C, особенно те, которые относятся к криптосистемам PKI. До сих пор я с нуля перекодировал основной алгоритм DES ecb
, cbc
, 3des-ecb
, а также 3des-cbc
режимы работы. Другие части проекта включают MD5 и SHA256. Эта часть проекта фокусируется на генерации, манипулировании и использовании ключей RSA.
Часть манипуляции ключом RSA включает в себя шифрование заданного ключа парольной фразой.
(не с чистым key
+ initial vector
один, как я делал раньше с DES)
Это требует преобразования пользовательской парольной фразы в ключ DES (и необязательный дополнительный IV при необходимости), а затем использовать его для шифрования ключа RSA. Я знаю, что общим термином для функции, которую я ищу, является PBKDF, или Функция получения ключа на основе пароля. Однако я не смог (через поиск man
страницы OpenSSL или Google), чтобы узнать, какие именно функции (или функции) используются в OpenSSL для получения ключей.
Демонстрация генерации ключей DES с шифрованием ключей RSA:
Выполнение следующей команды без ключевой фразы создает незашифрованный ключ RSA example_plain_key
,
ssh-keygen -t rsa -f example_plain_key
Затем выполнение следующих команд зашифрует example_plain_key
с des
шифровать ecb
Режим. Каждая команда выводит зашифрованную версию в новый файл, поэтому она не меняет оригинал. Используйте одну и ту же фразу-пароль для обеих команд (например,пароль).
openssl rsa -DES-ECB -in id_rsa -out id_rsa_1
openssl rsa -DES-ECB -in id_rsa -out id_rsa_2
Ты можешь использовать head id_rsa
а также head id_rsa_1
чтобы увидеть, как шифрование ключа меняет заголовок. Если сравнить два новых ключа с
diff id_rsa_1 id_rsa_2
они будут идентичны в заголовке и форматировании, но сам ключ будет зашифрован по-разному, даже если используется одна и та же ключевая фраза. Разница в том, что генерация ключа (я считаю) генерирует новую случайную соль каждый раз, когда она запускается. Я бы предположил, что алгоритм хеширования и количество итераций будут одинаковыми. Кроме того, в отличие от /etc/shadow
на Unix-машинах соль не хранится рядом с ключом (или, по крайней мере, я не знаю, как ее прочитать).
Демонстрация генерации ключа DES из пароля:
Более конкретный пример DES:
openssl des -P
Выполнение вышеуказанной команды любое количество раз с одним и тем же паролем всегда приводит к другому ключу и iv, вероятно, потому что соль отличается.
Мои выводы и вычтенные предположения:
- Поиск "как шифруются ключи rsa?" Дает много результатов об использовании ключей RSA для шифрования. (иногда я ожидаю слишком многого от Google NLP)
- Поиск "как ключи DES генерируются из ключевой фразы?" Дает много результатов о том, как сгенерировать 16 раундов подразделов des.
Я просмотрел исходники OpenSSL без удачи. Я сделаю исчерпывающий поиск, если это абсолютно необходимо, но код не самый читаемый или доступный для поиска.
- страница man perl
- Ссылка, я думаю, будет более полезной, чем была
(Примечание: у меня нет учетной записи в OpenSSL, но я не думаю, что это потребуется для просмотра)
Самые полезные результаты привели меня к мысли, что пример прототипа того, что я ищу, будет выглядеть примерно так:
#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
// #include <something_else_maybe.h>
int main(void)
{
int num_iterations = 1000;
char *salt;
char *passphrase;
char *key;
passphrase = getpass("Password: ");
salt = get_some_random_bytes(8); // assumed arbitrary length
// the function in question
key = example_pbkdf(md5_function, num_iterations, salt, 8, passphrase, strlen(passphrase));
printf("Key (in hexadecimal or otherwise) is: %s\n", key);
free(key);
free(passphrase);
free(salt);
return (0);
}
Вещи, которые я специально ищу:
(Знание, где искать эти ответы, будет более ценным, чем сами ответы, но вся помощь приветствуется. Хотя мне нужен заголовок / source / prototype / etc в C).
- Функция (если она существует), которая работает так, как показано выше. Это не должно быть идеальное совпадение, я больше беспокоюсь о том, что он делает, а не о точном прототипировании или использовании.
- В качестве альтернативы (если он не существует) "рецепт" или последовательность операций, которые можно было бы обобщить как "алгоритм", который я ищу.
- Генерация ключей DES. (хотя включение нескольких шифров, скажем, AES, тоже круто)
- Как соль хранится в зашифрованном ключе RSA, если он есть (и если нет, то как его восстановить). Я знаю, что IV хранится в заголовке ключа, зашифрованного с помощью шифра в CBC.
1 ответ
Я нашел ответ на этот вопрос на бирже стека безопасности.
Спасибо, Grant Sanders, ваша ссылка на источник функции помогла мне указать источник функции (которую я планировал разобрать и идентифицировать), но оказалось, что фактический процесс намного проще. Даже если PBKDF
по определению имеет ряд итераций и переменных хеш-функций, реализация OpenSSL просто использует одну итерацию MD5 с паролем и необработанной солью (возможно, жестко закодированную).
Я написал быстрый скрипт, который доказывает ответ выше (по крайней мере для DES) здесь.