É importante que o Tink se comporte da mesma forma em todas as linguagens de programação. Esse conceito não é simples, mas o mais importante é:
Para manter a consistência, o Tink usa testes multilíngues, que podem ser encontrados no repositório multilíngue do GitHub. Esses testes verificam a consistência e a interoperabilidade de diferentes linguagens.
No entanto, definir a consistência não é tão simples quanto se imagina. Por isso, esta página apresenta nossa definição de trabalho. Basicamente, o Tink oferece dois tipos de consistência:
- Consistência de avaliação:para um determinado conjunto de chaves1, se a criação da primitiva for bem-sucedida em duas linguagens, elas se comportarão da mesma forma.
- Consistência de criação:a criação de uma primitiva é bem-sucedida em uma linguagem se ela for compatível com todos os tipos de chave em um conjunto de chaves, conforme documentado na nossa lista de tipos de chave compatíveis.
Contexto
Em geral, o Tink oferece as seguintes APIs:
Manipulação de conjuntos de chaves:o Tink fornece APIs para adicionar novas chaves a um conjunto de chaves, remover chaves de um conjunto de chaves e alterar a chave primária em um conjunto de chaves.
Serialização de conjunto de chaves:o Tink fornece APIs para serializar um conjunto de chaves em uma sequência de bytes e, por outro lado, analisar um conjunto de chaves de uma sequência de bytes.
Criação de primitivas:o Tink fornece uma API para criar uma interface para uma primitiva de um conjunto de chaves. Por exemplo, para criar um objeto
Aeadde um conjunto de chaves em Java, o usuário chamakeysetHandle.getPrimitive(config, Aead.class).Uso de primitivas:a interface produzida na etapa de criação de primitivas fornece uma API para realizar operações criptográficas.
Há duas perguntas importantes sobre essas APIs:
Criação:para um determinado conjunto de chaves serializado, idioma e primitiva, é possível criar a primitiva com base nesse conjunto de chaves no idioma?
Avaliação:se uma primitiva puder ser criada em alguma linguagem de um determinado conjunto de chaves, como o objeto primitivo se comporta?
É importante observar que o Tink não oferece 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 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, que falham 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 um AEAD em Java não puder descriptografar a criptografia do AEAD em C++, os usuários terão um problema sério.
Em geral, o Tink busca ser consistente de maneira óbvia para as primitivas. 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 há 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 comprimento 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 outras linguagens, a criptografia
é permitida para essas entradas.
Portanto, o Tink oferece consistência de avaliação: para um determinado conjunto de chaves, se a criação da primitiva for bem-sucedida em dois idiomas, eles vão se comportar da mesma forma.
A exceção é que algumas operações podem falhar em circunstâncias excepcionais.
Consistência na criação
A criação de primitivas nem sempre é bem-sucedida para todos os conjuntos de chaves. Por exemplo, o Tink não permite que os usuários criem uma AesSivKey se o material da chave tiver um comprimento de 128 bits.
No entanto, o Tink oferece consistência da seguinte maneira: se duas linguagens forem compatíveis com um tipo de chave, o conjunto de chaves para o qual a primitiva pode ser criada será o mesmo. Se uma linguagem não for compatível com um tipo de chave, nenhum objeto primitivo poderá ser criado.
A consistência de criação é menos importante do que a consistência de avaliação, e há mais exceções a essa regra do que para a consistência de 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 opção de curva elíptica para uso no acordo de chaves, mas o Java não é compatível com X25519. Portanto, a criação de uma chave usando X25519 em Java falha.
-
Neste documento, usamos o termo
Keysetpara indicar o objeto chamadoKeysetHandlena maioria das linguagens. ↩