【问题标题】:Unable to find aes-128-encryption key找不到 aes-128 加密密钥
【发布时间】:2020-03-07 20:13:04
【问题描述】:

我找不到任何错误..

我想做什么:

  • 从文件中读取密钥(从常用单词列表中)
  • 尝试所有可能的加密密钥
  • 获取能够生成首选密文的密钥

备注:

  • 加密使用 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]='\0';
        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) = '\0';

        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] = '\0'; //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;
    }

}

【问题讨论】:

  • 您的帖子没有说明问题,没有说明观察到的行为,没有说明预期的行为,也没有提供足够的信息来重现问题,尤其是“wordList. txt”或至少足以重现您看到的任何问题。当发布这样的问题时,您应该说明您的程序是否在没有输出的情况下终止、正在打印错误的输出、是否正在崩溃并显示错误消息、没有编译,或者其他什么,您应该说明您希望从工作程序中得到什么输出.
  • wordList: 10th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th a AAA AAAS Aarhus Aaron ...
  • 每个单词占一行
  • @EricPostpischil:您的评论是对的,但是回答如此低质量的问题会向 OP 发送错误信息。如果他得到了答案,他为什么要做得更好。您可以投票、近距离投票或至少等到 OP edits 发布帖子来改进它。

标签: c aes encryption-symmetric


【解决方案1】:

错误

char words[16] 更改为char words[18]words 中需要 18 个元素,因为您要处理最多 16 个字符的键,因为 fgets 将读取一个键和一个换行符,然后缓冲区将包含一个空字符。

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

删除*(buf_ptr + 1) = '\0';。这是不必要的,因为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]='\0';
i=strlen(words);

把最后一行改成i = i-1;,因为我们知道上一行将长度减一,所以我们可以直接设置长度,不用再次调用strlen。许多程序员会将这些行写成这样:

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

【讨论】:

  • OP 还需要更改 fgets 大小参数。
猜你喜欢
  • 2016-05-26
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多