Consistência

É importante que o Tink se comporte "da mesma forma" em todas as linguagens de programação. Esse conceito não é simples, mas é essencial:

Para manter a consistência, a Tink usa testes em várias linguagens, que podem ser encontrados no repositório de várias linguagens do GitHub (em inglês). Esses testes verificam a consistência e a interoperabilidade de linguagens diferentes.

No entanto, definir a consistência não é tão simples quanto se poderia esperar. Portanto, esta página fornece nossa definição de trabalho. Basicamente, a Tink oferece dois tipos de consistência:

contexto

De modo geral, a Tink fornece as seguintes APIs:

  • Manipulação de conjunto de chaves:o Tink fornece APIs para adicionar novas chaves a um conjunto de chaves, remover e alterar a chave primária em um conjunto.

  • Serialização do conjunto de chaves:o Tink fornece APIs para serializar um conjunto de chaves para uma sequência de bytes e, por outro lado, analisar um conjunto de chaves a partir de uma sequência de bytes.

  • Criação primitiva:o Tink fornece uma API para criar uma interface para um primitivo a partir de um conjunto de chaves. Por exemplo, para criar um objeto Aead com base em um conjunto de chaves em Java, o usuário chama keysetHandle.getPrimitive(Aead.class, config).

  • Uso primitivo:a interface produzida na etapa de criação primitiva fornece uma API para executar operações criptográficas.

Há duas perguntas importantes a serem feitas sobre essas APIs:

  • Criação: para um determinado conjunto de chaves serializado, linguagem e primitivo, é possível criar o primitivo a partir desse conjunto de chaves na linguagem?

  • Avaliação: como o objeto primitivo pode ser criado em alguma linguagem com base em um determinado conjunto de chaves?

É importante observar que o Tink não fornece consistência ao analisar um conjunto de chaves. Por exemplo, é possível que o Tink C++

  • analisa com sucesso conjuntos de chaves que contêm as chaves CHACHA20-POLY1305, mesmo que as operações AEAD CHACHA20-POLY1305 não sejam implementadas no Tink;
  • analisa com sucesso conjuntos de chaves com chaves de 1 byte, o que falha em todas as operações criptográficas.

Esses comportamentos podem mudar em versões secundárias.

Consistência da avaliação

A consistência da avaliação é mais importante do que qualquer consistência no processo de criação: se uma AEAD em Java não puder descriptografar a criptografia da AEAD em C++, os usuários terão um problema sério.

Em geral, o objetivo da Tink é ser consistente da maneira óbvia para os primitivos. Por exemplo, se um binário C++ calcular uma assinatura com public_key_sign->Sign(data), a chamada de verificação Java correspondente publicKeyVerify.verify(signature, data) deverá ser bem-sucedida.

No entanto, mesmo aqui existem algumas ressalvas. Por exemplo, o tipo de retorno de aead.Encrypt em Java é um byte[]. De acordo com a Especificação da linguagem Java (JLS, na sigla em inglês) §10.7, o tamanho de uma matriz é do tipo int, que de acordo com §JLS 4.2.1 pode ser no máximo 2147483647. Portanto, a criptografia de uma matriz com comprimento de 2147483647 falha em Java: a criptografia tem alguma sobrecarga, o que significa que a saída seria muito longa. No entanto, em outros idiomas, a criptografia pode ser bem-sucedida para essas entradas.

Portanto, a Tink oferece consistência de avaliação: para um determinado conjunto de chaves, se a criação do primitivo for bem-sucedida em duas linguagens, elas se comportarão da mesma forma.

A exceção é que algumas operações podem falhar em algumas circunstâncias excepcionais.

Consistência de criação

A criação de primitivos nem sempre tem êxito para todos os conjuntos de chaves. Por exemplo, o Tink não permitirá que os usuários criem uma AesSivKey se o material da chave tiver um comprimento de 128 bits.

No entanto, a Tink oferece consistência da seguinte forma: se duas linguagens forem compatíveis com um tipo de chave, o conjunto de chaves para as quais o primitivo pode ser criado coincide. Obviamente, se uma linguagem não for compatível com um tipo de chave, nenhum objeto primitivo poderá ser criado.

A consistência da criação é menos importante do que a da avaliação, e há mais exceções a essa regra do que a consistência da avaliação. Essas limitações estão documentadas na nossa lista de tipos de chave compatíveis. Por exemplo, para o tipo de chave ECIES, o Tink oferece uma escolha de qual curva elíptica usar para a concordância de chaves, mas o Java não oferece suporte a X25519. Portanto, a criação de uma chave usando X25519 em Java falha.


  1. Neste documento, usamos o termo Keyset para denotar o objeto chamado KeysetHandle na maioria dos idiomas.