2012-06-02 1 views
1

У меня есть C# WebService и (Java) приложение для Android. Существует ли ПРОСТОЙ хэш-функция, которая дает тот же результат между этими двумя языками? Простейший хеш C# - String.GetHashCode(), но я не могу его реплицировать на Java. Простейший Java-хэш не является простым. И я не знаю, могу ли я воспроизвести его именно на C#.Простой хэш, который всегда равен между C# и Java

В случае, если это имеет значение, я передаю пароли перед отправкой через Интернет. В настоящее время я использую Encode64, но это явно небезопасно, так как мы можем отменить его.


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

Java

public String Hash(String s) 
{ 
    StringBuffer sb = new StringBuffer(); 
    try { 
     MessageDigest md = MessageDigest.getInstance("SHA-256"); 
     md.update(s.getBytes()); 
     byte byteData[] = md.digest(); 
     for (int i = 0; i < byteData.length; i++) { 
      sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16) 
        .substring(1)); 
     } 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return sb.toString(); 
} 

C#

public static string Hash(String s) 
{ 
    HashAlgorithm Hasher = new SHA256CryptoServiceProvider(); 
    byte[] strBytes = Encoding.UTF8.GetBytes(s); 
    byte[] strHash = Hasher.ComputeHash(strBytes); 
    return BitConverter.ToString(strHash).Replace("-","").ToLowerInvariant().Trim(); 
} 

Спасибо, ребята! :)

+0

Как насчет хэширования строки с общим хэш-функции из какой-либо библиотеки/существующего пакета? – nhahtdh

+1

AES. Не изобретайте велосипед. – starbolin

+1

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

ответ

6

Во-первых, вид хешей, реализованный String.GetHashCode() и String.hashCode(), не предназначен для использования в таких целях. Для начала они имеют только хеш для 32, но числа (по крайней мере, в случае Java), поэтому существует значительный риск столкновения. В этом случае, если два разных пароля сопоставляются с одним и тем же хэшем ... тогда у кого-то есть шанс на 1 из 2^32, что будет принят случайно выбранный пароль. (И обратная сторона заключается в том, что если плохой парень может перехватить 32-битный хеш для действительного пароля, у них есть большой «нога вверх», угадывая, что такое исходный пароль!)

Во-вторых, отправка крипто хеша (например, MD5, SHA-256 и т. д.), вероятно, не решит ваши проблемы с безопасностью ... если вы не отправите хэш через SSL или что-то еще. Конечно, плохой парень не сможет восстановить исходный пароль, но они МОГУТ перехватить и использовать хэш в атаке «повторного воспроизведения». (Есть способы борьбы с этим, но для них требуется общий секретный ключ или использование шифрования с открытым/закрытым ключом ... и вы должны знать, что вы делаете, если хотите, чтобы это было безопасно.)

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


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

(Но не использовать простой 32-битный хэш-код, потому что едва ли более безопасным, чем base64.)

+0

Хорошо, сначала я не программирую ядерный реактор (например, у I/dont/есть проблема с безопасностью). Я прошу простую хэш, так как безопасность не вызывает беспокойства. Я просто не хочу, чтобы мои собственные сотрудники писали Decode64 через поле PasswordHash в БД и выясняли, что большинство людей используют один и тот же пароль с другими учетными записями. Если кто-то использует повторную атаку на моем сервисе, я буду очень польщен тем, что они даже беспокоились. – GaiusSensei

+0

Работа с паролями требует хорошего шифрования. Ваши сотрудники будут перерабатывать пароли и свою ответственность, чтобы заботиться о них правильно. Теперь у вас может не быть проблемы с безопасностью, но в конце концов. – Kurru

1

Вы должны попробовать шифровать, если ищете безопасность. В противном случае существуют встроенные алгоритмы хеширования, такие как MD5. Это должно быть надежно согласовано между 2

+1

MD5 не работает. используйте другой –

+0

+1. MD5 является wayyyyy лучше, чем base64 :). Но да SHA-256 будет лучше (SHA-256 в C# и Java - http://stackoverflow.com/questions/7095664/c-sharp-sha-256-vs-java-sha-256-different-results) –

3

Используйте стандартный алгоритм, такой как MD5 или SHA256, который даст одинаковые результаты на любой платформе (если он будет реализован правильно), но вы можете подумать, действительно ли это способ «зашифровать» пароль, прежде чем отправлять его по кабелю.

+0

У меня есть очень большая вероятность столкнуться с чем-то вроде этого: http://stackoverflow.com/questions/7095664/c-sharp-sha-256-vs-java-sha-256-different-results, и я просто не могу есть время для отладки. Вот почему я ищу ПРОСТОЙ хэш. – GaiusSensei

+0

Мне любопытно, почему вы думаете, что у вас есть большой шанс? Принятый ответ на этот вопрос - простое исправление - убедитесь, что вы явно указываете, какую кодировку вы используете при преобразовании из строки в 'byte []'. –

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