Search code examples
copensslhexaescbc-mode

OpenSSL EVP API datatypes, comparing known ciphertext with generated ciphertext


Disclaimer: I am working on a SEED lab for homework; I don't need help with the implementation, but I would like to get some assistance on how to compare generated ciphertexts from AES_128_CBC with the given ciphertext I have.

In this task, we know that a key for AES was generated with srand(), and we know what time window the file was created. I computed the starting seed, so I can generate all keys from the starting seed until the end of the time window.

Next all that needs to be done is use the openSSL API to perform aes_128_cbc on the plaintext with the computed key and given initialization vector.

I used example code from openSSL here: Symmetric enrycption and decription to perform the aes-128-cbc algorithm. In my code I have initialized the known plaintext and ciphertext and IV as unsigned char arrays. The problem is when I generate a ciphertext to compare with my known ciphertext, I can never get a match, and I have a feeling it is because of the way I have formatted the input.

Below is the code I am using to initialize the plaintext, ciphertext, IV, generate the keys and ciphertext:

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");
        
        }
    }
  }

Do I need to convert each cipher[i] to a hex string before comparison?

Edit: I wrote a bash script to try to do the same thing, and see if I can compare the base64 encoding of the ciphertexts, but no luck. I am very inexperienced with bash scripting and I still don't have a solid grasp on the data types I should be passing into the encryption:

Bash script

Edit 2: Here is the procedure I used to generate the starting seed. The lab manual says that Alice created a pdf file at "2018-04-17 23:08:49". I used a date command date -d "2018-04-17 23:08:49" +%s to get the number of seconds since the starting epoch. This is what I used as the starting seed. The lab also states that it is known that Alice generated the key between this starting time and 2 hours later, which is why I set the end of the seed range to startSeed + 7200.

Last edit: After the changes I finally got it to work. I made it so that I am generating seeds in the proper time window, and I made it so that AES algorithm does not add padding.

Additionally, I only allocate 16 bytes to my ciphertext arrays, and changed memcmp to look at 16 bytes only. After these changes I was able to reproduce the known ciphertext.


Solution

  • Aside from the fixes that I made to use the proper seed range and statically decode the hex input strings, what was the most broken in my implementation was comparing a 16-byte long char array with a 128 byte long char array. I changed the generated cipher text char arrays to only be 16 bytes long, as well as only comparing 16 bytes at a time in memcmp().