Un hash criptográfico convierte cualquier cantidad de datos en un resumen corto y de tamaño fijo. La misma entrada siempre produce el mismo resumen, una entrada distinta (aunque solo cambie un bit) produce uno completamente diferente, y no existe una forma práctica de encontrar una entrada que produzca un resumen elegido. Un código de autenticación de mensajes (MAC) añade una clave secreta a esa idea, de modo que el resumen también demuestra que los datos no han sido alterados por nadie que no posea la clave.
Todas las funciones de esta página reciben y devuelven TBytes y residen en sgcCrypto_SHA2, sgcCrypto_Keccak, sgcCrypto_Blake2b, sgcCrypto_Blake2s, sgcCrypto_SipHash, sgcCrypto_HMAC, sgcCrypto_CMAC y sgcCrypto_Poly1305.
SHA-2
La familia de hash detrás de los certificados TLS, la firma de código y la mayoría de los protocolos en producción hoy en día. Use SHA-256 a menos que algo específico requiera un tamaño distinto.
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 y KMAC
SHA-3 se construye sobre una base distinta (Keccak) a la de SHA-2, de modo que una debilidad en una familia no se traslada a la otra, razón por la cual los protocolos que necesitan garantías a largo plazo suelen especificar ambas. SHAKE128 y SHAKE256 son funciones de salida extensible: en lugar de un tamaño de resumen fijo, se solicitan tantos bytes como se necesiten, y una salida más corta siempre es un prefijo de una más larga a partir de la misma entrada. ML-KEM, ML-DSA y SLH-DSA (vea Criptografía Poscuántica) se construyen internamente sobre SHAKE. KMAC es el código de autenticación de mensajes nativo de SHA-3, construido sobre 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 y BLAKE2s
BLAKE2 es más rápido que SHA-2 y SHA-3 en software, ofreciendo el mismo margen de seguridad, y acepta directamente una clave opcional, sin la construcción HMAC. BLAKE2b está orientado a plataformas de 64 bits con resúmenes de hasta 512 bits; BLAKE2s está orientado a plataformas de 32 bits y embebidas con resúmenes de hasta 256 bits. Un resumen más corto no es una truncación del completo, la longitud se mezcla dentro del propio hash, de modo que un programa no puede cambiar de tamaño y esperar una salida coincidente.
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 es un hash rápido y con clave diseñado para búsquedas en tablas hash. Su función es impedir que un atacante alimente la aplicación con entradas elegidas que caigan todas en el mismo cubo y conviertan una búsqueda O(1) en O(n), una técnica de denegación de servicio conocida como hash flooding. Toma exactamente 16 bytes de clave y produce una etiqueta de 8 bytes; no es un MAC de propósito general y no debe usarse para autenticar mensajes.
function sgcSipHash24(const aKey, aData: TBytes): TBytes;
HMAC
HMAC convierte cualquiera de los hashes anteriores en un código de autenticación de mensajes. Es la opción estándar cuando el hash subyacente no acepta una clave directamente (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 construye un MAC a partir de un cifrado de bloque en lugar de un hash. Úselo cuando un protocolo especifica AES-CMAC por su nombre (es habitual en especificaciones de tarjetas inteligentes e IoT); en caso contrario, HMAC-SHA256 es la opción predeterminada más habitual.
function sgcAES_CMAC(const aKey, aData: TBytes): TBytes;
function sgcAES_CMAC_Verify(const aKey, aData, aTag: TBytes): Boolean;
Poly1305
Poly1305 es un autenticador de un solo uso: nunca debe usarse dos veces con la misma clave. En la práctica no se llama directamente, es la mitad de autenticación de los cifrados AEAD ChaCha20-Poly1305 y XChaCha20-Poly1305 de la página Cifrado Simétrico, que derivan una clave de un solo uso distinta para cada mensaje.
function sgcPoly1305(const aKey, aData: TBytes): TBytes;
function sgcPoly1305_Verify(const aKey, aData, aTag: TBytes): Boolean;
Comparar un MAC o un hash de contraseña
Nunca compare dos etiquetas o resúmenes con un simple = cuando uno de ellos proceda de una fuente no confiable. Una comparación byte a byte que se detiene en cuanto encuentra una discrepancia tarda mensurablemente menos tiempo cuanto antes se produce la discrepancia, lo cual es suficiente señal para que un atacante falsifique una etiqueta válida un byte cada vez a lo largo de muchos intentos. Use en su lugar la comparación en tiempo constante de sgcCrypto_Encoding, listada en Codificación y utilidades en la página general de Criptografía.
function sgcConstantTimeEquals(const aLeft, aRight: TBytes): Boolean;
RIPEMD-160
Un resumen de 160 bits del proyecto europeo RIPE, en sgcCrypto_Legacy pero no heredado en el sentido que le da el apartado de abajo. No está roto como lo están MD5 y SHA-1, pero es más lento que SHA-256 y ofrece menos margen de seguridad, así que pertenece a los sitios donde un formato lo nombra específicamente y no a una elección por defecto. Bitcoin y todas las cadenas descendientes de él lo usan para las direcciones, en capas sobre SHA-256. HMAC-RIPEMD160 es 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;
Hashes heredados
sgcCrypto_Legacy proporciona MD4, MD5 y HMAC-MD5. Los tres están rotos como primitivas de seguridad: se han publicado colisiones prácticas tanto para MD4 como para MD5. Existen únicamente para interoperar con protocolos y formatos de archivo más antiguos que los especifican por su nombre (por ejemplo, la autenticación NTLM). No los elija para nada nuevo; use SHA-256 o BLAKE2b en su lugar.
function sgcMD4(const aData: TBytes): TBytes;
function sgcMD5(const aData: TBytes): TBytes;
function sgcHMAC_MD5(const aKey, aData: TBytes): TBytes;