- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果您有一个使用 openssl 简单加密文件的好例子,并且比我遇到的问题更好,我将不胜感激。
更新:作者 Myabe 是正确的。在我没有分配的东西上使用 memset 让我想起了 strtok 对非堆栈变量的阻塞。
更新 2: 使用 malloc 停止核心转储。更新了代码。对照 Hs 仍在出现。更新代码以反射(reflect)这一点。
更新 3: 示例中的循环结构不正确。我不确定后续读取如何发生大于初始读取的大小。
更新4:我想我找到了。 decrypt 循环有一个 olen += tlen,缓冲区应该丢弃那组位。 :( 不是。
更新 99988:我已经放弃了这里的所有希望。我想我需要放弃这个例子,转而从 Openssl 书中的内容开始。解密中间层缓冲区时会预先附加 ^H,但由于传入了一个指针,我开始怀疑对齐问题。
我想我可能处于从一个坏榜样开始比从头开始更糟糕的境地。我不得不做一些更正(原文在下面的代码中有注释)。原作者在错误传递地址方面存在一些问题。作者使用 1024 和 1032 的不同大小的缓冲区让我很困惑,但我认为这与 8 位种子和链式加密调用有关。
我在 (control Hs) 中收到垃圾字符,并且像解密这样的核心转储正在破坏堆栈。我对加密、openssl 还很陌生,而且我对 gdb 也不是很熟悉。
我已尽一切努力将其简化
编译.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/
如果我使用open ssl命令 sudo openssl genrsa -out privkey.pem 2048 要生成rsa key ,它仅生成1个文件。这是私钥。我如何获得公钥。 最佳答案 回答
三个不同版本的 openssl 正在同时更新 openssl.org : 0.98, 1.0.0, 1.0.1?它们之间有什么区别,我该如何选择要使用的版本? 最佳答案 https://en.wiki
我有以下命令用于 OpenSSL 生成私钥和公钥: openssl genrsa –aes-128-cbc –out priv.pem –passout pass:[privateKeyPass] 2
我正在尝试使用对应的 gcc (arm-none-eabi-5_4-2016q2) 为 cortex m3 机器交叉编译 openssl。机器应该有能力做 TCP 请求,我们希望在一天结束时做 HTT
我正在尝试使用 openssl dsa 实现,但我对以下细节感到非常困惑: 命令 openssl dsa .... 的选项“-text”:输出中的十六进制数字,我是否正确地假设这些是字节,因此它们是按
我正在尝试制作一个假 CA 并用它签署一个证书以与 stunnel 一起使用(这似乎只是调用 OpenSSL 例程,因此您可能不需要了解该程序来提供帮助:)。然而,stunnel 一直拒绝我的证书,说
不幸的是,Perl 在尝试安装 OpenSSL 的手册页(例如 OpenSSL_1_0_1g)时不知何故遇到了错误。因为我不需要它们 - 我只想使用 OpenSSL 作为 C 库,我想我可以通过完全跳
OpenSSL 中的 BIO 对到底是什么?它的用途是什么?我已经检查过 OpenSSL 文档,但任何细节都很少。 最佳答案 OpenSSL 中的 BIO 类似于文件句柄。您可以使用一对它们来安全地相
openssl ca 和 openssl x509 命令有什么区别?我正在使用它来创建和签署我的 root-ca、intermed-ca 和客户端证书,但是 openssl ca 命令不会在证书上注册
如何(如果有的话)为 OpenSSL 定义一个单一的可信证书文件在 Windows(Win-7,OpenSSL 1.0.1c)上使用 SSL_CERT_FILE 环境变量? 各种研究促使我下载了 Mo
我有一个自签名证书,其中显示了列出的基本约束,但从中生成的签名请求不显示这些属性,例如 [v3_req]。我怎样才能让它可见?我正在使用 openssl 生成证书。 场景: 我使用以下方法创建自签名证
这个问题在这里已经有了答案: Check if a connection is TLSv1 vs SSLv3 (SSL_CIPHER_description/SSL_CIPHER_get_name)
是否有更简单的方法来确定在构建 openssl 期间指定的选项,例如当时是否定义了 OPENSSL_NO_SRTP? 我只能从以下方面获得有限的信息: openssl 版本 -a 命令。但是,如果我只
我们正在与 AWS Nitro 合作,仅提供 3 小时的证书。 我们正在寻找一种可以跳过验证中的过期部分并仍然确认证书链有效的方法。 最佳答案 根据 openssl-verify 文档
嗨,我如何在 Easyphp 中启用 openssl,因为我收到错误消息无法发送。Mailer 错误:缺少扩展:opensslTime:使用 phpmailer 时。谢谢 最佳答案 在您的 php.i
我正在尝试以编程方式读取 OpenSSL 警报消息,但无法找到执行此操作的方法。 OpenSSL API 提供如下功能: const char *SSL_alert_type_string(int v
我跑了openssl speed在我的 Ubuntu 计算机上。一些结果: Doing md4 for 3s on 16 size blocks: 9063888 md4's in 3.00s Doi
我编译了带有cryptodev支持(即硬件加速)的OpenSSL,但不幸的是默认引擎仍然是软件。 time openssl speed -evp aes-128-cbc -engine cryptod
我需要从 RedHat Linux 服务器连接到 Microsoft Dynamics CRM 服务器。地址是xxx.api.crm4.dynamics.com。服务器接受 TLSv1 但不接受 1.
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 上个月关闭。 Improve thi
我是一名优秀的程序员,十分优秀!