我想根据我在perl中所做的事情在C中进行加密/解密程序。编译的perl程序是2MB,所以我想如果我用C编写它将是一个较小的可执行文件大小。
我的问题是,当我加密它时,我无法解密它。自从我上次使用C以来,这已经很久了,所以我忘记了很多东西。有人请赐教我这里做错了什么?感谢。
/*
============================================================================
Name : test-c.c
Description : Testing Project
Trying to do a C version of this perl code:
my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
my $enc_text = $cipher->encrypt_hex($text);
Requires : -lcrypt
References :
Function: cbc_crypt (char *key, char *blocks, unsigned len, unsigned mode, char *ivec)
GNU C Library: DES Encryption (http://www.gnu.org/software/libc/manual/html_node/DES-Encryption.html#DES-Encryption)
cbc_crypt (http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2012-10/msg00023.html)
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>
int main(void) {
char key[] = "aBcDeFg1";
char pass[] = "mypass1234test";
char encbuff[] = "87654321";
char decbuff[] = "87645321";
int buffsize;
int result;
des_setparity(key);
/* Encrypt pass, result is in encbuff */
buffsize = sizeof(pass);
/* Add to pass to ensure size is divisable by 8. */
while (buffsize % 8) {
pass[buffsize++] = '\0';
}
printf("Encrypted: ");
result = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, encbuff);
if (DES_FAILED(result) || strcmp(encbuff, "") == 0) {
if(strcmp(encbuff, "") == 0) {
printf("*** Null Output ***\n");
} else {
printf("*** Encryption Error ***\n");
}
} else {
printf("%s\n", encbuff);
}
/* Decrypt encbuff, result is in decbuff */
/* FIXME: Decryption doesn't work:
Encrypted: ,�7&���8
Decrypted: *** Decryption Error ***
*/
buffsize = sizeof(encbuff);
/* Add to pass to ensure size is divisable by 8. */
while (buffsize % 8) {
encbuff[buffsize++] = '\0';
}
printf("Decrypted: ");
result = cbc_crypt(key, encbuff, buffsize, DES_DECRYPT | DES_SW, decbuff);
if(DES_FAILED(result) || strcmp(decbuff, "") == 0) {
if(strcmp(encbuff, "") == 0) {
printf("*** Null Output ***\n");
} else {
printf("*** Decryption Error ***\n");
}
} else {
printf("%s\n", decbuff);
}
return 0;
}
答案 0 :(得分:0)
正如@Brian_Sidebotham所注意到的,使用char str[10];buffsize=sizeof(str);...str[buffsize++]='\0'
在c中并不是一件好事。超出数组末尾的写入可能会触发未定义的行为。它可能工作或提供错误的结果或由于分段错误而停止。所以要做的第一件事就是使用更大的缓冲区。例如:
char key[9];
sprintf(key,"12345678");
char password[420];
sprintf(password,"i am not going to write my password here.");
请注意,为\0
自动添加以构建有效c字符串的空终止字符sprintf()
留出一些位置是9而不是8。
此外,cbc_crypt()
的最后一个参数不是输出。它不是加密的字符串,而是链接的8字节初始化向量。这样,如果您需要加密多个字符串,它会阻止明文中的规则出现在密文中。由于要对密文进行解密,因此必须提供相同的初始化向量。加密就地执行:输入字符串pass
将被加密文本覆盖。
最后,请确保您的字符串足够大,因为加密文本似乎略大于明文。
以下代码可以使用。它由gcc main.c -o main
/*
============================================================================
Name : test-c.c
Description : Testing Project
Trying to do a C version of this perl code:
my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
my $enc_text = $cipher->encrypt_hex($text);
Requires : -lcrypt
References :
Function: cbc_crypt (char *key, char *blocks, unsigned len, unsigned mode, char *ivec)
GNU C Library: DES Encryption (http://www.gnu.org/software/libc/manual/html_node/DES-Encryption.html#DES-Encryption)
cbc_crypt (http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2012-10/msg00023.html)
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>
#define BUFFSIZE 420
int main(void) {
// char key[] = "aBcDeFg1";
char key[9];
sprintf(key,"aBcDeFg1");
//char pass[] = "mypass1234test";
char pass[BUFFSIZE];
sprintf(pass,"mypass1234test");
// char encbuff[] = "87654321";
char ivec[9];
sprintf(ivec,"87654321");
// char decbuff[] = "87645321";
char ivectemp[9];
strcpy(ivectemp,ivec);
int buffsize;
int result;
des_setparity(key);
/* Encrypt pass, result is in encbuff */
buffsize = strlen(pass);
printf("buffsize is %d\n",buffsize);
/* Add to pass to ensure size is divisable by 8. */
while (buffsize % 8 && buffsize<BUFFSIZE) {
pass[buffsize++] = '\0';
}
printf("pass is %s\n",pass);
printf("buffsize is %d\n",buffsize);
printf("Encrypted: ");
result = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, ivectemp);
if (DES_FAILED(result) || strcmp(pass, "") == 0) {
if(strcmp(pass, "") == 0) {
printf("*** Null Output ***\n");
} else {
printf("*** Encryption Error ***\n");
}
} else {
printf("%s\n", pass);
}
/* Decrypt encbuff, result is in decbuff */
/* FIXME: Decryption doesn't work:
Encrypted: ,�7&���8
Decrypted: *** Decryption Error ***
*/
buffsize = strlen(pass);
printf("buffsize is %d\n",buffsize);
/* Add to pass to ensure size is divisable by 8. */
while (buffsize % 8 && buffsize<BUFFSIZE) {
pass[buffsize++] = '\0';
}
printf("buffsize is %d\n",buffsize);
printf("Decrypted: ");
//keeping the same initialization vector for decrypting, encrypt has altered ivectemp
strcpy(ivectemp,ivec);
result = cbc_crypt(key, pass, buffsize, DES_DECRYPT | DES_SW, ivectemp);
if(DES_FAILED(result) || strcmp(pass, "") == 0) {
if(strcmp(pass, "") == 0) {
printf("*** Null Output ***\n");
} else {
printf("*** Decryption Error ***\n");
}
} else {
printf("%s\n",pass);
}
return 0;
}
现在......关于安全的几句话......根据wikipedia page about the Data Encryption Standard NBS DES:
现在认为DES对许多应用程序来说都是不安全的。这主要是由于56位密钥大小太小; 1999年1月,distributed.net和Electronic Frontier Foundation合作在22小时15分钟内公开破解DES密钥
例如,您可以通过openssl库切换到AES的实现。例如,请参阅How to do encryption using AES in Openssl或Simple AES encryption decryption with openssl library in C或AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) encryption/decryption with openssl C。