Java - algorytmy Hash-najszybsze wdrożenia

Chcę wiedzieć jaka jest najlepsza i najszybsza implementacja algorytmów hashowych dla Javy szczególnie MD5 i SHA - 2 512 (SHA512) lub 256. Chcę, aby funkcja otrzymywała ciąg znaków jako argument i zwracała hash jako wynik. Dziękuję.

Edit: służy do mapowania każdego adresu URL na unikalny hash. Ponieważ MD5 nie jest tak niezawodny w tej dziedzinie, bardziej interesuje mnie znalezienie najlepszej i najszybszej implementacji dla algorytmów SHA-2. Zauważ, że wiem, że nawet SHA-2 może produkować ten sam hash dla niektórych adresów URL, ale mogę z tym żyć.

Author: Alireza Noori, 2011-03-26

6 answers

Po pierwsze: prędkość jest przereklamowana. Przed stwierdzeniem, że dany algorytm jest "zbyt wolny"należy dokonać pomiarów. Przez większość czasu szybkość funkcji hash nie robi żadnej zauważalnej różnicy. Jeśli masz wątpliwości dotyczące bezpieczeństwa, najpierw wybierz funkcję hash, która jest wystarczająco bezpieczna, a następnie martw się tylko o wydajność.

Ponadto, chcesz hashować "strings". Java String jest wewnętrznie fragmentem tablicy char wartości, które reprezentują punkty kodu Unicode (właściwie Unicode 16-bitowe jednostki kodu, które kodują punkty kodu za pomocą UTF-16). Funkcja hash przyjmuje jako wejście sekwencję bitów lub bajtów. Będziesz musiał wykonać krok konwersji, np. str.getBytes("UTF-8"), aby uzyskać ciąg znaków jako kilka bajtów. Jest prawdopodobne, że krok konwersji będzie miał niebagatelny koszt w porównaniu do samego hashowania.

Uwaga: uwaga na kodowanie URL ! W adresie URL niektóre bajty mogą być zastąpione sekwencjami rozpoczynającymi się znakiem " %"; ma to na celu wsparcie znaki niedrukowalne, ale mogą być również używane na" standardowych " znakach(np. zastąpienie "a "przez" %61"). Oznacza to, że dwa łańcuchy znaków, które są różne (w sensie String.equals()), mogą faktycznie reprezentować ten sam adres URL (jeśli chodzi o przetwarzanie adresów URL). W zależności od sytuacji może to być problem lub nie.

Powinieneś najpierw spróbować użyć API Javy MessageDigest ze standardowym (już zainstalowanym) dostawcą JCE( tzn. wywołasz MessageDigest.getInstance("SHA-256")), a wynik będzie testowany jako bench. Teoretycznie JCE może mapować wywołanie do implementacji z" natywnym " kodem (napisanym w C lub assembly), który będzie szybszy niż to, co można uzyskać w Javie.

To powiedziane...

Sphlib jest implementacją opensource wielu kryptograficznych funkcji hashowych, w C i w Javie. Kod został zoptymalizowany pod kątem szybkości, a w praktyce wersja Java okazuje się szybsza niż standardowa JRE firmy Sun/Oracle. Użyj tego linku w przypadku, gdy poprzedni link nie powiedzie się (główny serwer hosta jest czasami wyłączony do konserwacji, jak wydaje się być teraz w przypadku) (Ostrzeżenie: pobieranie 10 MB). Archiwum zawiera również raport (który został przedstawiony na drugiej konferencji kandydatów SHA-3 w 2010 roku), który podaje pewne wyniki pomiarów na kilku platformach, dla SHA-2 i 14 "drugiej tury" kandydatów na nadchodzące SHA-3.

Ale naprawdę powinieneś zrobić benchmarki w sytuacji. Na przykład, efekty na pamięci podręcznej L1 mogą mieć drastyczny efekt na wydajność i nie można dokładnie przewidzieć, biorąc kod funkcji i uruchamiając go w izolacji.

 52
Author: Thomas Pornin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-28 12:33:40

Edit: pierwotnie przeczytałem to pytanie jako "najszybszy algorytm skrótu" i zostało ono wyjaśnione jako "najszybsza implementacja każdego algorytmu". To ważne pytanie, a inni wskazywali na szybsze implementacje. Jednak o ile nie mieszasz dużych ilości danych w krótkim czasie, to po prostu nie będzie to miało większego znaczenia. Wątpię, że zwykle warto poświęcić czas i złożoność, aby użyć czegoś innego niż to, co jest dostarczane ze standardem JCE.

Dla adresów URL musiałbyś być hashujący z SHA-256 w górę milion na sekundę na nowoczesnym sprzęcie, aby wymagać czegoś szybciej. Nie wyobrażam sobie, aby większość aplikacji wymagała więcej niż tysiąca na sekundę (ponad 86 milionów dziennie), co oznacza, że całkowity czas procesora spędzony na hashowaniu byłby znacznie mniejszy niż 1%. Więc nawet jeśli masz nieskończenie szybki algorytm haszujący, będziesz w stanie poprawić ogólną wydajność tylko o 1% w najlepszym przypadku.

Oryginalna Odpowiedź: Uzyskanie zarówno najlepszego, jak i najszybszego jest sprzeczne ze sobą. Lepsze skróty są zazwyczaj wolniejsze. Jeśli naprawdę potrzebujesz prędkości, a bezpieczeństwo nie jest tak ważne, użyj MD5. Jeśli potrzebujesz najlepszego zabezpieczenia, wybierz SHA-256 lub nawet SHA-512. Nie wspomniałeś, do czego go używasz, więc trudno polecić jedno lub drugie. Prawdopodobnie najbezpieczniej będzie z SHA-256, ponieważ powinien być wystarczająco szybki dla większości przypadków użycia na nowoczesnym sprzęcie. Oto jak możesz to zrobić it:

String input = "your string";
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(input.getBytes("UTF-8"));
byte[] hash = digest.digest();

Jeśli używasz tego do celów bezpieczeństwa, takich jak hashowanie hasła, powinieneś również dodać sól do digestu. Jeśli chcesz wypisać z hasha drukowalny ciąg znaków, możesz go zakodować z powrotem do łańcucha jako hex:

static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();

StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
    sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
    sb.append(HEX_CHARS[b & 0x0F]);
}
String hex = sb.toString();
 21
Author: WhiteFang34,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-29 05:55:07

Zobacz: wiele przykładów SHA / MD5

Także: z tego samego wątku: Fast MD5

String hash = MD5.asHex (MD5.getHash(new File (filename)));

 2
Author: AndyMac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:08:50

Kolejną rzeczą do rozważenia jest użycie MD4. Nie jest tak bezpieczny jak MD5, ale jest obliczany jeszcze szybciej. Windows do XP używany do przechowywania i wymiany haseł w MD4, więc używamy tego hasha, ponieważ nadal pozwala nam świadczyć usługi uwierzytelniania dla tej platformy.

 2
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-27 00:43:59

Rozważ BLAKE2, który jest szybszy i bezpieczniejszy niż wspomniane wyżej hasze.

MD5, SHA-1, SHA256 i SHA-512 są podatne na wydłużenie.

MD5 i SHA-1 są podatne na kolizje.

MD5 jest podatny na kolizje z wybranym prefiksem.

SHA - 3 i BLAKE2 nie mają znanych problemów z bezpieczeństwem i mogą generować strawienia o różnej długości.

SHA - 3 jest najszybszy, gdy jest zaimplementowany w sprzęcie; BLAKE2 jest najszybszy, gdy jest używany w oprogramowaniu wdrożenia.

BLAKE2b jest zoptymalizowany pod kątem platform 64-bitowych i produkuje digesty o dowolnym rozmiarze od 1 do 64 bajtów.

BLAKE2s jest zoptymalizowany dla platform od 8 do 32-bitowych i produkuje digesty o dowolnym rozmiarze od 1 do 32 bajtów.

W tym celu należy wykonać następujące czynności:]}

Https://blake2.net/

Https://www.cryptopp.com/benchmarks.html

W pierwszym łączu BLAKE2b (947 Mbits) jest znacznie szybszy niż SHA-256 (413 Mbits) I MD5 (632 Mbits).

W drugim łączu, AES - 256 (805 Mbits) i BLAKE2b (776 Mbits) są mniej więcej równe i szybsze niż SHA-256 (275 Mbits) i MD5 (602) Mbits.

 1
Author: Paul Des Rivieres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 18:41:17

Dla ciągu wystarczy wywołać hashCode(), ponieważ jest tańszy w pamięci.

W przeciwnym razie polecam ten kod dla private hash:

public static int hash8(String val) throws UnsupportedEncodingException {
    return hash8(val.getBytes("UTF-8"));
}

public static int hash8(byte[] val) {
    int h = 1, i = 0;
    for (; i + 7 < val.length; i += 8) {
        h = 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * 31
                * 31 * 31 * 31 * val[i] + 31 * 31 * 31 * 31 * 31 * 31
                * val[i + 1] + 31 * 31 * 31 * 31 * 31 * val[i + 2] + 31
                * 31 * 31 * 31 * val[i + 3] + 31 * 31 * 31 * val[i + 4]
                + 31 * 31 * val[i + 5] + 31 * val[i + 6] + val[i + 7];
    }
    for (; i + 3 < val.length; i += 4) {
        h = 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * val[i] + 31 * 31
                * val[i + 1] + 31 * val[i + 2] + val[i + 3];
    }
    for (; i < val.length; i++) {
        h = 31 * h + val[i];
    }
    return h;
}

FYI: http://lemire.me/blog/2015/10/22/faster-hashing-without-effort/

 0
Author: Daniel De León,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-24 01:41:50