Хеширование Java MD5 не соответствует хешированию C# MD5

Я очень мало знаю о шифровании / хешировании.

Я должен хешировать ключ шифрования. Пример на 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);

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

Ява получает...

[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 (не наоборот), есть идеи?

Спасибо.

1 ответ

Решение

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

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

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

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

Другие вопросы по тегам