diff options
| -rw-r--r-- | lib/lib3.c | 78 | ||||
| -rw-r--r-- | lib/lib3.h | 6 | ||||
| -rw-r--r-- | set3/task24.c | 48 |
3 files changed, 132 insertions, 0 deletions
@@ -203,3 +203,81 @@ int unshift_left_xor(int number, int shifts, unsigned int mask) return restore; } + +int mt_19937_stream_cipher(char *in, int length_in, char *out, int seed) +{ + struct mt_19937_state mt_state; + char keystream; + int i, tmp; + + mt_19937_seed(seed, &mt_state); + + for(i=0;i<length_in;i++) { + tmp = mt_19937(&mt_state); + keystream = tmp & 0xFF; + out[i] = in[i] ^ keystream; + } +} + +int mt_19937_stream_cipher_oracle(char *in, int length_in, char *out) +{ + int prefix_length = random_number_between(0,50); + // only 16 bit seed, 0 would not be a good seed, since the keystream + // would allways be 0 + int seed = random_number_between(1,65536); + char *plaintext_full = malloc(length_in + prefix_length); + + printf("use seed: %i\n", seed); + // generate random number of random bytes + generate_random_bytes(plaintext_full, prefix_length); + memcpy(&plaintext_full[prefix_length], in, length_in); + + mt_19937_stream_cipher(plaintext_full, (length_in+prefix_length), + out, seed); + + return (length_in + prefix_length); +} + + +int crack_mt_19937_stream_cipher_16_bit_seed(char *ciphertext, int length_ciphertext, + char *plaintext, char *match) +{ + int i; + int seed; + int match_len = strlen(match); + for(seed=1;seed<65536;seed++) { + mt_19937_stream_cipher(ciphertext, length_ciphertext, plaintext, seed); + for(i=1;i<match_len;i++) { + if(plaintext[length_ciphertext-i] != match[match_len-i]) { + break; + } + else if (i == (match_len-1)) + goto out; + } + } +out: + printf("found seed: %i\n", seed); +} + +unsigned int mt_19937_password_token() +{ + int seed = time(NULL); + struct mt_19937_state mt_state; + printf("password token seed: %i\n", seed); + mt_19937_seed(seed, &mt_state); + + return mt_19937(&mt_state); +} + +int mt_19937_password_token_time_based(unsigned int password_token, int time_window) +{ + int start_time = time(NULL); + struct mt_19937_state mt_state; + int seed; + for(seed=start_time-(time_window*60);seed<start_time+(time_window*60);seed++) { + mt_19937_seed(seed, &mt_state); + if(password_token == mt_19937(&mt_state)) + return 1; + } + return 0; +} @@ -33,4 +33,10 @@ unsigned int mt_19937_timestamp_orcale(struct mt_19937_state *mt_state); void mt_19937_brute_force_timestamp(); int unshift_left_xor(int number, int shifts, unsigned int mask); int unshift_right_xor(int number, int shifts); +int mt_19937_stream_cipher(char *in, int length_in, char *out, int seed); +int mt_19937_stream_cipher_oracle(char *in, int length_in, char *out); +int crack_mt_19937_stream_cipher_16_bit_seed(char *ciphertext, int length_ciphertext, + char *plaintext, char *match); +unsigned int mt_19937_password_token(); +int mt_19937_password_token_time_based(unsigned int password_token, int time_window); #endif diff --git a/set3/task24.c b/set3/task24.c new file mode 100644 index 0000000..e355d08 --- /dev/null +++ b/set3/task24.c @@ -0,0 +1,48 @@ +#include "../lib/lib.h" +#include "../lib/lib2.h" +#include "../lib/lib3.h" +#include <time.h> + +/** + * One should not restore the internal state of the MT. Given 624 bytes of + * input this would be straight forward. + * Instead one should restore more or less the first state (the seed from + * which this states arrived). To restore a previous state of the MT is + * possible. You have to go so far back, how long your ciphertext is and + * how much states you would need to encrpyt it. + * + * Since it is a 16 bit seed, one can also brute force it with 2^16 + * possible values...within seconds! exhautive search Yeah! + * Theoritcal we only need 2^(16/2) values because of birthday paradox + * + **/ + +int main() +{ + srand(time(NULL)); + // try to decrypt + char plaintext[] = "Hallo du da wie geht es dir Knallkopp"; + char *ciphertext = malloc(strlen(plaintext)); + + int length_ciphertext = mt_19937_stream_cipher_oracle(plaintext, + strlen(plaintext), ciphertext); + + char *restore_pl = malloc(length_ciphertext); + char *hex_ciphertext = malloc(length_ciphertext*2+1); + hex_binary_to_string(ciphertext, hex_ciphertext, length_ciphertext); + printf("ciphertext: %s\n", hex_ciphertext); + //mt_19937_stream_cipher(ciphertext, length_ciphertext + // decrypt it + crack_mt_19937_stream_cipher_16_bit_seed(ciphertext, length_ciphertext, + restore_pl, plaintext); + + printf("plaintext: %s\n", restore_pl); + + // crack a MT time based password token + // well do it agian with brute force + unsigned int password_token = mt_19937_password_token(); + int is_time_based = mt_19937_password_token_time_based(password_token, 1000); + + printf("password token is time based %i\n", is_time_based); + +} |
