Un hachage cryptographique transforme n'importe quelle quantité de données en une empreinte courte et de taille fixe. La même entrée produit toujours la même empreinte, une entrée différente (même un seul bit modifié) produit une empreinte complètement différente, et il n'existe aucun moyen pratique de trouver une entrée qui produise une empreinte choisie. Un code d'authentification de message (MAC) ajoute une clé secrète à cette idée, de sorte que l'empreinte prouve également que les données n'ont pas été altérées par quiconque ne détient pas la clé.
Toutes les fonctions de cette page prennent et renvoient des TBytes et résident dans sgcCrypto_SHA2, sgcCrypto_Keccak, sgcCrypto_Blake2b, sgcCrypto_Blake2s, sgcCrypto_SipHash, sgcCrypto_HMAC, sgcCrypto_CMAC et sgcCrypto_Poly1305.
SHA-2
La famille de hachage derrière les certificats TLS, la signature de code et la plupart des protocoles en production aujourd'hui. Utilisez SHA-256 sauf si un besoin spécifique impose une autre taille.
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 et KMAC
SHA-3 repose sur une construction différente (Keccak) de celle de SHA-2, de sorte qu'une faiblesse dans une famille ne se répercute pas sur l'autre, ce qui explique pourquoi les protocoles qui ont besoin d'une garantie à long terme spécifient souvent les deux. SHAKE128 et SHAKE256 sont des fonctions de sortie extensible : au lieu d'une taille d'empreinte fixe, vous demandez autant d'octets que nécessaire, et une sortie plus courte est toujours un préfixe d'une sortie plus longue issue de la même entrée. ML-KEM, ML-DSA et SLH-DSA (voir Cryptographie post-quantique) reposent tous en interne sur SHAKE. KMAC est le code d'authentification de message natif de SHA-3, construit sur 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 et BLAKE2s
BLAKE2 est plus rapide que SHA-2 et SHA-3 en logiciel tout en offrant la même marge de sécurité, et il accepte directement une clé optionnelle, sans passer par la construction HMAC. BLAKE2b vise les plateformes 64 bits avec des empreintes allant jusqu'à 512 bits ; BLAKE2s vise les plateformes 32 bits et embarquées avec des empreintes allant jusqu'à 256 bits. Une empreinte plus courte n'est pas une troncature de l'empreinte complète, la longueur est mélangée dans le hachage lui-même, de sorte qu'un programme ne peut pas changer de taille et attendre une sortie correspondante.
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 est un hachage rapide et à clé conçu pour les recherches dans les tables de hachage. Son rôle est d'empêcher un attaquant de fournir à votre application des entrées choisies qui atterrissent toutes dans le même compartiment et de transformer une recherche en O(1) en O(n), une technique de déni de service connue sous le nom de hash flooding. Il prend exactement 16 octets de clé et produit un tag de 8 octets ; ce n'est pas un MAC généraliste et il ne doit pas être utilisé pour authentifier des messages.
function sgcSipHash24(const aKey, aData: TBytes): TBytes;
HMAC
HMAC transforme n'importe lequel des hachages ci-dessus en un code d'authentification de message. C'est le choix standard lorsque le hachage sous-jacent n'accepte pas de clé directement (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 construit un MAC à partir d'un chiffrement par bloc plutôt qu'à partir d'un hachage. Utilisez-le lorsqu'un protocole spécifie AES-CMAC par son nom (c'est courant dans les spécifications de cartes à puce et d'IoT) ; sinon HMAC-SHA256 est le choix par défaut le plus habituel.
function sgcAES_CMAC(const aKey, aData: TBytes): TBytes;
function sgcAES_CMAC_Verify(const aKey, aData, aTag: TBytes): Boolean;
Poly1305
Poly1305 est un authentificateur à usage unique : il ne doit jamais être utilisé deux fois avec la même clé. En pratique il n'est pas appelé directement, il constitue la moitié authentification des chiffrements AEAD ChaCha20-Poly1305 et XChaCha20-Poly1305 sur la page Chiffrement symétrique, qui dérivent une nouvelle clé à usage unique pour chaque message.
function sgcPoly1305(const aKey, aData: TBytes): TBytes;
function sgcPoly1305_Verify(const aKey, aData, aTag: TBytes): Boolean;
Comparer un MAC ou un hachage de mot de passe
Ne comparez jamais deux tags ou empreintes avec un simple = lorsque l'un d'eux provient d'une source non fiable. Une comparaison octet par octet qui s'arrête dès qu'elle trouve une différence prend un temps mesurablement plus court lorsque la différence survient plus tôt, ce qui constitue un signal suffisant pour permettre à un attaquant de forger un tag valide un octet à la fois sur de nombreuses tentatives. Utilisez à la place la comparaison en temps constant de sgcCrypto_Encoding, listée sous Encodage & utilitaires sur la page de présentation Cryptographie.
function sgcConstantTimeEquals(const aLeft, aRight: TBytes): Boolean;
RIPEMD-160
Une empreinte de 160 bits issue du projet européen RIPE, présente dans sgcCrypto_Legacy mais sans être héritée au sens où l'entend la section ci-dessous. Il n'est pas cassé comme le sont MD5 et SHA-1, mais il est plus lent que SHA-256 et offre une marge de sécurité moindre, il a donc sa place là où un format le nomme spécifiquement, plutôt que comme choix par défaut. Bitcoin et toutes les chaînes qui en descendent l'utilisent pour les adresses, superposé à SHA-256. HMAC-RIPEMD160 est la 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;
Hachages hérités
sgcCrypto_Legacy fournit MD4, MD5 et HMAC-MD5. Les trois sont compromis en tant que primitives de sécurité : des collisions pratiques ont été publiées pour MD4 comme pour MD5. Ils n'existent que pour interopérer avec d'anciens protocoles et formats de fichiers qui les spécifient par leur nom (par exemple l'authentification NTLM). Ne les choisissez pas pour quoi que ce soit de nouveau ; utilisez plutôt SHA-256 ou BLAKE2b.
function sgcMD4(const aData: TBytes): TBytes;
function sgcMD5(const aData: TBytes): TBytes;
function sgcHMAC_MD5(const aKey, aData: TBytes): TBytes;