#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. И обратите внимание, что даже у двух человек может возникнуть одна и та же ошибка во время реализации. Если у вас есть тестовые векторы, то это легко увидеть, и если это первая реализация дизайнерами, это нелегко увидеть.