使用 openssl 河豚简单示例插入垃圾字符的帮助 [英] Assistance with openssl blowfish simple example inserting garbage characters

查看:12
本文介绍了使用 openssl 河豚简单示例插入垃圾字符的帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您有一个使用 openssl 加密文件的好例子,它比我遇到的问题更好,我将不胜感激.

If you have a good example of simply encrypting a file using openssl that is better than this one that I am having issues with I would be very grateful.

更新: Myabe 作者是正确的.在我没有分配的东西上使用 memset 让我想起了非堆栈变量上的 strtok choking.

Update: Myabe the author was correct. Using memset on something I did not allocate reminds me of strtok choking on non-stack variables.

Update2: 使用 malloc 停止核心转储.更新了代码.控制 Hs 仍然出现.更新代码以反映这一点.

Update2: Got the core dump to stop by using malloc. Updated the code. The control Hs are still appearing. Updating the code to reflect this.

Update3: 示例中的循环结构似乎不正确.我不确定后续读取如何大于初始读取的大小.

Update3: The looping structure does not appear correct in the example. I am unsure how subsequent reads are occuring greater than the size of the initial read.

Update4: 我想我找到了.解密循环有一个 olen += tlen 并且缓冲区应该丢弃那组位.:(不是它.

Update4: I think I found it. decrypt loop has a olen += tlen and the buffer should discard that set of bits. :( not it.

更新 99988:我已经放弃了这里的所有希望.我想我需要扔掉这个例子,而是从 Openssl 书中的一些东西开始.解密后,中间层缓冲区预先附加了 ^H,但由于传入了一个指针,我开始怀疑对齐问题.

Update99988: I have given up all hope here. I think I need to throw away this example and start with something from the Openssl book instead. Upon decrypting the middle layer buffers are preappended with ^H's but since a pointer is passed in I am beginning to suspect alignment issues.

我想我可能会从一个坏例子开始比从头开始更糟糕.我不得不进行一些更正(原始代码在下面的代码中进行了注释).原作者有一些错误传递地址的问题.我的想法被作者使用的不同大小的缓冲区 1024 和 1032 左右,但我认为这与 8 位种子和链式加密调用有关.

I think I may be in the boat of starting with a bad example is worse than starting from scratch. i had to make some corrections (the original is annotated in the code below). The original author had some issues with passing addresses incorrectly. My mind is being kicked around by the different sized buffers the author is using 1024 and 1032 but I think it is related to the 8 bit seed and chained encryption calls.

我在(控制 Hs)中收到垃圾字符,并且像解密这样的核心转储正在破坏堆栈.我对加密、openssl 还很陌生,而且我对 gdb 不太熟悉.

I am getting garbage characters in (control Hs) and a core dump like the decryption is corrupting the stack. I am fairly new to encryption, openssl, and I am not all that familiar with gdb.

我已尽一切努力简化这一点

I have made every attempt to simplify this down

  1. gcc --version 报告 4.3.2
  2. 打开 SUSE 11

compile.sh

gcc -g -o blowfish blowfish.c -lcrypto

run.sh

ulimit -c unlimited
./blowfish example.txt encrypted_example decrypted_example
echo diff example.txt decrypted_example
diff example.txt decrypted_example

clean.sh

rm -rf blowfish encrypted_example decrypted_example core

example.txt

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor 
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 
culpa qui officia deserunt mollit anim id est laborum.

Hydrogen H
Helium H
Lithium L
Beryllium B
Boron B
Carbon C
Nitrogen N
Oxygen O
Fluorine F
Neon N
Sodium N
Magnesium M
Aluminium A
Silicon S
Phosphorus P
Sulfur S
Chlorine C
Argon A
Potassium K
Calcium C
Scandium S
Titanium T
Vanadium V
Chromium C
Manganese M
Iron F
Cobalt C
Nickel N
Copper C
Zinc Z
Gallium G
Germanium G
Arsenic A
Selenium S
Bromine B
Krypton K
Rubidium R
Strontium S
Yttrium Y
Zirconium Z
Niobium N
Molybdenum M
Technetium T
Ruthenium R
Rhodium R
Palladium P
Silver A
Cadmium C
Indium I
Tin S
Antimony S
Tellurium T
Iodine I
Xenon X
Caesium C
Barium B
Lanthanum L
Cerium C
Praseodymium P
Neodymium N
Promethium P
Samarium S
Europium E
Gadolinium G
Terbium T
Dysprosium D
Holmium H
Erbium E
Thulium T
Ytterbium Y
Lutetium L
Hafnium H
Tantalum T
Tungsten W
Rhenium R
Osmium O
Iridium I
Platinum P
Gold A
Mercury H
Thallium T
Lead P
Bismuth B
Polonium P
Astatine A
Radon R
Francium F
Radium R
Actinium A
Thorium T
Protactinium P
Uranium U
Neptunium N
Plutonium P
Americium A
Curium C
Berkelium B
Californium C
Einsteinium E
Fermium F
Mendelevium M
Nobelium N
Lawrencium L
Rutherfordium R
Dubnium D
Seaborgium S
Bohrium B
Hassium H
Meitnerium M
Darmstadtium D
Roentgenium R
Ununbium U
Ununtrium U
Ununquadium U
Ununpentium U
Ununhexium U
Ununseptium U
Ununoctium U

错误代码警告错误代码使用来自所选答案的代码blowfish.c

#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define IP_SIZE 1024
#define OP_SIZE 1032
unsigned char key[16];
unsigned char iv[8];

int
generate_key ()
{
  int i, j, fd;
  if ((fd = open ("/dev/random", O_RDONLY)) == -1)
    perror ("open error");

  if ((read (fd, key, 16)) == -1)
    perror ("read key error");

  if ((read (fd, iv, 8)) == -1)
    perror ("read iv error");

  printf ("128 bit key:
");
  for (i = 0; i < 16; i++)
    printf ("%4d ", key[i]);

  printf ("
Initialization vector
");
  for (i = 0; i < 8; i++)
    printf ("%4d ", iv[i]);
  printf ("
");


  close (fd);
  return 0;
}

int
decrypt (int infd, int outfd)
{
  char *inbuff, *outbuf;
  int olen, tlen, n;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init (&ctx);
  EVP_DecryptInit (&ctx, EVP_bf_cbc (), key, iv);

  outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE );
  inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE );

  /* keep reading until a break */
  for (;;)
    {
      memset(inbuff,'', OP_SIZE);
      if ((n = read (infd, inbuff, OP_SIZE)) == -1)
    {
      perror ("read error");
      break;
    }
      else if (n == 0)
    break;

      memset(outbuf,'', IP_SIZE);

      if (EVP_DecryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1)
    {
      printf ("error in decrypt update
");
      return 0;
    }

      if (EVP_DecryptFinal (&ctx, outbuf + olen, &tlen) != 1)
    {
      printf ("error in decrypt final
");
      return 0;
    }
      olen += tlen;
      if ((n = write (outfd, outbuf, olen)) == -1)
    perror ("write error");
    }

  EVP_CIPHER_CTX_cleanup (&ctx);
  return 1;
}

int
encrypt (int infd, int outfd)
{
  char *inbuff, *outbuf;

  int olen, tlen, n;
  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init (&ctx);
  EVP_EncryptInit (&ctx, EVP_bf_cbc (), key, iv);

  outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE );
  inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE );

  for (;;)
    {
      memset(inbuff,'', IP_SIZE);

      if ((n = read (infd, inbuff, IP_SIZE)) == -1)
    {
      perror ("read error");
      break;
    }
      else if (n == 0)
    break;

      if (EVP_EncryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1)
    {
      printf ("error in encrypt update
");
      return 0;
    }

      if (EVP_EncryptFinal (&ctx, outbuf + olen, &tlen) != 1)
    {
      printf ("error in encrypt final
");
      return 0;
    }
      olen += tlen;
      if ((n = write (outfd, outbuf, olen)) == -1)
    perror ("write error");
    }
  EVP_CIPHER_CTX_cleanup (&ctx);
  return 1;
}

int
main (int argc, char *argv[])
{
  int flags1 = 0, flags2 = 0, outfd, infd, decfd;
  mode_t mode;
  char choice, temp;
  int done = 0, n, olen;

  memset(key,'', 16);
  memset(iv,'', 8);
  memset(&mode, '', sizeof(mode));

  flags1 = flags1 | O_RDONLY;
  flags2 = flags2 | O_RDONLY;
  flags2 = flags2 | O_WRONLY;
  flags2 = flags2 | O_CREAT;

  mode = mode | S_IRUSR;
  mode = mode | S_IWUSR;

  generate_key ();

  if ((infd = open (argv[1], flags1, mode)) == -1)
    perror ("open input file error");

  if ((outfd = open (argv[2], flags2, mode)) == -1)
    perror ("open output file error");

  encrypt (infd, outfd);

  close (infd);
  close (outfd);

  if ((outfd = open (argv[2], flags1, mode)) == -1)
    perror ("open output file error");

  if ((decfd = open (argv[3], flags2, mode)) == -1)
    perror ("open output file error");

  /* After much head scratching reusing the out as an in is correct here */
  decrypt (outfd, decfd);

  close (outfd);
  fsync (decfd);
  close (decfd);

  return 0;
}

推荐答案

错误在于调用 EVP_DecryptFinal 和 EVP_EncryptFinal 的方式.这些函数应该在 for 循环的最后被调用,最后一部分 olen 被添加到 tlen 并再次写入是复制输出.以下是最终的工作版本:

The error is in the way the EVP_DecryptFinal and EVP_EncryptFinal are called. These functions should be called in the end of the for cycle, also the final part where to olen is added tlen and written again was duplicating output. Below is the final working version:

#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define IP_SIZE 1024
#define OP_SIZE 1024 + EVP_MAX_BLOCK_LENGTH
unsigned char   key[16];
unsigned char   iv[8];

int
generate_key()
{
    int             i, fd;
    if ((fd = open("/dev/random", O_RDONLY)) == -1)
        perror("open error");

    if ((read(fd, key, 16)) == -1)
        perror("read key error");

    if ((read(fd, iv, 8)) == -1)
        perror("read iv error");

    printf("128 bit key:
");
    for (i = 0; i < 16; i++)
        printf("%4d ", key[i]);

    printf("
Initialization vector
");
    for (i = 0; i < 8; i++)
        printf("%4d ", iv[i]);
    printf("
");


    close(fd);
    return 0;
}

int
do_decrypt(int infd, int outfd)
{
    unsigned char           *inbuff, *outbuf;
    int             olen=0, tlen=0, n=0;
    EVP_CIPHER_CTX  ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_DecryptInit(&ctx, EVP_bf_cbc(), key, iv);

    outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
    inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);

    /* keep reading until a break */
    for (;;) {
        memset(inbuff, 0, IP_SIZE);
        if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
            perror("read error");
            break;
        } else if (n == 0)
            break;

        memset(outbuf, 0, OP_SIZE);

        if (EVP_DecryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
            printf("error in decrypt update
");
            return 0;
        }
        if ((n = write(outfd, outbuf, olen)) == -1)
            perror("write error");
    }

    tlen=0;
    if (EVP_DecryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
        perror("error in decrypt final");
        return 0;
    }

    if ((n = write(outfd, outbuf+olen, tlen)) == -1)
        perror("write error");

    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

int
do_encrypt(int infd, int outfd)
{
    unsigned char           *inbuff, *outbuf;

    int             olen=0, tlen=0, n=0;
    EVP_CIPHER_CTX  ctx;
    EVP_CIPHER_CTX_init(&ctx);
    EVP_EncryptInit(&ctx, EVP_bf_cbc(), key, iv);

    outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
    inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);

    for (;;) {
        memset(inbuff, 0, IP_SIZE);

        if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
            perror("read error");
            break;
        } else if (n == 0)
            break;

        if (EVP_EncryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
            printf("error in encrypt update
");
            return 0;
        }

        if ((n = write(outfd, outbuf, olen)) == -1)
            perror("write error");
    }
    tlen=0;
    if (EVP_EncryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
        printf("error in encrypt final
");
        return 0;
    }

    if ((n = write(outfd, outbuf+olen, tlen)) == -1)
        perror("write error");

    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

int
main(int argc, char *argv[])
{
    int             flags1 = 0, flags2 = 0, outfd, infd;
    mode_t          mode;

    memset(key, 0, 16);
    memset(iv, 0, 8);
    memset(&mode, 0, sizeof(mode));

    flags1 = flags1 | O_RDONLY;
    flags2 = flags2 | O_RDONLY;
    flags2 = flags2 | O_WRONLY;
    flags2 = flags2 | O_CREAT;

    mode = mode | S_IRUSR;
    mode = mode | S_IWUSR;


    generate_key();


    if ((infd = open(argv[1], flags1, mode)) == -1)
        perror("open input file error");

    if ((outfd = open(argv[2], flags2, mode)) == -1)
        perror("open output file error");

    do_encrypt(infd, outfd);

    close(infd);
    fsync(outfd);
    close(outfd);

    if ((infd = open(argv[2], flags1, mode)) == -1)
        perror("open output file error");

    if ((outfd = open(argv[3], flags2, mode)) == -1)
        perror("open output file error");

    do_decrypt(infd, outfd);

    close(infd);
    fsync(infd);
    close(outfd);

    return 0;
}

这篇关于使用 openssl 河豚简单示例插入垃圾字符的帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆