Esta página descreve o formato de fio do Tink para chaves e saída primitiva. A documentação é destinada a criptógrafos que querem adicionar outros idiomas à Tink e mantenedores de outras bibliotecas de criptografia de alto nível que querem um modo compatível com fio. Ele não é destinado ao público em geral.
Serialização do conjunto de chaves
O Tink usa protobuf do Google para serializar os conjuntos de chaves.
- Um conjunto de chaves serializado binário é um proto Keyset serializado definido em tink.proto. A propriedade KeyData de uma chave é um proto serializado do tipo de chave correspondente.
- Um conjunto de chaves serializado em JSON é um proto Keyset serializado no formato JSON. O valor KeyData ainda é um proto binário serializado.
- Um conjunto de chaves criptografado é um proto EncryptedKeyset serializado definido em tink.proto. Ele contém um conjunto de chaves binário criptografado serializado e, opcionalmente, alguns metadados não criptografados de KeysetInfo.
Prefixo de saída do Tink
A maioria das primitivas do 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: é o ID da chave usada.
Algumas chaves legadas também podem ser compatíveis com o byte de versão 0x00.
Observação: este prefixo não é autenticado e não pode ser usado para fins de segurança. O Tink usa isso como uma dica para acelerar a descriptografia ou a verificação.
AEAD
Em geral, o Tink formata textos criptografados AEAD como:
prefix || IV || ciphertext || tag
a menos que especificado de outra forma na RFC correspondente. prefix está vazio ou é um prefixo de saída de 5 bytes do Tink.
AES-CTR-HMAC
Para AES-CTR-HMAC, a Tink calcula o MAC com dados associados (AD, na sigla em inglês) da seguinte maneira:
AD || IV || ciphertext || bitlen(AD)
em que bitlen(AD) é o comprimento do AD em bits representado como um número inteiro não assinado de 64 bits big-endian. Esse esquema HMAC segue o rascunho para AES-CBC-HMAC de
Mcgrew (link em inglês).
AEAD determinista
O Tink implementa a RFC 5297 para AES-SIV, colocando o vetor de inicialização sintética (SIV) no início do texto cifrado. A primitiva pode adicionar um prefixo de saída do Tink de 5 bytes.
Embora o RFC 5297 aceite uma lista de dados associados, o Tink só aceita exatamente um dado associado, que corresponde a uma lista com um elemento no RFC 5297. Dados associados vazios são uma lista com um elemento vazio, e 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 de criptografia de dados DEK usando
as primitivas AEAD do Tink. A criptografia funciona da seguinte maneira:
- Um novo
DEKé gerado usando um modelo de chave (ou parâmetros de chave) específico. - O
DEKé serializado em uma string de bytes. O formato de serialização da serialização do buffer de protocolo do proto do tipo de chave. Por exemplo, esta é uma mensagem de buffer de protocoloAesGcmKeyserializada 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
DEKserializado é criptografado por um provedor externo (por exemplo, o GCP) em umencrypted DEK. - O
DEKé usado para criptografar o texto simples com os dados associados emciphertext. Assim,ciphertexttem exatamente o mesmo formato da primitiva 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 e armazena o comprimento do encrypted DEK como um número inteiro big-endian de 32 bits.
MAC
O Tink segue as RFCs correspondentes. As primitivas podem adicionar um prefixo de saída de 5 bytes do Tink à tag.
Conjunto de PRF
O Tink segue as RFCs correspondentes. Para o conjunto de PRF, o tipo de chave difere do tipo de chave MAC do mesmo algoritmo por não incluir o comprimento da saída. As chaves do conjunto PRF nunca adicionam um prefixo de saída do Tink. Isso garante que a saída seja uma PRF.
Criptografia híbrida
O formato geral de transmissão para criptografia híbrida da Tink é o seguinte:
prefix || encapsulated_key || encrypted_data
prefix está vazio ou é um prefixo de saída de 5 bytes do Tink. Cada tipo de chave contém as informações sobre quantos bytes analisar e como analisar esses bytes de encapsulated_key.
HPKE (criptografia de chave pública híbrida)
O Tink segue o padrão HPKE definido na RFC 9180. Um conjunto de algoritmos de criptografia HPKE inclui as três primitivas a seguir.
- Mecanismo de encapsulamento de chaves (KEM)
- Função de derivação de chaves (KDF)
- Criptografia autenticada com dados associados (AEAD)
O padrão HPKE não define um formato de transmissão geral na RFC 9180, seção 10 (em inglês). A implementação de HPKE do Tink usa os seguintes valores de
encapsulated_key e encrypted_data.
encapsulated_key- Chave pública serializada do remetente
- Definido como
encna RFC 9180, seção 4.1 - Formato determinado pelo KEM HPKE específico usado
encrypted_data- Texto criptografado e tag (ou seja,
ciphertext || tagsem o IV) - Definido como
ctem RFC 9180, seção 4 - Formato determinado pelo AEAD HPKE específico usado
- Texto criptografado e tag (ou seja,
KEM baseado em Diffie-Hellman X25519
Para DHKEMs X25519, o valor enc é a chave pública Diffie-Hellman de 32 bytes do remetente.
ECIES-AEAD-HKDF
Para a implementação do ECIES-AEAD-HKDF do 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, na sigla em inglês).
KEM
Dependendo do tipo de chave, a 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. Para pontos não compactados, o byte 0x04 é seguido pelas coordenadas x e y como números inteiros de tamanho fixo. Para coordenadas compactadas, o byte 0x02 ou 0x03 e a coordenada x como um número inteiro de tamanho fixo são usados. Para X25519, é usada a definição RFC 7748 (coordenada x como um número inteiro de tamanho fixo).
DEM
Para encrypted_data, o Tink usa o mesmo formato do AEAD. Isso inclui especificar um IV.
Derivação de chaves
Primeiro, a coordenada x x_ss do ponto compartilhado é calculada. A chave do
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 completa do KEM como bytes.
Assinaturas digitais
O Tink segue as RFCs correspondentes. As primitivas podem adicionar um prefixo de saída de 5 bytes do Tink à 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 são preenchidos com zeros e têm o mesmo tamanho em bytes que a ordem da curva. Por
exemplo, para a curva NIST P-256, r e s são preenchidos com zeros até 32 bytes.
A assinatura DER é codificada usando ASN.1:
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
Em especial, a codificação é:
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
O Tink segue as práticas recomendadas para verificação de assinatura, aceitando apenas assinaturas ECDSA codificadas em DER. Assinaturas alternativas codificadas em BER são inválidas.
Isso ajuda a evitar ataques de maleabilidade de assinatura, que geralmente afetam sistemas de criptomoedas.
Valores de pré-hash ML-DSA Mu externos
A primitiva Prehash transforma uma mensagem em um valor de pré-hash, que a primitiva SignPrehash assina. Para ML-DSA no modo External Mu, conforme descrito na RFC 9881, o valor de pré-hash é de 69 bytes com o seguinte layout:
0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
mué o representante da mensagem ML-DSA, calculado comoSHAKE256(tr || 0x00 || 0x00 || message, 64), em quetré o hash de 64 bytes da chave pública, o primeiro0x00é o separador de domínio FIPS 204 para ML-DSA puro, e o segundo0x00é o comprimento da string de contexto (vazia). Comotré derivado da chave pública,mué criptograficamente vinculado a essa chave, mas a verificação da vinculação requer a mensagem original.- O prefixo de 5 bytes é o enquadramento do Tink, não faz parte de
mu. Ele associa o valor de pré-hash a uma chave específica para que o SignPrehash saiba com qual chave assinar e possa rejeitar um valor de pré-hash para o qual não tem uma chave. O prefixo são metadados simples e não vincula nada criptograficamente: qualquer pessoa pode reescrever.
A assinatura rejeita qualquer entrada que não tenha exatamente 69 bytes, que não comece com 0xff ou cujo ID de chave não corresponda a uma chave ativada no conjunto de chaves.