2. Using basic rand() to generate keys
● Many programming languages support the basic rand() function
● rand() functions have a predictable behavior
○ Given the ith
byte of a random number, it is possible to predict the (i+1)th
byte
● Crypto keys shall be generated using secure random number generators
● For example, in Linux, urandom file contains good quality random numbers
● This demo shows how an attacker can identify the key when rand() is used
● Assume that the attacker knows the date/time of key generation
○ This is not a hard assumption - it is possible to perform this attack without this knowledge
2
3. Using rand to generate keys
unsigned char* generateKey_bad(unsigned int keySize) {
int i = 0;
unsigned char* key = (unsigned char *)malloc(sizeof(unsigned char)*keySize);
/* Error handling code left out for demo purposes */
srand(time(NULL)); /* Predictable behavior due to this seed */
for (i = 0; i < keySize; i++) {
key[i] = rand() % 256;
}
return key;
}
3
4. Using rand to generate keys ...
● After running the above program, we got 16 bytes of AES key
db76b5c16f7a4956ffb01de3433b05b8
● The attacker can reconstruct all these 16 bytes very easily as follows
● Let’s say the key was generated in the interval [Thu Nov 7 10:57:12 EST
2019, Thu Nov 7 11:01:29 EST 2019]
● We now show how to predict the possible list of keys
● We just have to initialize the seed for all time t in the above interval only
○ $ date -d "2019-11-07 10:57:12" +%s
○ Output: 1573142232
○ date -d "2019-11-07 11:01:29" +%s
○ Output: 1573142489
4
5. Attack: generating a list of potential keys
5
● For demo purposes, the
starting and ending seed
values are hardcoded (see
the loop index)
● Note that srand is called for
all possible seed values
● This attack is not specific to
CBC but worth stressing it
6. Attack: generating a list of potential keys ...
6
● There were only 258 keys in that time interval
○ wc -l keys.txt
○ 258 keys.txt
● The highlighted row indeed shows our key
● The attacker has to just try only 258 possible
keys to decrypt the data
7. Fix is simple - use /dev/urandom
unsigned char* generateKey_good(unsigned int keySize) {
unsigned char* key = (unsigned char *)malloc(sizeof(unsigned char)*keySize);
/* Error handling code is left out for demo purposes */
FILE* random = fopen("/dev/urandom", "r");
int i = 0;
for (i = 0; i < keySize; i++) {
fread(key, sizeof(unsigned char)*keySize, 1, random);
}
fclose(random);
return key;
}
7