私が問題を抱えているこれよりも優れた、opensslを使用してファイルを単純に暗号化する良い例があれば、私は非常に感謝しています.
更新:著者の Myabe は正しかった。割り当てていないものに memset を使用すると、スタック以外の変数で strtok がチョークすることを思い出します。
Update2: malloc を使用して停止するコア ダンプを取得しました。コードを更新しました。コントロール H はまだ表示されています。これを反映するようにコードを更新します。
Update3:この例では、ループ構造が正しく表示されません。最初の読み取りのサイズよりも大きい後続の読み取りがどのように発生しているかはわかりません。
Update4:見つかったと思います。復号化ループには olen += tlen があり、バッファはそのビット セットを破棄する必要があります。:( そうじゃない。
Update99988: 私はここですべての希望をあきらめました。この例は捨てて、代わりに Openssl の本から何かを始める必要があると思います。中間層のバッファーを復号化すると、^H が前に追加されますが、ポインターが渡されるため、アライメントの問題が疑われ始めています。
私は、悪い例から始めることは、ゼロから始めるよりも悪いというボートに乗っているかもしれないと思います. 私はいくつかの修正を加えなければなりませんでした (オリジナルは以下のコードに注釈が付けられています)。元の作者には、アドレスを間違って渡すという問題がありました。著者が使用している 1024 と 1032 のさまざまなサイズのバッファに頭が混乱していますが、これは 8 ビット シードと連鎖暗号化呼び出しに関連していると思います。
(control Hs) でガベージ文字が取得され、復号化のようなコア ダンプがスタックを破損しています。私は暗号化とopensslにかなり慣れていないため、gdbにはあまり詳しくありません。
私はこれを単純化するためにあらゆる試みをしました
- gcc --version レポート 4.3.2
- SUSE 11 を開く
コンパイル.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
きれいな.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;
}