2012-06-14 2 views
4

Я очень мало знаю об шифровании/хешировании.Java MD5 хеширование не соответствует хешированию C# MD5

У меня есть hash ключ шифрования. Пример в Java, как это ...

String encryptionKey = "test"; 

    MessageDigest messageDigest = MessageDigest.getInstance("MD5"); 
    messageDigest.update(encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length()); 
    byte[] encryptionKeyBytes = messageDigest.digest(); 

Теперь исправьте меня, если я ошибаюсь, но приведенный выше код хэш строки с алгоритмом MD5.

И я хочу тот же результат, когда у меня есть одна и та же строка в C#.

Мой текущий C# код выглядит следующим образом ...

string encryptionKey = "test"; 

     var md5 = MD5.Create(); 
     var keyBytes = Encoding.UTF8.GetBytes(encryptionKey); 
     byte[] encryptionKeyBytes = md5.ComputeHash(keyBytes); 

Но результаты конца байта не совпадают.

Java получает ...

[0] 9 
[1] -113  
[2] 107 
[3] -51 
[4] 70 
[5] 33 
[6] -45 
[7] 115 
[8] -54 
[9] -34 
[10] 78 
[11] -125  
[12] 38 
[13] 39 
[14] -76 
[15] -10 

C# получает ...

[0] 9 byte 
    [1] 143 byte 
    [2] 107 byte 
    [3] 205 byte 
    [4] 70 byte 
    [5] 33 byte 
    [6] 211 byte 
    [7] 115 byte 
    [8] 202 byte 
    [9] 222 byte 
    [10] 78 byte 
    [11] 131 byte 
    [12] 38 byte 
    [13] 39 byte 
    [14] 180 byte 
    [15] 246 byte 

мне нужен мой C# код, чтобы получить тот же результат, что и код Java (а не наоборот), есть идеи?

спасибо.

+3

Байты Java подписаны. C# байтов нет. Обратите внимание, что только места, где байт Java отрицательный, это неправильно. – vcsjones

+0

Кроме того, у вас есть довольно плохая ошибка в java-коде: 'encryptionKey.getBytes (« UTF-8 »), 0, encryptionKey.length()' Я оставляю это вам, чтобы понять, что такое ошибка. Последнее сравнение прямого строкового представления (toString) всегда плохое. – bestsss

+0

@bestsss Я использую точку останова для проверки значений. Я думаю, что значения точки останова производятся из представления toString (может быть, и не так). Как вы собираетесь сравнивать байтовые значения? – Theo

ответ

11

Действительно, результаты являются идентичными. Как и другие интегральные типы, значение байта может интерпретироваться как подписанное, так и неподписанное. Например, 10001111 соответствует 143 (ваше второе значение C#), если оно интерпретируется как unsigned. Однако, если он интерпретируется как , подписанный (с использованием two’s complement), его значение будет -113 (ваше второе значение Java).

Таким образом, несоответствие, по-видимому, вызвано тем, что ваши значения отформатированы как подписанные на Java, но без знака в C#. Если вы хотите получить подписанный байт в C#, вы можете использовать:

sbyte[] encryptionKeyBytesSigned = 
    encryptionKeyBytes.Select(b => (sbyte)b).ToArray(); 

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

+0

Спасибо за ваш ответ ... Это последнее утверждение, похоже, противоречит, если я правильно его читаю.Если вы сохраните оба файла, и они идентичны, то это просто проблема форматирования, возникающая при отображении значений. Вы можете уточнить? Я возьму это хешированное значение (в байте []) и использую его как ключ шифрования. Так что, если это всего лишь проблема с отображением, я думаю, что без конверсии все будет в порядке. Я не думаю, что функция шифрования будет принимать sbyte [] вместо байта []. – Theo

+0

Н/м. Вы просто предупреждали меня проверить и убедиться. Я понял. – Theo

+0

@ Theo: Да, я предполагаю, что это проблема форматирования, и при сохранении в файл результирующие файлы должны быть идентичными даже без преобразования значений C# в подписанный байт. Однако, честно говоря, я не знаком с Java (я могу только ручаться за ваш код C#), поэтому я бы выполнил некоторые тесты, чтобы убедиться. – Douglas