Nesta página, descrevemos o formato de cabo do Tink para chaves e saída primitiva. A documentação é destinada a criptógrafos que querem adicionar outras linguagens ao Tink e aos mantenedores de outras bibliotecas de criptografia de alto nível que querem um modo compatível com wireframes. Ele não é indicado para o público em geral.
Serialização do conjunto de chaves
O Tink usa o protobuf do Google para serializar os conjuntos de chaves.
- Um conjunto de chaves binário serializado é um proto do conjunto de chaves serializado definido no tink.proto. A propriedade de valor KeyData de uma chave é um protótipo serializado do tipo de chave correspondente.
- Um conjunto de chaves serializado JSON é um proto de conjunto de chaves serializado no formato JSON. Observe que o valor KeyData ainda é um proto serializado binário.
- Um conjunto de chaves criptografado é um proto EncryptedKeyst serializado definido no tink.proto. Ela contém um conjunto de chaves serializado binário criptografado e, opcionalmente, alguns metadados KeysetInfo não criptografados.
Prefixo de saída do Tink
A maioria dos primitivos Tink é compatível com um prefixo de saída de 5 bytes que consiste em:
- Versão de 1 byte:
0x01
- Dica de chave de 4 bytes: esse é o ID da chave usada.
Algumas chaves legadas também podem ser compatíveis com o byte de versão 0x00
.
Esse prefixo não é autenticado e não pode ser usado para fins de segurança. Ela é usada pela Tink como uma dica para acelerar a descriptografia ou a verificação.
AEAD
Em geral, a Tink formata os textos criptografados AEAD como:
prefix || IV || ciphertext || tag
a menos que especificado de outra forma no RFC correspondente. prefix
está vazio
ou é um prefixo de saída Tink de 5 bytes.
AES-CTR-HMAC
Para o AES-CTR-HMAC, o Tink calcula o MAC com os dados associados (AD) da seguinte maneira:
AD || IV || ciphertext || bitlen(AD)
em que bitlen(AD)
é o comprimento do AD em bits representado como número inteiro não assinado
big-endian de 64 bits. Este esquema de HMAC segue o rascunho para AES-CBC-HMAC do Mcgrew.
AEAD determinista
O Tink implementa o RFC 5297 para AES-SIV, colocando o vetor de inicialização sintética (SIV, na sigla em inglês) no início do texto criptografado. O primitivo pode adicionar um prefixo de saída do Tink de 5 bytes.
Enquanto o RFC 5297 oferece suporte a uma lista de dados associados, o Tink só aceita exatamente um dado associado, que corresponde a uma lista com um elemento no RFC 5297. Um dado associado vazio é uma lista com um elemento vazio, não uma lista vazia.
AEAD de streaming
Consulte HMAC AES-CTR e AES-GCM-HKDF.
Criptografia de envelope
A criptografia de envelope criptografa os dados com uma chave DEK
usando
os primitivos AEAD do Tink. A criptografia funciona da seguinte maneira:
- Um novo
DEK
é gerado usando um determinado modelo de chave (ou parâmetros principais). - O
DEK
é serializado em uma string de bytes. O formato de serialização da serialização do buffer de protocolo do tipo de chave proto. Por exemplo, essa é uma mensagem serializada do buffer de protocoloAesGcmKey
definida em aes_gcm.proto para DEK do tipo de chave AES GCM. Consulte serialização de buffer de protocolo para saber como serializar um buffer de protocolo. - O
DEK
serializado é criptografado por um provedor externo (por exemplo, GCP) em umencrypted DEK
. - O
DEK
é usado para criptografar o texto simples com os dados associados emciphertext
. Portanto,ciphertext
tem exatamente o mesmo formato que o primitivo AEAD correspondente aoDEK
.
O formato de saída da criptografia de envelope é o seguinte:
encrypted DEK length || encrypted DEK || ciphertext
O encrypted DEK length
tem 4 bytes, armazenando o comprimento da encrypted DEK
como um número inteiro big-endian de 32 bits.
MAC
O Tink segue os RFCs correspondentes. Os primitivos podem adicionar um prefixo de saída Tink de 5 bytes à tag.
PRF definido
O Tink segue os RFCs correspondentes. Para PRF Set, o tipo de chave difere do tipo de chave MAC do mesmo algoritmo ao não incluir o comprimento da saída. As chaves "PRF set" nunca adicionam um prefixo de saída do Tink. Isso garante que a saída seja realmente um PRF.
Criptografia híbrida
O formato de transmissão geral para a criptografia híbrida do Tink é o seguinte:
prefix || encapsulated_key || encrypted_data
prefix
está vazio ou é um prefixo de saída do Tink de 5 bytes. Cada tipo de chave contém
as informações sobre quantos bytes serão analisados e como analisar esses bytes com
encapsulated_key
.
HPKE (criptografia de chave pública híbrida)
A Tink segue o padrão HPKE definido na RFC 9180 (link em inglês). Um pacote de criptografia HPKE inclui os três primitivos a seguir.
- Mecanismo de encapsulamento de chaves (KEM)
- Função de derivação de chaves (KDF, na sigla em inglês)
- Criptografia autenticada com dados associados (AEAD, na sigla em inglês)
O padrão HPKE não define um formato de condutor neutro na RFC 9180, seção 10. A implementação HPKE da Tink usa os seguintes valores encapsulated_key
e encrypted_data
.
encapsulated_key
- Chave pública serializada do remetente
- Definido como
enc
na RFC 9180, seção 4.1 - Formato determinado pelo HPKE KEM específico usado
encrypted_data
- Texto criptografado e tag (por exemplo,
ciphertext || tag
sem o IV) - Definido como
ct
na RFC 9180, seção 4 - Formato determinado pelo HPKE AEAD específico usado
- Texto criptografado e tag (por exemplo,
KEM X25519 baseado em Diffie-Hellman
Para DHKEMs X25519, o valor enc
é a chave pública Diffie-Hellman de 32 bytes do remetente.
ECIES-AEAD-HKDF
Para a implementação ECIES-AEAD-HKDF da Tink, encapsulated_key
é a saída
do Mecanismo de encapsulamento de chaves (KEM, na sigla em inglês) e encrypted_data
é a saída
do Mecanismo de encapsulamento de dados (DEM).
KEM
Dependendo do tipo de chave, o Tink usa pontos de curva elíptica compactados e não
compactados, seguindo os padrões de codificação RFC 8422/ANSI.X9-62.2005
(link em inglês). Para
pontos não compactados, o byte 0x04
é seguido pela coordenada x
e pela y
como números inteiros de tamanho fixo. Para coordenadas compactadas, são usados o byte 0x02
ou 0x03
e a coordenada x
como um número inteiro de tamanho fixo. Para X25519
, a definição RFC 7748 é usada (coordenada x
como número inteiro de tamanho fixo).
DEM
Para encrypted_data
, o Tink usa o mesmo formato que o AEAD. Isso inclui a especificação de um IV.
Derivação de chaves
Primeiro, a coordenada x x_ss
do ponto compartilhado é calculada. A chave da
AEAD é definida como:
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
em que encapsulated_key
é a saída KEM completa como bytes.
Assinaturas digitais
O Tink segue os RFCs correspondentes. Os primitivos podem adicionar um prefixo de saída Tink de 5 bytes à tag gerada.
ECDSA
Dependendo do campo EcdsaSignatureEncoding na chave,
o formato de uma assinatura ECDSA é IEEE P1363
ou ASN.1 DER
.
O formato da assinatura IEEE P1363
é r || s
, em que r
e s
não têm padding e têm o mesmo tamanho em bytes que a ordem da curva. Por
exemplo, para a curva NIST P-256
, r
e s
têm preenchimento zero para 32 bytes.
A assinatura DER é codificada usando ASN.1
:
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
Especificamente, a codificação é:
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
O Tink segue as práticas recomendadas para a verificação de assinaturas, aceitando apenas assinaturas ECDSA codificadas por DER. Assinaturas alternativas codificadas por BER são inválidas.
Isso ajuda a evitar ataques de maleabilidade da assinatura, que geralmente afetam sistemas de criptomoedas.