无法找到 aes-128 加密密钥
Unable to find aes-128-encryption key
我找不到任何错误..
我想做的事情:
- 从文件中读取关键字(来自常用词列表)
- 尝试所有可能的加密密钥
- 获得一个能够产生首选密文的密钥
备注:
- 加密使用 AES-128-CBC
- 已读取少于16个字符的密钥将用"#"(hex: 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]='[=10=]';
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) = '[=10=]';
printf("%s\n",buf_str);
if(strcicmp(cipherTextGiven, buf_str) == 0){
printf("Key: %s\nwith 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] = '[=10=]'; //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
将读取一个键加上一个换行符,之后缓冲区将包含一个空字符。
将 fgets(word,16, key)
更改为 fgets(word, sizeof word, key)
。 fgets
需要知道可用缓冲区的完整大小,包括 space 换行符和终止空字符,而不仅仅是您想要的关键字符数。
删除*(buf_ptr + 1) = '[=19=]';
。这是不必要的,因为 sprintf
写入了一个终止空字符,而且它的正确位置是 buf_ptr
,而不是 buf_ptr+1
。所以这条语句写的超出了分配给 buf_str
.
的 space
错误代码
以下代码不会导致您观察到的任何问题,但可以编写得更好。
将 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]='[=10=]';
i=strlen(words);
把最后一行改成i = i-1;
,因为我们知道上一行把长度减了一个,所以可以直接设置长度,不用再调用strlen
。许多程序员会像这样写这些行:
i = strlen(words);
words[--i] = '[=11=]';
我找不到任何错误..
我想做的事情:
- 从文件中读取关键字(来自常用词列表)
- 尝试所有可能的加密密钥
- 获得一个能够产生首选密文的密钥
备注:
- 加密使用 AES-128-CBC
- 已读取少于16个字符的密钥将用"#"(hex: 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]='[=10=]';
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) = '[=10=]';
printf("%s\n",buf_str);
if(strcicmp(cipherTextGiven, buf_str) == 0){
printf("Key: %s\nwith 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] = '[=10=]'; //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
将读取一个键加上一个换行符,之后缓冲区将包含一个空字符。
将 fgets(word,16, key)
更改为 fgets(word, sizeof word, key)
。 fgets
需要知道可用缓冲区的完整大小,包括 space 换行符和终止空字符,而不仅仅是您想要的关键字符数。
删除*(buf_ptr + 1) = '[=19=]';
。这是不必要的,因为 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]='[=10=]';
i=strlen(words);
把最后一行改成i = i-1;
,因为我们知道上一行把长度减了一个,所以可以直接设置长度,不用再调用strlen
。许多程序员会像这样写这些行:
i = strlen(words);
words[--i] = '[=11=]';