¿Qué es Tink?

Tink es una biblioteca de criptografía de código abierto escrita por criptógrafos y, también, ingenieros de seguridad de Google. Las APIs seguras y sencillas de Tink reducen los errores comunes mediante el diseño centrado en el usuario, una implementación cuidadosa, revisiones de código y pruebas exhaustivas. Consulta la sección Objetivos de esta página y obtén más información sobre los objetivos para cumplir Tink.

Tink ayuda a los usuarios sin criptografía a implementar tareas criptográficas comunes de forma segura. En Google, Tink se implementó en cientos de productos y sistemas.

¿Por qué debería usar Tink?

Las razones más importantes para usar Tink son las siguientes:

  • Es fácil de usar

    La criptografía es difícil de obtener correctamente. Con Tink, puedes encriptar o firmar datos con garantías de seguridad integradas en el uso de solo unas pocas líneas de código. Tink también puede ayudarte a rotar o proteger claves mediante sistemas de administración de claves (KMS) externos.

  • Es segura

    Tink agrega protecciones de seguridad a las bibliotecas conocidas, como BoringSSL y Java Cryptography Architecture, y las muestra directamente en las interfaces, para que los auditores y las herramientas puedan encontrar las brechas con rapidez. Tink también separa las APIs que son potencialmente peligrosas, para que puedas supervisarlas.

  • Es compatible

    Los textos cifrados de Tink son compatibles con las bibliotecas de criptografía existentes. Tink también admite la encriptación o el almacenamiento de claves en Amazon KMS, Google Cloud KMS, Android Keystore y Llaveros de iOS.

¿Quién está usando Tink?

Muchas empresas, como Google, Square y Citadel, usan Tink, así como cientos de clientes de Google Cloud y socios de Google Pay. Tink también potencia la biblioteca de seguridad de Jetpack, que protege muchas apps para Android populares, como Slack, Adidas, AirBnb y Nextdoor.

Tink Goals

¿Cuáles son los objetivos principales de Tink en comparación con otras bibliotecas criptográficas y cuáles son los mecanismos principales que usa para lograr esos objetivos?

En resumen, Tink tiene dos objetivos:

  1. Promueve la agilidad criptográfica: Los usuarios deben poder cambiar las claves y los algoritmos de forma sencilla.
  2. Habilitar revisiones de seguridad: Tink tiene como objetivo permitir que los usuarios escriban código cuya seguridad se pueda revisar de forma local a través de interfaces que brinden garantías de seguridad claras.

Los principales mecanismos que usa Tink para lograr estos objetivos son los siguientes:

  1. Tink proporciona interfaces y primitivas como abstracciones importantes. Estas abstracciones permiten que los usuarios escriban código que no especifica el algoritmo exacto que se usará, sino la noción de seguridad esperada.
  2. Tink usa la noción de "conjunto de claves", que es un conjunto de claves asociadas con una primitiva en particular. Como resultado, los usuarios escriben un código que funciona con varias claves.
  3. En Tink, las claves no solo se especifican en el material de clave subyacente, sino también en el algoritmo criptográfico y en todos los parámetros. Esto significa que una clave Tink siempre selecciona una función criptográfica única entre todas las funciones posibles que pueden existir, y no deja lugar para la interpretación.

En las siguientes secciones, se explican estos conceptos.

Agilidad criptográfica

Considera Ingeniería de software en Google, un libro sobre las lecciones aprendidas en el campo de la ingeniería de software, con el subtítulo "lecciones aprendidas de la programación a lo largo del tiempo". En él, los autores hacen todo lo posible para implorar las implicaciones del hecho de que las cosas cambien. Esto también afectó gran parte del diseño de Tink. En la criptografía, es importante que se prepare para el cambio. Se filtrarán las claves y se dañarán los algoritmos. Poder cambiar claves y algoritmos es crucial para muchos usuarios, y estar preparado es prudente.

Revisiones de seguridad y propiedades locales

Tink promueve el uso de interfaces, como nuestra interfaz AEAD, que permite a los usuarios encriptar datos. Entre otras garantías de seguridad, un AEAD garantiza que varias encriptaciones de la misma string generen diferentes textos cifrados.

Para ver cómo se puede usar esto, supongamos que un ingeniero desea almacenar algún ID sensible en una cookie del usuario. Podrían proporcionar una clase como la siguiente:

class IdEncrypter {
  public static IdEncrypter createFromAead(Aead aead);

  public String encrypt(long id) throws GeneralSecurityException;
  public long decrypt(String encrypted) throws GeneralSecurityException;
};

Cuando se pasa un Aead, se obtienen las siguientes propiedades:

  1. El código comunica que, para que IdEncrypter haga su trabajo, requiere un esquema de encriptación con las propiedades de seguridad que Aead proporciona. Como alternativa, una DeterministicAead no sería suficiente: IdEncrypter requiere que dos encriptaciones del mismo ID sean diferentes. Por otro lado, tomar como parámetro una instancia de un encriptador de GCM de AES (una instancia particular de un Aead) sería demasiado estricto: cualquier Aead es suficiente para que IdEncrypter haga su trabajo y no es necesario que sea un algoritmo específico.
  2. Una revisión de seguridad puede tomar en cuenta este punto. Un revisor de seguridad no necesita revisar todo el repositorio de código para verificar si en algún lugar alguien creó una subclase de Aead que no es segura para usar con IdEncrypter. En cambio, Tink proporciona propiedades de seguridad que tienen todos los objetos Aead, y el revisor puede verificar que sean suficientes.

En particular, el segundo punto requiere mucho cuidado. Los usuarios a menudo solicitan que se agreguen algoritmos que "no sean" exactamente un Aead. En el punto anterior, se ilustra por qué esto es peligroso: si hay alguna implementación de Aead disponible que no proporciona las garantías de seguridad requeridas, IdEncrypter puede volverse inseguro, y el ingeniero que realiza una revisión de seguridad debe examinar código adicional para verificar que las instancias del objeto se hayan creado de forma correcta.