En esta página, se describe el formato de transmisión de Tink para claves y salidas primitivas. La documentación está dirigida a criptógrafos que quieran agregar idiomas adicionales a Tink y a los encargados de otras bibliotecas de criptografía de alto nivel que quieran un modo compatible con cables. No está destinado al público en general.
Serialización del conjunto de claves
Tink usa Google protobuf para serializar sus conjuntos de claves.
- Un conjunto de claves serializado binario es un proto de conjunto de claves serializado definido en tink.proto. La propiedad de valor KeyData de una clave es un proto 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 proto serializado binario.
- Un conjunto de claves encriptado es un proto EncryptedKeyset serializado que se define en tink.proto. Contiene un conjunto de claves binario encriptado y, de manera opcional, algunos metadatos de KeysetInfo no encriptados.
Prefijo de salida de 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 utilizada.
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 usar con fines de seguridad. Tink lo usa como una sugerencia 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 la 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 representada como número entero sin signo de formato big-endian de 64 bits. Este esquema de HMAC sigue el borrador de AES-CBC-HMAC de McGrew.
AEAD determinista
Tink implementa la RFC 5297 para AES-SIV y coloca el vector de inicialización sintético (SIV) al comienzo del texto cifrado. La primitiva puede agregar un prefijo de salida de Tink de 5 bytes.
Si bien el RFC 5297 admite una lista de datos asociados, Tink solo admite exactamente un dato asociado, que corresponde a una lista con un elemento en el RFC 5297. Los datos asociados vacíos son una lista con un elemento vacío, 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
usando las primitivas de AEAD de Tink. La encriptación funciona de la siguiente manera:
- Se genera un
DEK
nuevo con una plantilla de clave (o parámetros de clave) determinada. - El
DEK
se serializa en una cadena de bytes. El formato de serialización es la serialización del búfer de protocolo del proto de tipo de clave. Por ejemplo, este es un mensaje de búfer de protocoloAesGcmKey
serializado definido en aes_gcm.proto para la DEK del tipo de clave AES GCM. Consulta serialización de búferes 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
. - Se usa
DEK
para encriptar el texto simple 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
El encrypted DEK length
es de 4 bytes y almacena la longitud del encrypted DEK
como un número entero de 32 bits big-endian.
MAC
Tink sigue las RFC correspondientes. Las primitivas pueden agregar un prefijo de salida de Tink de 5 bytes a la etiqueta.
PRF establecido
Tink sigue las RFC correspondientes. Ten en cuenta que, para PRF Set, el tipo de clave difiere del tipo de clave MAC del mismo algoritmo porque no incluye la longitud de salida. Las claves de PRF Set nunca agregan un prefijo de salida de Tink. Esto garantiza que el resultado sea realmente un PRF.
Encriptación híbrida
El formato de cable 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 de Tink de 5 bytes. Cada tipo de clave contiene la información sobre cuántos bytes analizar y cómo analizarlos desde encapsulated_key
.
HPKE (encriptación de clave pública híbrida)
Tink sigue el estándar HPKE definido en la RFC 9180. Un algoritmo 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 cable general en la RFC 9180, sección 10. 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 la RFC 9180, sección 4.1. - Es el formato determinado por el KEM de HPKE específico que se usa.
encrypted_data
- Texto cifrado y etiqueta (es decir,
ciphertext || tag
sin el IV) - Se define como
ct
en la sección 4 de la RFC 9180. - Formato determinado por el AEAD de HPKE específico que se usa
- Texto cifrado y etiqueta (es decir,
KEM basado en Diffie-Hellman X25519
Para los DHKEM X25519, el valor enc
es la clave pública de Diffie-Hellman de 32 bytes del remitente.
ECIES-AEAD-HKDF
En la implementación de ECIES-AEAD-HKDF de Tink, encapsulated_key
es el resultado del mecanismo de encapsulación de claves (KEM) y encrypted_data
es el resultado del mecanismo de encapsulación de datos (DEM).
KEM
Según el tipo de clave, Tink usa puntos de curva elíptica comprimidos y no comprimidos, según los estándares de codificación RFC 8422/ANSI.X9-62.2005
. Para los puntos sin comprimir, el byte 0x04
está seguido de las coordenadas x
y y
como números enteros de tamaño fijo. Para 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 de la RFC 7748 (coordenadas x
como número entero de tamaño fijo).
DEM
Para encrypted_data
, Tink usa el mismo formato que el AEAD. Esto incluye especificar un IV.
Derivación de claves
Primero, se calcula la coordenada x x_ss
del punto compartido. Luego, la clave de la AEAD se establece en lo siguiente:
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
donde encapsulated_key
es el resultado completo del KEM como bytes.
Firmas digitales
Tink sigue las RFC correspondientes. Las primitivas pueden agregar un prefijo de salida de Tink de 5 bytes a la etiqueta que se genera.
ECDSA
Según el campo EcdsaSignatureEncoding en 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
se rellenan con 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
se rellenan con ceros hasta 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 codificadas en BER no son válidas).
Esto ayuda a prevenir los ataques de maleabilidad de la firma, que a menudo afectan a los sistemas de criptomonedas.