Ein kryptografischer Hash wandelt eine beliebige Datenmenge in einen kurzen Digest fester Größe um. Dieselbe Eingabe erzeugt immer denselben Digest, eine andere Eingabe (selbst ein einziges geändertes Bit) erzeugt einen völlig anderen, und es gibt keine praktikable Möglichkeit, eine Eingabe zu finden, die einen gewählten Digest erzeugt. Ein Message Authentication Code (MAC) fügt dieser Idee einen geheimen Schlüssel hinzu, sodass der Digest auch beweist, dass die Daten von niemandem verändert wurden, der den Schlüssel nicht besitzt.
Alle Funktionen auf dieser Seite nehmen TBytes entgegen und geben es zurück, und befinden sich in sgcCrypto_SHA2, sgcCrypto_Keccak, sgcCrypto_Blake2b, sgcCrypto_Blake2s, sgcCrypto_SipHash, sgcCrypto_HMAC, sgcCrypto_CMAC und sgcCrypto_Poly1305.
SHA-2
Die Hash-Familie hinter TLS-Zertifikaten, Codesignierung und den meisten heute produktiv eingesetzten Protokollen. Verwenden Sie SHA-256, sofern nichts Spezifisches eine andere Größe verlangt.
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 und KMAC
SHA-3 basiert auf einer anderen Konstruktion (Keccak) als SHA-2, sodass eine Schwäche in einer Familie nicht auf die andere übergreift, weshalb Protokolle, die eine langfristige Absicherung benötigen, oft beide festlegen. SHAKE128 und SHAKE256 sind Extendable-Output-Funktionen: Statt einer festen Digest-Größe fordern Sie so viele Bytes an, wie Sie benötigen, und eine kürzere Ausgabe ist immer ein Präfix einer längeren aus derselben Eingabe. ML-KEM, ML-DSA und SLH-DSA (siehe Post-Quanten-Kryptografie) basieren alle intern auf SHAKE. KMAC ist der native Message Authentication Code von SHA-3, aufgebaut auf 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 und BLAKE2s
BLAKE2 ist in Software schneller als SHA-2 und SHA-3 und bietet dabei dieselbe Sicherheitsmarge, und es nimmt einen optionalen Schlüssel direkt entgegen, ohne die HMAC-Konstruktion. BLAKE2b zielt auf 64-Bit-Plattformen mit Digests bis zu 512 Bit ab; BLAKE2s zielt auf 32-Bit- und Embedded-Plattformen mit Digests bis zu 256 Bit ab. Ein kürzerer Digest ist keine Kürzung des vollständigen Digests, die Länge wird in den Hash selbst eingemischt, sodass ein Programm nicht einfach die Größe wechseln und passende Ausgaben erwarten kann.
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 ist ein schneller, geschlüsselter Hash, der für Hashtabellen-Lookups entwickelt wurde. Seine Aufgabe ist es, einen Angreifer daran zu hindern, Ihrer Anwendung gezielt gewählte Eingaben zuzuführen, die alle im selben Bucket landen und einen O(1)-Lookup in O(n) verwandeln, eine Denial-of-Service-Technik, die als Hash Flooding bekannt ist. Er verwendet genau 16 Byte Schlüssel und erzeugt ein 8-Byte-Tag; er ist kein universeller MAC und sollte nicht zur Authentifizierung von Nachrichten verwendet werden.
function sgcSipHash24(const aKey, aData: TBytes): TBytes;
HMAC
HMAC verwandelt jeden der obigen Hashes in einen Message Authentication Code. Es ist die Standardwahl, wenn der zugrunde liegende Hash keinen Schlüssel direkt akzeptiert (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 baut einen MAC aus einer Blockchiffre statt aus einem Hash auf. Verwenden Sie ihn, wo ein Protokoll AES-CMAC namentlich vorschreibt (üblich in Smartcard- und IoT-Spezifikationen); ansonsten ist HMAC-SHA256 die gebräuchlichere Standardwahl.
function sgcAES_CMAC(const aKey, aData: TBytes): TBytes;
function sgcAES_CMAC_Verify(const aKey, aData, aTag: TBytes): Boolean;
Poly1305
Poly1305 ist ein Einmal-Authentifikator: Er darf niemals zweimal mit demselben Schlüssel verwendet werden. In der Praxis wird er nicht direkt aufgerufen, er bildet die Authentifizierungshälfte der AEAD-Chiffren ChaCha20-Poly1305 und XChaCha20-Poly1305 auf der Seite Symmetrische Verschlüsselung, die für jede Nachricht einen neuen Einmalschlüssel ableiten.
function sgcPoly1305(const aKey, aData: TBytes): TBytes;
function sgcPoly1305_Verify(const aKey, aData, aTag: TBytes): Boolean;
Einen MAC oder einen Passwort-Hash vergleichen
Vergleichen Sie zwei Tags oder Digests niemals mit einem einfachen =, wenn einer davon aus einer nicht vertrauenswürdigen Quelle stammt. Ein Byte-für-Byte-Vergleich, der zurückkehrt, sobald er eine Abweichung findet, benötigt messbar weniger Zeit, je früher die Abweichung auftritt, was ausreicht, damit ein Angreifer über viele Versuche hinweg Byte für Byte ein gültiges Tag fälschen kann. Verwenden Sie stattdessen den Constant-Time-Vergleich aus sgcCrypto_Encoding, aufgeführt unter Kodierung & Hilfsfunktionen auf der Übersichtsseite Kryptografie.
function sgcConstantTimeEquals(const aLeft, aRight: TBytes): Boolean;
RIPEMD-160
Ein 160-Bit-Digest aus dem europäischen RIPE-Projekt, in sgcCrypto_Legacy, aber nicht legacy im Sinne des folgenden Abschnitts. Es ist nicht gebrochen, wie MD5 und SHA-1 es sind, aber es ist langsamer als SHA-256 und bietet eine geringere Sicherheitsmarge, daher gehört es dorthin, wo ein Format es ausdrücklich benennt, statt als Standardwahl. Bitcoin und jede von ihm abstammende Chain verwenden es für Adressen, geschichtet über SHA-256. HMAC-RIPEMD160 ist RFC 2286.
function sgcRIPEMD160(const aData: TBytes): TBytes;
function sgcHMAC_RIPEMD160(const aKey, aData: TBytes): TBytes;
var
oHash160: TBytes;
begin
{ the Bitcoin address digest: RIPEMD-160 over SHA-256 }
oHash160 := sgcRIPEMD160(sgcSHA256(oPublicKey));
end;
Legacy-Hashes
sgcCrypto_Legacy stellt MD4, MD5 und HMAC-MD5 bereit. Alle drei sind als Sicherheitsprimitive gebrochen: Praktische Kollisionen wurden sowohl für MD4 als auch für MD5 veröffentlicht. Sie existieren nur zur Interoperabilität mit älteren Protokollen und Dateiformaten, die sie namentlich vorschreiben (zum Beispiel NTLM-Authentifizierung). Wählen Sie sie für nichts Neues; verwenden Sie stattdessen SHA-256 oder BLAKE2b.
function sgcMD4(const aData: TBytes): TBytes;
function sgcMD5(const aData: TBytes): TBytes;
function sgcHMAC_MD5(const aKey, aData: TBytes): TBytes;