Coherencia

Es importante que Tink se comporte de la misma manera en todos los lenguajes de programación. Este concepto no es sencillo, pero lo más importante es lo siguiente:

Para mantener la coherencia, Tink usa pruebas de varios lenguajes que se pueden encontrar en el repositorio de GitHub de varios lenguajes. Estas pruebas verifican la coherencia y la interoperabilidad de los diferentes lenguajes.

Sin embargo, definir la coherencia no es tan sencillo como se podría esperar. Por lo tanto, en esta página, se proporciona nuestra definición de trabajo. Básicamente, Tink proporciona dos tipos de coherencia:

Contexto

En un nivel alto, Tink proporciona las siguientes APIs:

  • Manipulación de conjuntos de claves: Tink proporciona APIs para agregar claves nuevas a un conjunto de claves, quitar claves de un conjunto de claves y cambiar la clave primaria en un conjunto de claves.

  • Serialización de conjuntos de claves: Tink proporciona APIs para serializar un conjunto de claves en una secuencia de bytes y, a la inversa, analizar un conjunto de claves a partir de una secuencia de bytes.

  • Creación de primitivas: Tink proporciona una API para crear una interfaz para una primitiva a partir de un conjunto de claves. Por ejemplo, para crear un objeto Aead a partir de un conjunto de claves en Java, el usuario llama a keysetHandle.getPrimitive(config, Aead.class).

  • Uso de primitivas: La interfaz producida en el paso de creación de primitivas proporciona una API para realizar operaciones criptográficas.

Hay dos preguntas importantes que debes hacerte sobre estas APIs:

  • Creación: Para un conjunto de claves, un lenguaje y una primitiva serializados determinados, ¿es posible crear la primitiva a partir de este conjunto de claves en el lenguaje?

  • Evaluación: Si se puede crear una primitiva en algún lenguaje a partir de un conjunto de claves determinado, ¿cómo se comporta el objeto de primitiva?

Es importante tener en cuenta que Tink no proporciona coherencia cuando se analiza un conjunto de claves. Por ejemplo, es posible que Tink C++

  • analiza correctamente los conjuntos de claves que contienen claves CHACHA20-POLY1305, aunque las operaciones de AEAD de CHACHA20-POLY1305 no se implementen en Tink;
  • analiza correctamente los conjuntos de claves con claves que tienen una longitud de 1 byte, lo que fallará en todas las operaciones criptográficas.

Estos comportamientos pueden cambiar en las versiones secundarias.

Coherencia de la evaluación

La coherencia de la evaluación es más importante que cualquier coherencia en el proceso de creación: si un AEAD en Java no puede desencriptar la encriptación del AEAD en C++, los usuarios tienen un problema grave.

En general, Tink busca ser coherente de la manera obvia para las primitivas. Por ejemplo, si un objeto binario de C++ calcula una firma con public_key_sign->Sign(data), se espera que la llamada de verificación de Java correspondiente publicKeyVerify.verify(signature, data) tenga éxito.

Sin embargo, incluso en este caso, hay algunas advertencias. Por ejemplo, el tipo de datos que se devuelve de aead.Encrypt en Java es un byte[]. Según la especificación del lenguaje Java (JLS) §10.7, la longitud de un array es de tipo int, que, según §JLS 4.2.1, puede ser un máximo de 2147483647. Por lo tanto, la encriptación de un array con una longitud de 2147483647 falla en Java: la encriptación tiene cierta sobrecarga, lo que significa que el resultado sería demasiado largo. Sin embargo, en otros lenguajes, se permite que la encriptación se realice correctamente para esas entradas.

Por lo tanto, Tink proporciona coherencia de evaluación: Para un conjunto de claves determinado, si la creación de la primitiva se realiza correctamente en dos lenguajes, se comportan de la misma manera.

La excepción es que algunas operaciones pueden fallar en algunas circunstancias excepcionales.

Coherencia en la creación

La creación de primitivas no siempre se realiza correctamente para todos los conjuntos de claves. Por ejemplo, Tink no permite que los usuarios creen una AesSivKey si el material de la clave tiene una longitud de 128 bits.

Sin embargo, Tink proporciona coherencia de la siguiente manera: si dos lenguajes admiten un tipo de clave, el conjunto de claves para el que se puede crear la primitiva coincide. Por supuesto, si un lenguaje no admite un tipo de clave, no se puede crear ningún objeto primitivo.

La coherencia de creación es menos importante que la coherencia de evaluación, y hay más excepciones a esta regla que para la coherencia de evaluación. Estas limitaciones se documentan en nuestra lista de tipos de claves admitidos. Por ejemplo, para el tipo de clave ECIES, Tink ofrece una opción de qué curva elíptica usar para el acuerdo de claves, pero Java no admite X25519. Por lo tanto, la creación de una clave con X25519 en Java falla.


  1. En este documento, usamos el término Keyset para denotar el objeto llamado KeysetHandle en la mayoría de los lenguajes. ↩