c++ - openssl rc4命令行加密和实现rc4的cpp文件之间的区别

标签 c++ linux openssl rc4-cipher

我正在尝试使用我用 openssl/rc4 header 编写的 cpp 文件通过 RC4 加密文本文件,然后通过命令行解密以表明我的实现是正确的。

下面是我的文件终端命令,下面是cpp文件,还有我用的终端编译命令。

除了一些解释 RC4 密码如何工作的模糊 youtube 视频(我已经知道)之外,网上几乎没有任何关于此的信息。我在手册页中找不到任何内容来解释 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;
}

最佳答案

所以,这是你的代码的一个版本,添加了很多错误检查,修复了错误,还有一些奇怪的东西(当你只读还是写?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.

关于c++ - openssl rc4命令行加密和实现rc4的cpp文件之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55623247/

相关文章:

c++ - ? : operator on sprintf

c++ - C++11 中的泛型函数指针

java - 如何使用 EVP_Sign 函数计算签名

linux - 为 arm 编译 rtmpdump

php - curl 错误 (58) : unable to set private key file: '/var/www/work/xml/keys/client.pem' type PEM

c++ - 给定一个素数列表和一个因式分解模式,如何构造其素数分解与给定模式匹配的所有数字?

c++ - 创建返回 QList<int> 的函数

java - JSch 一次执行多个 linux 命令

python - nTop RRDalarm 配置

c++ - 在隐藏其输出的同时在 C++ 中执行 Linux shell 命令