En esta página, se describe el formato de conexión de Tink para las claves y los resultados primitivos. La documentación está dirigida a los criptógrafos que desean agregar lenguajes adicionales a Tink y los encargados de mantenimiento de otras bibliotecas criptográficas de alto nivel que desean un modo compatible con conexiones por cable. No está destinada al público general.
Serialización del conjunto de claves
Tink usa Búfer de Google para serializar sus conjuntos de claves.
- Un conjunto de claves serializado binario es un proto conjunto de claves serializado definido en tink.proto. La propiedad de valor KeyData de una clave es un protocolo serializado del tipo de clave correspondiente.
- Un conjunto de claves serializado en JSON es un proto de conjunto de claves serializado en formato JSON. Ten en cuenta que el valor de KeyData sigue siendo un archivo proto serializado binario.
- Un conjunto de claves encriptado es un proto EncryptedKeyst serializado definido en tink.proto. Contiene un conjunto de claves binario serializado encriptado y, opcionalmente, algunos metadatos de KeysetInfo no encriptados.
Prefijo de salida Tink
La mayoría de las primitivas de Tink admiten un prefijo de salida de 5 bytes que consta de lo siguiente:
- Versión de 1 byte:
0x01
- Sugerencia de clave de 4 bytes: Este es el ID de clave de la clave que se usó.
Es posible que algunas claves heredadas también admitan el byte de versión 0x00
.
Ten en cuenta que este prefijo no está autenticado y no se puede utilizar con fines de seguridad. Tink lo usa como pista para acelerar la desencriptación o la verificación.
AEAD
En general, Tink formatea los textos cifrados AEAD de la siguiente manera:
prefix || IV || ciphertext || tag
a menos que se especifique lo contrario en el RFC correspondiente. prefix
está vacío o es un prefijo de salida de Tink de 5 bytes.
AES-CTR-HMAC
Para AES-CTR-HMAC, Tink calcula el MAC con datos asociados (AD) de la siguiente manera:
AD || IV || ciphertext || bitlen(AD)
donde bitlen(AD)
es la longitud de AD en bits representados como un número entero big-endian de 64 bits sin firma. Este esquema HMAC sigue el borrador de AES-CBC-HMAC de Mcgrew.
AEAD determinista
Tink implementa RFC 5297 para AES-SIV, colocando el vector de inicialización sintético (SIV) al comienzo del texto cifrado. La primitiva puede agregar un prefijo de salida Tink de 5 bytes.
Si bien RFC 5297 admite una lista de datos asociados, Tink solo admite un dato asociado exactamente, que corresponde a una lista con un elemento en RFC 5297. Un dato asociado vacío es una lista con un elemento vacío, y no una lista vacía.
AEAD de transmisión
Consulta HMAC de AES-CTR y AES-GCM-HKDF.
Encriptación de sobre
La encriptación de sobre encripta los datos con una clave de encriptación de datos DEK
mediante las primitivas de AEAD de Tink. La encriptación funciona de la siguiente manera:
- Se genera un
DEK
nuevo con una plantilla de claves (o parámetros de clave) determinada. DEK
se serializa en una string de bytes. El formato de serialización la serialización del búfer de protocolo del proto del tipo de clave. Por ejemplo, este es un mensaje de búfer de protocoloAesGcmKey
serializado definido en aes_gcm.proto para la DEK de tipo de clave AES GCM. Consulta serialización de búfer de protocolo para saber cómo serializar un búfer de protocolo.- Un proveedor externo (por ejemplo, GCP) encripta el
DEK
serializado en unencrypted DEK
. DEK
se usa para encriptar el texto sin formato con los datos asociados enciphertext
. Por lo tanto,ciphertext
tiene exactamente el mismo formato que la primitiva de AEAD correspondiente aDEK
.
El formato de salida de la encriptación de sobre es el siguiente:
encrypted DEK length || encrypted DEK || ciphertext
encrypted DEK length
es de 4 bytes y almacena la longitud de encrypted DEK
como un número entero big-endian de 32 bits.
MAC
Tink sigue las RFC correspondientes. Las funciones básicas pueden agregar un prefijo de salida Tink de 5 bytes a la etiqueta.
Conjunto de documentos PRF
Tink sigue las RFC correspondientes. Ten en cuenta que, para el conjunto de PRF, el tipo de clave difiere del tipo de clave MAC del mismo algoritmo, ya que no incluye la longitud de salida. Las claves de conjunto de PRF nunca agregan un prefijo de salida de Tink. Esto garantiza que el resultado sea realmente una PRF.
Encriptación híbrida
El formato de conexión general para la encriptación híbrida de Tink es el siguiente:
prefix || encapsulated_key || encrypted_data
prefix
está vacío o es un prefijo de salida Tink de 5 bytes. Cada tipo de clave contiene información sobre la cantidad de bytes que se deben analizar y cómo analizar esos bytes desde encapsulated_key
.
HPKE (encriptación de clave pública híbrida)
Tink sigue el estándar HPKE definido en RFC 9180. Un conjunto de cifrado HPKE incluye las siguientes tres primitivas.
- Mecanismo de encapsulamiento de claves (KEM)
- Función de derivación de claves (KDF)
- Encriptación autenticada con datos asociados (AEAD)
El estándar HPKE no define un formato de conexión general en la sección 10 de RFC 9180. La implementación de HPKE de Tink usa los siguientes valores de encapsulated_key
y encrypted_data
.
encapsulated_key
- Clave pública serializada del remitente
- Se define como
enc
en RFC 9180, sección 4.1. - Formato determinado por el HPKE KEM específico utilizado
encrypted_data
- Texto cifrado y etiqueta (es decir,
ciphertext || tag
sin el IV) - Se define como
ct
en RFC 9180, sección 4. - Formato determinado por el AEAD de HPKE específico utilizado
- Texto cifrado y etiqueta (es decir,
X25519 KEM basado en Diffie-Hellman
Para los DHKEM X25519, el valor enc
es la clave pública Diffie-Hellman de 32 bytes del remitente.
ECIES-AEAD-HKDF
Para la implementación de ECIES-AEAD-HKDF de Tink, encapsulated_key
es el resultado del mecanismo de encapsulamiento de claves (KEM) y encrypted_data
es el resultado del mecanismo de encapsulamiento de datos (DEM).
KEM de
Según el tipo de clave, Tink usa puntos de curva elíptica comprimidos y sin comprimir, según los estándares de codificación RFC 8422/ANSI.X9-62.2005
. Para los puntos sin comprimir, al byte 0x04
le siguen las coordenadas x
y y
como números enteros de tamaño fijo. En el caso de las coordenadas comprimidas, se usa el byte 0x02
o 0x03
y la coordenada x
como un número entero de tamaño fijo. Para X25519
, se usa la definición RFC 7748 (coordenada x
como número entero de tamaño fijo).
DEM
En el caso de encrypted_data
, Tink usa el mismo formato que AEAD. Esto incluye especificar un IV.
Derivación de claves
Primero, se calcula la coordenada x x_ss
del punto compartido. La clave del AEAD se establece de la siguiente manera:
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
donde encapsulated_key
es la salida completa de KEM como bytes.
Firmas digitales
Tink sigue las RFC correspondientes. Las funciones básicas pueden agregar un prefijo de salida Tink de 5 bytes a la etiqueta que se genera.
ECDSA
Según el campo EcdsaSignatureEncoding de la clave, el formato de una firma ECDSA es IEEE P1363
o ASN.1 DER
.
El formato de la firma IEEE P1363
es r || s
, en el que r
y s
tienen relleno cero y tienen el mismo tamaño en bytes que el orden de la curva. Por ejemplo, para la curva NIST P-256
, r
y s
tienen un relleno de cero a 32 bytes.
La firma DER se codifica con ASN.1
:
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
En particular, la codificación es la siguiente:
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
Tink sigue las prácticas recomendadas para la verificación de firmas, ya que solo acepta firmas ECDSA codificadas en DER (las firmas alternativas con codificación BER no son válidas).
Esto ayuda a evitar los ataques de maleabilidad de firmas, que a menudo afectan los sistemas de criptomonedas.