2014-06-29 17 views
0

Я утомляюсь преобразованию логики ввода в java, которая написана на C#. Я передаю пользовательский параметр IV в качестве параметра.Шифрование AES 256 путем передачи IV

private static byte[] iv = new byte[] { 116,209,63,154,85,66,37,82,96,104,131,192,103,140,125,176 }; 

Но, в java не может содержать больше 128 в массиве байтов. В C# это возможно.

 this.secretKeySpec = new SecretKeySpec(key, "AES"); 
     this.iv = new IvParameterSpec(iv); 
     this.cipher = Cipher.getInstance(ALGORITHM_AES256); 

В javax.crypto IvParameterSpec constactory только позволяют байтовый массив как "IV". Может кто-нибудь, пожалуйста, помогите пройти выше байта [] как параметр iv в java.

+0

[аналогичный] (http://stackoverflow.com/questions/2346101/java-how-to-use-byte-literals-greater-than-0x7f) [вопросы] (http://stackoverflow.com/questions/9241336/initialize-unsigned-byte-array-using-hex-number), которые можно было бы считать дублирующими. –

+0

Вы не должны использовать статические IV в первую очередь. Статические IV бесполезны. –

ответ

2

Проблема в том, что Java не поддерживает unsigned datatypes, в то время как .NET это делает.

байты без знака от 0 до 255. Это .NET Byte структуры
Подписи байт от -128 до 127. Это Java-byte примитивного типа данных или .NET SByte структуры.

Данные в .Net-коде хранят iv как значения без знака, в то время как Java-код не позволяет вам делать это напрямую.

Решения:

1) Можно просто вручную вычесть 128 из каждого байта в коде .NET, таким образом делая его, чтобы представлять один и тот же битовый шаблон (IV просто последовательность битов - это не имеет значения, является ли они хранятся в виде подписанных или значений без знака - это биты, которые должны совпадать):

byte[] iv = new byte[] { -8, 81, ...}; 

2) или вы могли бы хранить одни и те же данные в массив типа данных Int и преобразовать их в байтовые значения, используя следующий код.

int[] ivInInts = new int[] { 116,209,63,154,85,66,37,82,96,104,131,192,103,140,125,176 }; 

byte[] iv = new byte[ivInInts.getLength()]; 

for (int i = 0; i < ivInInts.getLength(); i++) 
    iv = (byte)(ivInInts[i] - 128); 

EDIT:

Если у вас есть некоторые сомнения по поводу бинарного эквивалентности чисел можно прочитать о two's complement numbers:

65 = 0100 0001, как байт без знака = 0100 0001 как знаковое байт
-65 = не может быть представлен как unsigned byte = 1011 1111 как подписанный байт
193 = 1011 1111 как unsigned byte = не может быть представлен как подписанный байт

+0

Спасибо Eugene. Если мы вычитаем -128 из каждого элемента массива, массив результатов будет иметь (-) значение, не то же самое, что и в C#. Это нормально? – Dinusha

+0

@ Юджин Подскал. Вы не правы. Беззнаковое 8-битовое целое число от 0 до 255, а подписанное 8-битовое целое или sbyte - от -128 до 127. Пожалуйста, исправьте. – GoRoS

+0

@GoRoS Спасибо. Просто утеряли строки. –

1

Альтернатива предложению Юджина: просто явно преобразовать все значения - или значения выше 127 - путем литья в byte. Также рекомендуется использовать шестнадцатеричные данные для двоичных данных.

byte[] test = new byte[] { 0, (byte) 0, 0x00, (byte) 0x00, (byte) 128, (byte) 0x80, (byte) 256, (byte) 0x100 }; 

Обратите внимание, что - в качестве значения двух последних байтов должны ясно - это позволит вам указать значения, которые находятся вне диапазона, не поднимая предупреждение.

В качестве альтернативы вы можете использовать шестнадцатеричный или base64-декодер, поэтому вы можете создать более плотное представление массива байтов, используя строки.

Смежные вопросы