Вопрос или проблема
Я ищу способ расшифровать данные, зашифрованные с помощью RC4. Я пробовал openssl, но он не поддерживает длину ключа 64 бита (в моей версии есть только rc4 и rc4-40).
Зашифрованные данные:
6dec8a6b6356b36e1f4c1a94c8f6dd5ddfd60108da479d5b4a8794afa468c7e78cd22946d7
Ключ:
24641684
Ожидаемый открытый текст:
ThisIstheOriginaltext=theoriginaltext
Используя этот веб-сайт, я могу успешно расшифровать данные. Однако у меня возникают сложности с расшифровкой в Linux без использования веб-инструмента.
Как я могу расшифровать это в linux?
RC4? Это должно быть легко. Есть очень короткая версия на c, которая поддерживает любые ключи (в шестнадцатеричном кодировании). Просто скомпилируйте так:
$ gcc -o rc4 -O3 -std=c89 rc4.c
Этот код:
#define S ,t=s[i],s[i]=s[j],s[j]=t /* rc4 hexkey <file */
unsigned char k[256],s[256],i,j,t;main(c,v,e)char**v;{++v;while(++i)s[
i]=i;for(c=0;*(*v)++;k[c++]=e)sscanf((*v)++-1,"%2x",&e);while(j+=s[i]
+k[i%c]S,++i);for(j=0;c=~getchar();putchar(~c^s[t+=s[i]]))j+=s[++i]S;}
Использование:
$ rc4 hexkey < input > output
Беззастенчиво скопировано с этого сайта:
Если вам нужна/хочется длинная версия, [используйте это][adam2].
Эта версия более надежна, просто немного больше, так как это 2k файл кода на c.
[adam2]: http://www.cypherspace.org/rsa/rc4.html “ищите “Эквивалентный код на C””
Кажется, что утилита openssl
, которая входит в состав большинства дистрибутивов Linux, не была скомпилирована с поддержкой rc4-64
.
Что вы можете сделать, так это скачать последний исходный код с веб-сайта OpenSSL и скомпилировать его самостоятельно.
Утилита OpenSSL enc
поддерживает только rc4, который по умолчанию является 128-битным (EVP_rc4()
), и rc4-40 (EVP_rc4_40()
).
Первая поддерживает переменные размеры ключей (через EVP_CIPHER_CTX_set_key_length()
), но, похоже, enc
не поддерживает не стандартные размеры ключей и никогда не вызывает эту функцию установки длины. Мне не известен ни один инструмент CLI или модуль perl, который это поддерживает.
Вместо этого вы можете легко изменить пример RC2 80-битной функции do_crypt()
на странице man OpenSSL EVP_EncryptInit
, чтобы реализовать RC4-64 (или любой другой поддерживаемый размер):
// компилируйте с: gcc -lcrypto -o rc4-64 rc4-64.c
#include <stdio.h>
#include <openssl/ssl.h>
int main(int argc, char * argv[]) {
FILE *in,*out;
// шифрование
//in=fopen("rc4.in","r");
//out=fopen("rc4.out","w");
//do_crypt(in,out,1);
//fclose(in);
//fclose(out);
// расшифровка
in=fopen("rc4.out","r");
out=fopen("rc4.txt","w");
do_crypt(in,out,0);
fclose(in);
fclose(out);
}
int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
/* Позволяем достаточно места в выходном буфере для дополнительного блока */
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
EVP_CIPHER_CTX ctx;
/* Ложный ключ и IV: обычно мы бы устанавливали их из
* другого источника. */
//unsigned char key[] = "0123456789";
//unsigned char iv[] = "12345678";
unsigned char key[] = "24641684";
unsigned char iv[] = "\0\0\0\0\0\0\0\0";
/* Не устанавливайте ключ или IV, потому что мы изменим параметры */
EVP_CIPHER_CTX_init(&ctx);
/* установить RC4 с ключом 64 бита */
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, do_encrypt);
EVP_CIPHER_CTX_set_key_length(&ctx, 64/8)
/* Мы закончили изменять параметры, теперь мы можем установить ключ и IV */
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
for(;;) {
inlen = fread(inbuf, 1, 1024, in);
if(inlen <= 0) break;
if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) {
/* Ошибка */
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
}
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) {
/* Ошибка */
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
(Проверка ошибок и т.д. опущена для краткости и ясности – это не производственный код)
Ответ или решение
Чтобы расшифровать данные, зашифрованные с использованием алгоритма RC4 в Linux, вы можете воспользоваться несколькими подходами. В вашем случае, с учетом предоставленных данных о шифровании, самым подходящим решением будет использование самописного кода на C или модификация существующего решения, так как стандартные утилиты OpenSSL могут не поддерживать необходимые вам параметры.
Использование самописного решения на C
Мы можем использовать короткую версию кода на C, чтобы реализовать алгоритм RC4 с поддержкой ключей длиной до 64 бит. Приведенный ниже код создаст исполняемый файл, который сможет расшифровать ваши данные.
Шаги для компиляции и использования кода
- Скопируйте следующий код в файл, например,
rc4.c
:
#define S ,t=s[i],s[i]=s[j],s[j]=t /* rc4 hexkey <file */
unsigned char k[256],s[256],i,j,t;main(c,v,e)char**v;{++v;while(++i)s[
i]=i;for(c=0;*(*v)++;k[c++]=e)sscanf((*v)++-1,"%2x",&e);while(j+=s[i]
+k[i%c]S,++i);for(j=0;c=~getchar();putchar(~c^s[t+=s[i]]))j+=s[++i]S;}
-
Откройте терминал и перейдите в директорию, где находится ваш
rc4.c
. -
Скомпилируйте код с помощью следующей команды:
gcc -o rc4 -O3 -std=c89 rc4.c
- Создайте файл с зашифрованными данными, например,
encrypted_data.txt
, и вставьте в него ваши данные в шестнадцатеричном формате (без пробелов и новых строк):
6dec8a6b6356b36e1f4c1a94c8f6dd5ddfd60108da479d5b4a8794afa468c7e78cd22946d7
- Затем выполните расшифровку с помощью следующей команды, подставляя ваш ключ:
./rc4 24641684 < encrypted_data.txt > decrypted_output.txt
Файл decrypted_output.txt
будет содержать расшифрованный текст.
Альтернативный метод с использованием OpenSSL
Если вы предпочтете использовать OpenSSL, потребуется модифицировать библиотеку, чтобы поддерживать 64-битное шифрование. Ниже приведен более сложный метод, который включает в себя написание кода с использованием OpenSSL.
- Скачайте и установите исходный код OpenSSL с официального сайта.
- Создайте новый файл, например,
rc4-64.c
, и поместите в него следующий код (с модификациями для поддержки 64-битного ключа):
#include <stdio.h>
#include <openssl/ssl.h>
int do_crypt(FILE *in, FILE *out, int do_encrypt) {
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
EVP_CIPHER_CTX ctx;
unsigned char key[] = "24641684";
unsigned char iv[] = "\0\0\0\0\0\0\0\0";
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, do_encrypt);
EVP_CIPHER_CTX_set_key_length(&ctx, 64 / 8);
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
for (;;) {
inlen = fread(inbuf, 1, 1024, in);
if (inlen <= 0) break;
if (!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) {
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
}
if (!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) {
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
int main(int argc, char *argv[]) {
FILE *in, *out;
in = fopen("encrypted_data.txt", "r");
out = fopen("decrypted_output.txt", "w");
do_crypt(in, out, 0);
fclose(in);
fclose(out);
return 0;
}
- Компилируйте его с помощью:
gcc -lcrypto -o rc4-64 rc4-64.c
- Подготовьте файлы и запустите:
./rc4-64
Заключение
Оба подхода позволят вам успешно расшифровать данные, зашифрованные с использованием алгоритма RC4 с ключом длиной 64 бита. Ни один из предложенных вами методов не требует подключения к интернету или использования онлайн-сервисов, что обеспечивает безопасность работы. Выберите тот метод, который вам более удобен, и следуйте приведенным инструкциям для достижения своих целей.