OpenSSL EVP API 数据类型,将已知密文与生成的密文进行比较
OpenSSL EVP API datatypes, comparing known ciphertext with generated ciphertext
免责声明:我正在 SEED 实验室做家庭作业;我不需要实施方面的帮助,但我想获得一些帮助,了解如何将 AES_128_CBC 生成的密文与我拥有的给定密文进行比较。
在此任务中,我们知道 AES 的密钥是使用 srand() 生成的,并且我们知道文件的创建时间 window。我计算了起始种子,所以我可以生成从起始种子到时间结束的所有密钥 window。
接下来需要做的就是使用 openSSL API 使用计算出的密钥和给定的初始化向量对明文执行 aes_128_cbc。
我在这里使用了来自 openSSL 的示例代码:Symmetric enrycption and decription 来执行 aes-128-cbc 算法。在我的代码中,我将已知的明文和密文以及 IV 初始化为无符号字符数组。问题是当我生成一个密文与我已知的密文进行比较时,我永远无法找到匹配项,我感觉这是因为我格式化输入的方式。
下面是我用来初始化明文、密文、IV、生成密钥和密文的代码:
void main(){
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
unsigned int i;
unsigned char key[7201][KEYSIZE];
unsigned char iv[] = "09080706050403020100A2B2C2D2E2F2";
unsigned char plaintext[] = "255044462D312E350A25D0D4C5D80A34";
unsigned char ciphertext[] = "D06BF9D0DAB8E8EF880660D2AF65AA82";
unsigned int startSeed = 1524020929;
unsigned char cipher[7201][128];
int cipher_len;
// 2 hours is 7200 seconds
//printf("Beginning keygen\n");
for(i = 0; i <= (7200); i++){
srand(i + startSeed);
//printf("Here\n");
for(int j = 0; j < KEYSIZE; j++){
//printf("Assigning key value\n");
key[i][j] = rand() % 256;
//printf("%.2x", (unsigned char)key[j]);
}
//printf("\n");
cipher_len = encrypt(plaintext, strlen((char *)plaintext), key[i], iv, cipher[i]);
//printf("%d\n", sizeof(cipher));
//BIO_dump_fp(stdout, (const char *)cipher, cipher_len);
if(memcmp(cipher[i], ciphertext, 128) == 0){
printf("found matching ciphertext");
}
}
}
我是否需要在比较之前将每个密码 [i] 转换为十六进制字符串?
编辑:
我写了一个 bash 脚本来尝试做同样的事情,看看我是否可以比较密文的 base64 编码,但没有成功。我对 bash 脚本编写非常缺乏经验,而且我仍然对我应该传递给加密的数据类型没有扎实的把握:
编辑 2:这是我用来生成起始种子的程序。实验室手册说 Alice 在“2018-04-17 23:08:49”创建了一个 pdf 文件。我使用日期命令 date -d "2018-04-17 23:08:49" +%s
来获取自开始纪元以来的秒数。这就是我用作起始种子的东西。实验室还指出,已知 Alice 在此开始时间和 2 小时后之间生成了密钥,这就是为什么我将种子范围的结束设置为 startSeed + 7200。
上次编辑:
更改后,我终于让它工作了。我这样做是为了在适当的时间生成种子 window,并且我这样做是为了让 AES 算法不添加填充。
另外,我只分配了16个字节给我的密文数组,并更改了memcmp只看16个字节。经过这些更改后,我能够重现已知的密文。
除了我为使用正确的种子范围和静态解码十六进制输入字符串所做的修复之外,我的实现中最糟糕的是将 16 字节长的字符数组与 128 字节长的字符数组进行比较.我将生成的密文字符数组更改为只有 16 个字节长,并且在 memcmp() 中一次只比较 16 个字节。
免责声明:我正在 SEED 实验室做家庭作业;我不需要实施方面的帮助,但我想获得一些帮助,了解如何将 AES_128_CBC 生成的密文与我拥有的给定密文进行比较。
在此任务中,我们知道 AES 的密钥是使用 srand() 生成的,并且我们知道文件的创建时间 window。我计算了起始种子,所以我可以生成从起始种子到时间结束的所有密钥 window。
接下来需要做的就是使用 openSSL API 使用计算出的密钥和给定的初始化向量对明文执行 aes_128_cbc。
我在这里使用了来自 openSSL 的示例代码:Symmetric enrycption and decription 来执行 aes-128-cbc 算法。在我的代码中,我将已知的明文和密文以及 IV 初始化为无符号字符数组。问题是当我生成一个密文与我已知的密文进行比较时,我永远无法找到匹配项,我感觉这是因为我格式化输入的方式。
下面是我用来初始化明文、密文、IV、生成密钥和密文的代码:
void main(){
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
unsigned int i;
unsigned char key[7201][KEYSIZE];
unsigned char iv[] = "09080706050403020100A2B2C2D2E2F2";
unsigned char plaintext[] = "255044462D312E350A25D0D4C5D80A34";
unsigned char ciphertext[] = "D06BF9D0DAB8E8EF880660D2AF65AA82";
unsigned int startSeed = 1524020929;
unsigned char cipher[7201][128];
int cipher_len;
// 2 hours is 7200 seconds
//printf("Beginning keygen\n");
for(i = 0; i <= (7200); i++){
srand(i + startSeed);
//printf("Here\n");
for(int j = 0; j < KEYSIZE; j++){
//printf("Assigning key value\n");
key[i][j] = rand() % 256;
//printf("%.2x", (unsigned char)key[j]);
}
//printf("\n");
cipher_len = encrypt(plaintext, strlen((char *)plaintext), key[i], iv, cipher[i]);
//printf("%d\n", sizeof(cipher));
//BIO_dump_fp(stdout, (const char *)cipher, cipher_len);
if(memcmp(cipher[i], ciphertext, 128) == 0){
printf("found matching ciphertext");
}
}
}
我是否需要在比较之前将每个密码 [i] 转换为十六进制字符串?
编辑: 我写了一个 bash 脚本来尝试做同样的事情,看看我是否可以比较密文的 base64 编码,但没有成功。我对 bash 脚本编写非常缺乏经验,而且我仍然对我应该传递给加密的数据类型没有扎实的把握:
编辑 2:这是我用来生成起始种子的程序。实验室手册说 Alice 在“2018-04-17 23:08:49”创建了一个 pdf 文件。我使用日期命令 date -d "2018-04-17 23:08:49" +%s
来获取自开始纪元以来的秒数。这就是我用作起始种子的东西。实验室还指出,已知 Alice 在此开始时间和 2 小时后之间生成了密钥,这就是为什么我将种子范围的结束设置为 startSeed + 7200。
上次编辑: 更改后,我终于让它工作了。我这样做是为了在适当的时间生成种子 window,并且我这样做是为了让 AES 算法不添加填充。
另外,我只分配了16个字节给我的密文数组,并更改了memcmp只看16个字节。经过这些更改后,我能够重现已知的密文。
除了我为使用正确的种子范围和静态解码十六进制输入字符串所做的修复之外,我的实现中最糟糕的是将 16 字节长的字符数组与 128 字节长的字符数组进行比较.我将生成的密文字符数组更改为只有 16 个字节长,并且在 memcmp() 中一次只比较 16 个字节。