Разница между шифрованием командной строки openssl rc4 и файлом cpp, реализующим rc4 - PullRequest
1 голос
/ 11 апреля 2019

Я работаю над попыткой зашифровать текстовый файл через RC4 с помощью файла cpp, который я написал с заголовками openssl / rc4, а затем расшифровать с помощью командной строки, чтобы показать, что моя реализация верна.

MyКоманда терминала для файла приведена ниже, а файл cpp - под ним вместе с командой компиляции терминала, которую я использовал для нее.

Едва ли есть какая-либо информация об этом где-либо онлайн, за пределами какого-то расплывчатого youtubeвидео, которые объясняют, как работает шифр RC4 (который я уже знаю).Я не могу найти что-либо на страницах руководства, чтобы объяснить детали реализации openssl.

Любые указатели на то, почему мой файл cpp не расшифровывается до исходного содержимого, будут очень благодарны.Я рву свои волосы здесь, пытаясь понять это.Заранее спасибо.

(и да, я понимаю, что есть уязвимости, которые делают RC4 менее подходящим вариантом, но сейчас я просто хочу понять, как они работают)

шифрование командной строки:

openssl rc4-40 -k PASSword123 -in /home/chris/Desktop/test.txt -out /home/chris/Desktop/ssloutput.txt -p -nosalt

cpp файл:

g++ rc4.cpp -o rc4 -lssl -lcrypto

cpp файл:

#include <openssl/rc4.h>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd = open("/home/chris/Desktop/ssloutput.txt", O_RDWR);
    unsigned char keygen[12] = "PASSword123";
    RC4_KEY key;

    struct stat st;
    fstat(fd, &st);
    int size = st.st_size;

    unsigned char* fileIn;
    fileIn = (unsigned char*) calloc(size, sizeof(char));
    pread(fd, fileIn, size, 0);
    unsigned char *fileOut = (unsigned char*)malloc(size);

    RC4_set_key(&key, 16, keygen);
    RC4(&key, size, fileIn, fileOut);
    close(fd);

    int fd2 = open("/home/chris/Desktop/rc4output.txt", O_RDWR | O_CREAT);
    pwrite(fd2, fileOut, size, 0);
    close(fd2);

    free(fileIn);
    free(fileOut);

    return 0;
}

1 Ответ

1 голос
/ 11 апреля 2019

Итак, вот версия вашего кода с множеством добавленных проверок ошибок, исправленными ошибками, странными вещами (Использование O_RDWR с open(), когда вы только читаете или пишете? pread()? pwrite()?) очищен и использует EVP_BytesToKey(), как опция -k для openssl rc4 использования (Это был ключевой (хе) фактор):

#include <fcntl.h>
#include <openssl/evp.h>
#include <openssl/rc4.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
  int fd = open("ssloutput.txt", O_RDONLY);
  if (fd < 0) {
    perror("open ssloutput.txt");
    return 1;
  }

  struct stat st;
  if (fstat(fd, &st) < 0) {
    perror("fstat");
    return 1;
  }
  size_t size = st.st_size;

  unsigned char *fileIn = calloc(size, 1);
  if (!fileIn) {
    perror("calloc");
    return 1;
  }
  if (read(fd, fileIn, size) != (ssize_t)size) {
    perror("read");
    return 1;
  }
  close(fd);

  unsigned char *fileOut = malloc(size);
  if (!fileOut) {
    perror("malloc");
    return 1;
  }

  // Prepare the key according to the same rules as openssl rc4 -k foo
  char keygen[] = "PASSword123";
  RC4_KEY key;
  unsigned char computed_key[16];
  if (EVP_BytesToKey(EVP_rc4(), EVP_sha256(), NULL,
                     (const unsigned char *)keygen, strlen(keygen), 1,
                     computed_key, NULL) != 16) {

    fputs("Error calculating rc4 key!\n", stderr);
    return 1;
  }
  // Should match the one printed out by openssl rc4 -p
  fputs("key=", stdout);
  for (size_t n = 0; n < sizeof computed_key; n += 1) {
    printf("%02hhx", computed_key[n]);
  }
  putchar('\n');

  RC4_set_key(&key, sizeof computed_key, computed_key);
  RC4(&key, size, fileIn, fileOut);

  int fd2 = open("rc4output.txt", O_WRONLY | O_TRUNC | O_CREAT, 0644);
  if (fd2 < 0) {
    perror("open rc4output.txt");
    return 1;
  }
  if (write(fd2, fileOut, size) != (ssize_t)size) {
    perror("write");
    return 1;
  }
  close(fd2);

  free(fileIn);
  free(fileOut);

  return 0;
}

Демонстрация:

$ cat input.txt
the quick brown dog jumped over the lazy red fox.
$ gcc -o myrc4 -O -Wall -Wextra myrc4.c -lcrypto
$ openssl rc4 -k PASSword123 -md sha256 -p -nosalt -in input.txt -out ssloutput.txt
key=B554C1D224D8EF1738ED4EE238317463
$ ./myrc4
key=B554C1D224D8EF1738ED4EE238317463
$ cat rc4output.txt
the quick brown dog jumped over the lazy red fox.
...