gpt4 book ai didi

c - 协助 openssl blowfish 插入垃圾字符的简单示例

转载 作者:太空狗 更新时间:2023-10-29 15:21:05 30 4
gpt4 key购买 nike

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

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

更新 2: 使用 malloc 停止核心转储。更新了代码。对照 Hs 仍在出现。更新代码以反射(reflect)这一点。

更新 3: 示例中的循环结构不正确。我不确定后续读取如何发生大于初始读取的大小。

更新4:我想我找到了。 decrypt 循环有一个 olen += tlen,缓冲区应该丢弃那组位。 :( 不是。

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

我想我可能处于从一个坏榜样开始比从头开始更糟糕的境地。我不得不做一些更正(原文在下面的代码中有注释)。原作者在错误传递地址方面存在一些问题。作者使用 1024 和 1032 的不同大小的缓冲区让我很困惑,但我认为这与 8 位种子和链式加密调用有关。

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

我已尽一切努力将其简化

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

编译.sh

gcc -g -o blowfish blowfish.c -lcrypto

运行.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:\n");
for (i = 0; i < 16; i++)
printf ("%4d ", key[i]);

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


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,'\0', OP_SIZE);
if ((n = read (infd, inbuff, OP_SIZE)) == -1)
{
perror ("read error");
break;
}
else if (n == 0)
break;

memset(outbuf,'\0', IP_SIZE);

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

if (EVP_DecryptFinal (&ctx, outbuf + olen, &tlen) != 1)
{
printf ("error in decrypt final\n");
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,'\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\n");
return 0;
}

if (EVP_EncryptFinal (&ctx, outbuf + olen, &tlen) != 1)
{
printf ("error in encrypt final\n");
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,'\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");

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 并再次写入的最后部分是复制输出。下面是最终的工作版本:

#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:\n");
for (i = 0; i < 16; i++)
printf("%4d ", key[i]);

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


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\n");
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\n");
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\n");
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;
}

关于c - 协助 openssl blowfish 插入垃圾字符的简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/993780/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com