Пример #1
0
static uint8_t find_key_byte(pool *p, const byteblock *b, size_t offs, size_t block)
{
  byteblock cp = { p->alloc(p, b->len), 0 };
  
  for (size_t x = 0, i = offs; i < b->len; i += block, x++)
  {
    cp.buf[x] = b->buf[i];
    cp.len++;
  }
  
  int best_score = INT_MAX;
  uint8_t best_keybyte = 0;
  
  for (int keybyte = 0; keybyte < 256; keybyte++)
  {
    uint8_t kb = (uint8_t) keybyte;
    byteblock key = { &kb, 1 };
    byteblock plain = byteblock_xor(p, &cp, &key);
    int score = score_english(&plain);
    
    if (score < best_score)
    {
      best_score = score;
      best_keybyte = keybyte;
    }
  }
  
  return best_keybyte;
}
Пример #2
0
char break_ciphertext_single_byte_xor(const unsigned char *ciphertext, size_t length, unsigned char *plaintext)
{
	unsigned char key;

	double high_score = 0.0;
	int i, j;
	for (i = 0; i < 256; ++i) {
		for (j = 0; j < length; ++j) {
			plaintext[j] = ciphertext[j] ^ i;
		}
		double score = score_english(plaintext, length);
		if (score > high_score) {
			high_score = score;
			key = i;
		}
	}

	for (j = 0; j < length; ++j) {
		plaintext[j] = ciphertext[j] ^ key;
	}
	return key;
}
Пример #3
0
int main(int argc, char **argv)
{
  pool p[1] = { pool_create() };
  
  assert(argc == 2);
  byteblock cipher = from_base64(p, argv[1]);
  
  int best_score = INT_MAX;
  byteblock best_key;
  byteblock best_plaintext;
  
  // this is actually quick enough and easier to bruteforce: 40 * 256 * 256 tries
  
  for (size_t k = 2; k < MAX_KEYLEN; k++)
  {
    byteblock key = { p->alloc(p, k), k };
    for (size_t i = 0; i < key.len; i++)
    {
      key.buf[i] = find_key_byte(p, &cipher, i, key.len);
    }
    
    byteblock plain = byteblock_xor(p, &cipher, &key);
    int score = score_english(&plain);
    
    if (score < best_score)
    {
      best_score = score;
      best_key = key;
      best_plaintext = plain;
    }
  }
  
  printf("key: %s, plain: %s\n", to_hex(p, &best_key), to_ascii(p, &best_plaintext));
  
  p->finish(p);
  return 0;
}