使用 openssl 库手动查找加密密钥
Finding the encryption key manually using openssl library
我有一个可能的密码列表,其中一个用于加密“这是最高机密”。小于16字节的字需要用#号补齐。但不知何故我无法生成正确的密文。这里是这个问题的已知信息:
十六进制格式的密文:
764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2
十六进制格式的 IV:
aabbccddeeff00998877665544332211
我知道密码是“Syracuse########”,我在 linux 上尝试了 openssl 命令来解密它。
我的代码获取这个单词列表,然后创建 matchingresult.txt,其中包含可能的密码的所有密文。不知道哪里弄错了none这些密文是真的Used wordlist
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/evp.h>
void pad(char *s, int length);
int print_result(unsigned char *buf, char *s, int len, FILE *outFile, char *match);
int strcicmp(char const *a, char const *b);
int main(){
unsigned char match[] = "MATCH";
unsigned char noMATCH[] = "NO MATCH";
int i;
char words[16],t; // each word in dictionary
FILE *key, *outFile;
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};// given in the description of task 5
int outlen, tmplen;
int num;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
char inText[] = "This is a top secret."; //given in the decription of task 5
char cipherTextGiven[] = "764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2"; //given in the description of task 5
key = fopen("words.txt", "r"); //provided file by SEED Labs
if(remove("matchingResult.txt") == -1){ // the file contains result of each key
perror("Error deleting file");
}
outFile = fopen("matchingResult.txt","a+");
if(key<0 || outFile < 0){
perror("Cannot open file");
exit(1);
}
char pbuffer[1024];
while ( fgets(words,16,key)) // get each word from dictionary that suppose to be a key to encrypt
{
i=strlen(words);
words[i-1]='[=10=]'; // in the text editor it automatically adds null or end of file so we need to remove that
i=strlen(words);
if (i < 16){ // 16 because we use AES-128
// since the word has less than 16 characters (i.e. 128 bits), pound signs (#: hexadecimal value is 0x23)
// are appended to the end of the word to form a key of 128 bits
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=]';
if (strcicmp(cipherTextGiven, buf_str) == 0)
print_result(outbuf, words, outlen, outFile, match);
else
print_result(outbuf, words, outlen, outFile, noMATCH);
}
fclose(key);
fclose(outFile);
return 1;
}
// print result to output file matchresult.txt
int print_result(unsigned char *buf, char *s, int len, FILE *outFile, char *match){
int i,n,j,k;
char x='\n';
char space = ' ';
for ( j=0; j<strlen(s); j++){
fprintf(outFile,"%c",s[j]);
}
fprintf(outFile,"%c",space);
for ( i = 0 ; i<len; i++){
fprintf(outFile,"%02x", buf[i]);
}
fprintf(outFile, "%c", space);
for (k=0; k< strlen(match); k++){
fprintf(outFile,"%c", match[k]);
}
fprintf(outFile,"%c",x);
return(0);
}
// add padding to the key
void pad(char *s, int length){
int l;
l= strlen(s); // its length
while(l<length){
s[l] = '#'; // insert a pound sign
l++;
}
s[l] = '[=10=]'; // strings need to be terminated in a null
}
// compare case insensitive
int strcicmp(char const *a, char const *b){
for(;;a++,b++){
int d = tolower(*a) - tolower(*b);
if (d != 0 || !*a)
return d;
}
}
问题是由这部分代码引起的:
s[l] = '\0';
我有一个可能的密码列表,其中一个用于加密“这是最高机密”。小于16字节的字需要用#号补齐。但不知何故我无法生成正确的密文。这里是这个问题的已知信息:
十六进制格式的密文:
764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2
十六进制格式的 IV:
aabbccddeeff00998877665544332211
我知道密码是“Syracuse########”,我在 linux 上尝试了 openssl 命令来解密它。
我的代码获取这个单词列表,然后创建 matchingresult.txt,其中包含可能的密码的所有密文。不知道哪里弄错了none这些密文是真的Used wordlist
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/evp.h>
void pad(char *s, int length);
int print_result(unsigned char *buf, char *s, int len, FILE *outFile, char *match);
int strcicmp(char const *a, char const *b);
int main(){
unsigned char match[] = "MATCH";
unsigned char noMATCH[] = "NO MATCH";
int i;
char words[16],t; // each word in dictionary
FILE *key, *outFile;
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};// given in the description of task 5
int outlen, tmplen;
int num;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
char inText[] = "This is a top secret."; //given in the decription of task 5
char cipherTextGiven[] = "764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2"; //given in the description of task 5
key = fopen("words.txt", "r"); //provided file by SEED Labs
if(remove("matchingResult.txt") == -1){ // the file contains result of each key
perror("Error deleting file");
}
outFile = fopen("matchingResult.txt","a+");
if(key<0 || outFile < 0){
perror("Cannot open file");
exit(1);
}
char pbuffer[1024];
while ( fgets(words,16,key)) // get each word from dictionary that suppose to be a key to encrypt
{
i=strlen(words);
words[i-1]='[=10=]'; // in the text editor it automatically adds null or end of file so we need to remove that
i=strlen(words);
if (i < 16){ // 16 because we use AES-128
// since the word has less than 16 characters (i.e. 128 bits), pound signs (#: hexadecimal value is 0x23)
// are appended to the end of the word to form a key of 128 bits
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=]';
if (strcicmp(cipherTextGiven, buf_str) == 0)
print_result(outbuf, words, outlen, outFile, match);
else
print_result(outbuf, words, outlen, outFile, noMATCH);
}
fclose(key);
fclose(outFile);
return 1;
}
// print result to output file matchresult.txt
int print_result(unsigned char *buf, char *s, int len, FILE *outFile, char *match){
int i,n,j,k;
char x='\n';
char space = ' ';
for ( j=0; j<strlen(s); j++){
fprintf(outFile,"%c",s[j]);
}
fprintf(outFile,"%c",space);
for ( i = 0 ; i<len; i++){
fprintf(outFile,"%02x", buf[i]);
}
fprintf(outFile, "%c", space);
for (k=0; k< strlen(match); k++){
fprintf(outFile,"%c", match[k]);
}
fprintf(outFile,"%c",x);
return(0);
}
// add padding to the key
void pad(char *s, int length){
int l;
l= strlen(s); // its length
while(l<length){
s[l] = '#'; // insert a pound sign
l++;
}
s[l] = '[=10=]'; // strings need to be terminated in a null
}
// compare case insensitive
int strcicmp(char const *a, char const *b){
for(;;a++,b++){
int d = tolower(*a) - tolower(*b);
if (d != 0 || !*a)
return d;
}
}
问题是由这部分代码引起的: s[l] = '\0';