Базовый алгоритм шифрования в Java не расшифровывается

#java #encryption

#java #шифрование

Вопрос:

Я пытаюсь реализовать TEA (алгоритм крошечного шифрования) на Java, чтобы закодировать byte[] содержащий аудио файл размером 512.

Вот моя функция шифрования:

 //Encrypt 64bit/8byte buffer with 128bit/16byte key
public byte[] encrypt(int[] data, int[] key) { 
    int x = data[0]; 
    int y = data[1]; 
    ByteBuffer encrypted = ByteBuffer.allocate(8);
    int sum = 0; 
    int constant = 0x9e3779b9; //magic constant

    for (int k = 0; k < 32;   k) { 
        sum  = constant; 
        x  = (y << 4 amp; 0xfffffff0)   key[0] ^ y   sum ^ (y >> 5 amp; 0x7ffffff)   key[1]; 
        y  = (x << 4 amp; 0xfffffff0)   key[2] ^ x   sum ^ (x >> 5 amp; 0x7ffffff)   key[3]; 
    }
    encrypted.putInt(x);
    encrypted.putInt(y);
    return encrypted.array();
}
  

и расшифровывать:

 public byte[] decrypt(int[] data, int[] key) { 
    int x = data[0]; 
    int y = data[1]; 
    ByteBuffer decrypted = ByteBuffer.allocate(8);
    int sum = 0xC6EF3720; //32*delta
    int constant = 0x9e3779b9; //magic constant

    for (int k = 0; k < 32;   k) { 
        x -= (x << 4 amp; 0xfffffff0)   key[2] ^ x   sum ^ (x >> 5 amp; 0x7ffffff)   key[3]; 
        y -= (y << 4 amp; 0xfffffff0)   key[0] ^ y   sum ^ (y >> 5 amp; 0x7ffffff)   key[1]; 
        sum -= constant; 
    }
    decrypted.putInt(x); 
    decrypted.putInt(y);
    return decrypted.array();
}
  

и мой вызов encrypt:

 ByteBuffer unwrapEncrypt = ByteBuffer.allocate(512);
int[] encryptionKey = {55555, 8888, 123857, 912029};

//block is a byte[] with length 512
ByteBuffer plainText = ByteBuffer.wrap(block);
for (int j = 0; j < block.length / 8; j  ) {
    //Initiate array for int pairs
    int[] plainTextInts = new int[2];
    plainTextInts[0] = plainText.getInt();
    plainTextInts[1] = plainText.getInt();
    //Encrypt and store
    unwrapEncrypt.put(encrypt(plainTextInts, encryptionKey));
}
  

и вызов decrypt:

 ByteBuffer audioToPlay = ByteBuffer.allocate(512);
int[] decryptionKey = {55555, 8888, 123857, 912029};

//audio is a byte[] with length 512
ByteBuffer cipherText = ByteBuffer.wrap(audio);
for (int j = 0; j < audio.length / 8; j  ) {
    int[] plainTextInts = new int[2];
    //Initiate array for int pairs
    plainTextInts[0] = cipherText.getInt();
    plainTextInts[1] = cipherText.getInt();
    //Decrypt and store
    audioToPlay.put(decrypt(plainTextInts, decryptionKey));
}
  

Извините за массу кода — я пробовал анализировать отправленный звук и полученные расшифрованные данные — они оба правильной длины, просто совершенно разные. Если я удалю эти 4 блока кода, звук будет идеальным. Кто-нибудь может определить, в чем дело? Спасибо

Комментарии:

1. >> -> >>> ?

2. Что примерно вы имеете в виду?

3. При сдвиге вправо. О, и я думаю, что amp; имеет приоритет.

4. Итак, (x >> 5 amp; 0x7ffffff) и (y >> 5 amp; 0x7ffffff) —> (x >>> 5 amp; 0x7ffffff) и (y >> 5 amp; 0x7ffffff) внутри encrypt и decrypt ?

5. (x >>> 5) amp; 0x7fffffff Я думаю. Обратите внимание, что я еще даже не посмотрел описание TEA, но мне это кажется неправильным. На самом деле, даже приведенное выше кажется неправильным, потому что для этого кода вам не понадобился бы amp; . Тестируйте шаг за шагом. Должен ли он быть rotate вместо shift? Хммм, я посмотрю. Если я смогу держать глаза открытыми, то да.

Ответ №1:

Кажется, в вашем decrpyt() методе есть ошибка при сравнении его с описанием TEA в Википедии. Вы должны поменять местами x и y слева от -= операторов. Для меня, похоже, работает следующее:

 public byte[] decrypt(int[] data, int[] key) { 
    int x = data[0]; 
    int y = data[1]; 
    ByteBuffer decrypted = ByteBuffer.allocate(8);
    int sum = 0xC6EF3720; //32*delta
    int constant = 0x9e3779b9; //magic constant

    for (int k = 0; k < 32;   k) { 
        y -= (x << 4 amp; 0xfffffff0)   key[2] ^ x   sum ^ (x >> 5 amp; 0x7ffffff)   key[3]; 
        x -= (y << 4 amp; 0xfffffff0)   key[0] ^ y   sum ^ (y >> 5 amp; 0x7ffffff)   key[1]; 
        sum -= constant; 
    }
    decrypted.putInt(x); 
    decrypted.putInt(y);
    return decrypted.array();
}
  

Комментарии:

1. Ах, я думаю, это еще одна ошибка. Обратите внимание, что работа дешифрования не означает, что это правильная реализация TEA. Для этого вам нужно протестировать тестовые векторы или известную хорошую реализацию.

2. И обратите внимание, что даже у двух человек может возникнуть одна и та же ошибка во время реализации. Если у вас есть тестовые векторы, то это легко увидеть, и если это первая реализация дизайнерами, это нелегко увидеть.