c-找不到aes-128加密密钥



我找不到任何错误

我想做的事:

  • 从文件中读取关键字(来自常用词列表(
  • 尝试所有可能的密钥进行加密
  • 获取能够生成首选密文的密钥

备注:

  • 加密使用AES-128-CBC
  • 已读取的少于16个字符的密钥将填充"#"(十六进制:0x23(
  • wordList正确

这是我的代码:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
void pad(char *s,int length);
int strcicmp(char const *a, char const *b);
int main(){

int i;
char words[16],t;
FILE *key;
unsigned char outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
unsigned char iv[] = {0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x00,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11};
int outlen, tmplen;

EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
char inText[] = "This is a top secret.";
char cipherTextGiven[] = "764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2";
key = fopen("wordList.txt","r");

while(fgets(words,16, key)) {
i=strlen(words);
words[i-1]='';
i=strlen(words);
if(i<16){
pad(words,16);
}
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(),NULL, words, iv);
if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, inText, strlen(inText))){
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen)){
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
outlen += tmplen;
int i;
char* buf_str = (char*) malloc (2*outlen + 1);
char* buf_ptr = buf_str;
for(i=0;i<outlen;i++)
buf_ptr += sprintf(buf_ptr, "%02X", outbuf[i]);
*(buf_ptr + 1) = '';
printf("%sn",buf_str);
if(strcicmp(cipherTextGiven, buf_str) == 0){
printf("Key: %snwith corresponding cipher: ", words);
for(i=0; i < outlen; i++)
printf("%02x",outbuf[i]);
printf("n");
}
}
fclose(key);
return 1;
}
//provide padding function to key
void pad(char *s,int length){
int l;
l = strlen(s);
while(l<length){
s[l] = 0x23;
l++;
}
s[l] = ''; //add termination char for the array
}
int strcicmp(char const *a, char const *b){
for(;;a++,b++){
int d = tolower(*a) - tolower(*b);
if(d != 0 || !*a)
return d;
}
}

错误

char words[16]更改为char words[18]words中需要18个元素,因为您希望处理最多16个字符的键,因为fgets将读取一个键加上一个新行字符,并且缓冲区将在这之后包含一个null字符。

fgets(word,16, key)更改为fgets(word, sizeof word, key)fgets需要知道可用缓冲区的完整大小,包括换行符和终止空字符的空间,而不仅仅是您想要的关键字符的数量。

删除*(buf_ptr + 1) = '';。这是不必要的,因为sprintf写入一个终止空字符,并且它的正确位置是buf_ptr,而不是buf_ptr+1。因此,该语句的写入超出了为buf_str分配的空间。

错误代码

以下代码不会导致您所观察到的任何问题,但它可以写得更好。

main声明为int main(void)int main(int argc, char *argv[]),而不是int main()

不要编写s[l] = 0x23;,除非您需要编写一个使用与编译和执行它的C实现的字符集不同的字符集的程序。要将字符设置为"#",请使用s[l] = '#';

如果在sprintf(buf_ptr, "%02X", outbuf[i]);中,将%02X更改为%02x,则它将使用小写表示十六进制,并且可以使用标准strcmp将缓冲区与cipherTextGiven进行比较,而不需要自定义strcicmp函数。更好的是,当程序启动时,将cipherTextGiven从十六进制转换为原始二进制,并在测试候选密钥时,使用memcmp将原始二进制与计算的密文进行比较。

在此:

i=strlen(words);
words[i-1]='';
i=strlen(words);

将最后一行更改为i = i-1;,因为我们知道前一行将长度减少了一,所以我们可以直接设置长度,而无需再次调用strlen。许多程序员会把这些行写成类似于:

i = strlen(words);
words[--i] = '';

最新更新