Skrót kryptograficzny zamienia dowolną ilość danych w krótki skrót o stałym rozmiarze. Te same dane wejściowe zawsze dają ten sam skrót, inne dane wejściowe (nawet przy zmianie jednego bitu) dają zupełnie inny wynik, a nie ma praktycznego sposobu na znalezienie danych wejściowych dających wybrany skrót. Kod uwierzytelniania wiadomości (MAC) dodaje do tej idei klucz tajny, dzięki czemu skrót dowodzi również, że dane nie zostały zmienione przez nikogo, kto nie posiada tego klucza.
Wszystkie funkcje na tej stronie przyjmują i zwracają TBytes i znajdują się w jednostkach sgcCrypto_SHA2, sgcCrypto_Keccak, sgcCrypto_Blake2b, sgcCrypto_Blake2s, sgcCrypto_SipHash, sgcCrypto_HMAC, sgcCrypto_CMAC i sgcCrypto_Poly1305.
SHA-2
Rodzina skrótów stojąca za certyfikatami TLS, podpisywaniem kodu i większością protokołów działających dziś produkcyjnie. Używaj SHA-256, chyba że coś konkretnie wymaga innego rozmiaru.
function sgcSHA1(const aData: TBytes): TBytes;
function sgcSHA224(const aData: TBytes): TBytes;
function sgcSHA256(const aData: TBytes): TBytes;
function sgcSHA384(const aData: TBytes): TBytes;
function sgcSHA512(const aData: TBytes): TBytes;
SHA-3, SHAKE, cSHAKE i KMAC
SHA-3 opiera się na innej konstrukcji (Keccak) niż SHA-2, więc słabość w jednej rodzinie nie przenosi się na drugą, dlatego protokoły wymagające długoterminowej pewności często określają obie naraz. SHAKE128 i SHAKE256 to funkcje o rozszerzalnym wyjściu: zamiast stałego rozmiaru skrótu żąda się tylu bajtów, ile potrzeba, a krótsze wyjście jest zawsze prefiksem dłuższego, uzyskanego z tych samych danych wejściowych. ML-KEM, ML-DSA i SLH-DSA (patrz Kryptografia postkwantowa) są wewnętrznie zbudowane na SHAKE. KMAC to natywny kod uwierzytelniania wiadomości SHA-3, zbudowany na cSHAKE.
function sgcSHA3_224(const aData: TBytes): TBytes;
function sgcSHA3_256(const aData: TBytes): TBytes;
function sgcSHA3_384(const aData: TBytes): TBytes;
function sgcSHA3_512(const aData: TBytes): TBytes;
function sgcSHAKE128(const aData: TBytes; aLen: Integer): TBytes;
function sgcSHAKE256(const aData: TBytes; aLen: Integer): TBytes;
function sgcKMAC128(const aKey, aData: TBytes; aLen: Integer; const aCustom: TBytes): TBytes;
function sgcKMAC256(const aKey, aData: TBytes; aLen: Integer; const aCustom: TBytes): TBytes;
BLAKE2b i BLAKE2s
BLAKE2 jest szybszy niż SHA-2 i SHA-3 w implementacji programowej, oferując przy tym ten sam margines bezpieczeństwa, a klucz opcjonalny przyjmuje bezpośrednio, bez konstrukcji HMAC. BLAKE2b jest przeznaczony na platformy 64-bitowe, ze skrótami do 512 bitów; BLAKE2s jest przeznaczony na platformy 32-bitowe i wbudowane, ze skrótami do 256 bitów. Krótszy skrót nie jest obcięciem pełnego skrótu, długość jest wmieszana w sam skrót, więc program nie może po prostu zmienić rozmiaru i oczekiwać zgodnego wyniku.
function sgcBlake2b(const aData: TBytes; aDigestLen: Integer = 64): TBytes;
function sgcBlake2b_Keyed(const aKey, aData: TBytes; aDigestLen: Integer = 64): TBytes;
function sgcBlake2s(const aData: TBytes; aDigestLen: Integer = 32): TBytes;
function sgcBlake2s_Keyed(const aKey, aData: TBytes; aDigestLen: Integer = 32): TBytes;
SipHash
SipHash-2-4 to szybki, kluczowany skrót zaprojektowany do przeszukiwania tablic haszujących. Jego zadaniem jest powstrzymanie atakującego przed dostarczaniem aplikacji wybranych danych wejściowych, które trafiają do tego samego kubełka i zamieniają wyszukiwanie O(1) w O(n), co jest techniką odmowy usługi znaną jako hash flooding. Przyjmuje dokładnie 16 bajtów klucza i tworzy 8-bajtowy tag; nie jest ogólnego przeznaczenia kodem MAC i nie powinien być używany do uwierzytelniania wiadomości.
function sgcSipHash24(const aKey, aData: TBytes): TBytes;
HMAC
HMAC zamienia dowolny z powyższych skrótów w kod uwierzytelniania wiadomości. Jest standardowym wyborem, gdy bazowy skrót nie przyjmuje klucza bezpośrednio (SHA-1, SHA-2).
function sgcHMAC_SHA1(const aKey, aData: TBytes): TBytes;
function sgcHMAC_SHA256(const aKey, aData: TBytes): TBytes;
function sgcHMAC_SHA384(const aKey, aData: TBytes): TBytes;
function sgcHMAC_SHA512(const aKey, aData: TBytes): TBytes;
var
oTag: TBytes;
begin
oTag := sgcHMAC_SHA256(TBytes(oKey), TBytes(oMessage));
end;
AES-CMAC
CMAC buduje MAC na bazie szyfru blokowego zamiast skrótu. Używaj go tam, gdzie protokół wprost wymienia AES-CMAC z nazwy (jest to powszechne w specyfikacjach kart inteligentnych i IoT); w innych przypadkach bardziej typowym wyborem domyślnym jest HMAC-SHA256.
function sgcAES_CMAC(const aKey, aData: TBytes): TBytes;
function sgcAES_CMAC_Verify(const aKey, aData, aTag: TBytes): Boolean;
Poly1305
Poly1305 jest uwierzytelniaczem jednorazowym: nigdy nie może zostać użyty dwukrotnie z tym samym kluczem. W praktyce nie jest wywoływany bezpośrednio, lecz stanowi część uwierzytelniającą szyfrów AEAD ChaCha20-Poly1305 i XChaCha20-Poly1305 opisanych na stronie Szyfrowanie symetryczne, które wyprowadzają świeży, jednorazowy klucz dla każdej wiadomości.
function sgcPoly1305(const aKey, aData: TBytes): TBytes;
function sgcPoly1305_Verify(const aKey, aData, aTag: TBytes): Boolean;
Porównywanie MAC-a lub skrótu hasła
Nigdy nie porównuj dwóch tagów ani skrótów zwykłym operatorem =, gdy jeden z nich pochodzi z niezaufanego źródła. Porównanie bajt po bajcie, które kończy się natychmiast po znalezieniu niezgodności, trwa mierzalnie krócej, im wcześniej ta niezgodność wystąpi, co jest wystarczającym sygnałem, aby atakujący mógł sfałszować poprawny tag bajt po bajcie w wielu próbach. Zamiast tego użyj porównania w stałym czasie z jednostki sgcCrypto_Encoding, wymienionego w sekcji Kodowanie i narzędzia na stronie przeglądowej Kryptografia.
function sgcConstantTimeEquals(const aLeft, aRight: TBytes): Boolean;
RIPEMD-160
160-bitowy skrót z europejskiego projektu RIPE, w sgcCrypto_Legacy, ale niebędący starszym rozwiązaniem w sensie, jaki ma na myśli poniższa sekcja. Nie jest złamany tak, jak MD5 i SHA-1, ale jest wolniejszy niż SHA-256 i oferuje mniejszy margines bezpieczeństwa, więc należy po niego sięgać tam, gdzie format wymienia go z nazwy, a nie jako domyślny wybór. Bitcoin i każdy łańcuch od niego pochodny używa go do adresów, nałożonego na SHA-256. HMAC-RIPEMD160 to RFC 2286.
function sgcRIPEMD160(const aData: TBytes): TBytes;
function sgcHMAC_RIPEMD160(const aKey, aData: TBytes): TBytes;
var
oHash160: TBytes;
begin
{ skrót adresu Bitcoin: RIPEMD-160 nad SHA-256 }
oHash160 := sgcRIPEMD160(sgcSHA256(oPublicKey));
end;
Starsze skróty
sgcCrypto_Legacy udostępnia MD4, MD5 i HMAC-MD5. Wszystkie trzy są złamane jako prymitywy bezpieczeństwa: opublikowano praktyczne kolizje zarówno dla MD4, jak i MD5. Istnieją wyłącznie po to, by zapewnić interoperacyjność ze starszymi protokołami i formatami plików, które wymieniają je z nazwy (na przykład uwierzytelnianie NTLM). Nie wybieraj ich do niczego nowego; zamiast tego stosuj SHA-256 lub BLAKE2b.
function sgcMD4(const aData: TBytes): TBytes;
function sgcMD5(const aData: TBytes): TBytes;
function sgcHMAC_MD5(const aKey, aData: TBytes): TBytes;