Formato cavo Tink

Questa pagina descrive il formato wire di Tink per le chiavi e l'output primitivo. La documentazione è rivolta ai crittografi che vogliono aggiungere altre lingue a Tink e ai manutentori di altre librerie crittografiche di alto livello che vogliono una modalità compatibile con il protocollo di rete. Non è destinato al pubblico generico.

Serializzazione del set di chiavi

Tink utilizza Google protobuf per serializzare i propri keyset.

  • Un keyset serializzato binario è un proto Keyset serializzato definito in tink.proto. La proprietà valore KeyData di una chiave è un proto serializzato del tipo di chiave corrispondente.
  • Un keyset serializzato in JSON è un proto Keyset serializzato in formato JSON. Tieni presente che il valore KeyData è ancora un proto serializzato binario.
  • Un keyset criptato è un proto EncryptedKeyset serializzato definito in tink.proto. Contiene un keyset binario serializzato criptato e, facoltativamente, alcuni metadati KeysetInfo non criptati.

Prefisso output Tink

La maggior parte delle primitive Tink supporta un prefisso di output di 5 byte composto da:

  • Versione a 1 byte: 0x01
  • Suggerimento per la chiave di 4 byte: questo è l'ID della chiave utilizzata.

Alcune chiavi legacy potrebbero supportare anche il byte di versione 0x00.

Tieni presente che questo prefisso non è autenticato e non può essere utilizzato per motivi di sicurezza. Tink lo utilizza come suggerimento per velocizzare la decriptazione o la verifica.

AEAD

In generale, Tink formatta i testi criptati AEAD come segue:

prefix || IV || ciphertext || tag

salvo diversamente specificato nella RFC corrispondente. prefix è vuoto o un prefisso di output Tink di 5 byte.

AES-CTR-HMAC

Per AES-CTR-HMAC, Tink calcola il MAC con i dati associati (AD) nel seguente modo:

AD || IV || ciphertext || bitlen(AD)

dove bitlen(AD) è la lunghezza di AD in bit rappresentata come numero intero non firmato big-endian a 64 bit. Questo schema HMAC segue la bozza per AES-CBC-HMAC di Mcgrew.

AEAD deterministico

Tink implementa RFC 5297 per AES-SIV, inserendo il vettore di inizializzazione (SIV) sintetico all'inizio del testo cifrato. La primitiva potrebbe aggiungere un prefisso di output Tink di 5 byte.

Sebbene RFC 5297 supporti un elenco di dati associati, Tink supporta solo esattamente un dato associato, che corrisponde a un elenco con un elemento in RFC 5297. I dati associati vuoti sono un elenco con un elemento vuoto e non un elenco vuoto.

Streaming AEAD

Vedi AES-CTR HMAC e AES-GCM-HKDF.

Crittografia envelope

La crittografia envelope cripta i dati con una chiave di crittografia dei dati DEK utilizzando le primitive AEAD di Tink. La crittografia funziona nel seguente modo:

  • Viene generato un nuovo DEK utilizzando un determinato modello di chiave (o parametri della chiave).
  • DEK viene serializzato in una stringa di byte. Il formato di serializzazione della serializzazione del buffer di protocollo del proto del tipo di chiave. Ad esempio, questo è un messaggio AesGcmKey buffer di protocollo serializzato definito in aes_gcm.proto per la DEK del tipo di chiave AES GCM. Consulta Serializzazione del buffer di protocollo per scoprire come serializzare un buffer di protocollo.
  • DEK serializzato viene criptato da un fornitore esterno (ad esempio GCP) in un encrypted DEK.
  • DEK viene utilizzato per criptare il testo non crittografato con i dati associati in ciphertext. Pertanto, ciphertext ha esattamente lo stesso formato della primitiva AEAD corrispondente a DEK.

Il formato di output della crittografia envelope è il seguente:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length è di 4 byte e memorizza la lunghezza di encrypted DEK come numero intero big-endian a 32 bit.

MAC

Tink segue le RFC corrispondenti. I primitivi potrebbero aggiungere un prefisso di output Tink di 5 byte al tag.

Set PRF

Tink segue le RFC corrispondenti. Tieni presente che per PRF Set the key type il tipo di chiave è diverso dal tipo di chiave MAC dello stesso algoritmo perché non include la lunghezza dell'output. Le chiavi PRF Set non aggiungono mai un prefisso di output Tink. In questo modo, l'output è effettivamente una PRF.

Crittografia ibrida

Il formato generale del cavo per la crittografia ibrida Tink è il seguente:

prefix || encapsulated_key || encrypted_data

prefix è vuoto o un prefisso di output Tink di 5 byte. Ogni tipo di chiave contiene le informazioni su quanti byte analizzare e come analizzarli da encapsulated_key.

HPKE (Hybrid Public Key Encryption)

Tink segue lo standard HPKE definito nella RFC 9180. Una suite di cifratura HPKE include le seguenti tre primitive.

  • Meccanismo di incapsulamento chiave (KEM)
  • Funzione di derivazione della chiave (KDF)
  • Crittografia autenticata con dati associati (AEAD)

Lo standard HPKE non definisce un formato di trasmissione generale nella RFC 9180, sezione 10. L'implementazione HPKE di Tink utilizza i seguenti valori encapsulated_key e encrypted_data.

  • encapsulated_key
    • Chiave pubblica serializzata del mittente
    • Definito come enc nella RFC 9180, sezione 4.1
    • Formato determinato dal KEM HPKE specifico utilizzato
  • encrypted_data
    • Testo crittografato e tag (ovvero ciphertext || tag senza IV)
    • Definito come ct nella RFC 9180, sezione 4
    • Formato determinato dall'AEAD HPKE specifico utilizzato
KEM basato su X25519 Diffie-Hellman

Per X25519 DHKEM, il valore enc è la chiave pubblica Diffie-Hellman di 32 byte del mittente.

ECIES-AEAD-HKDF

Per l'implementazione di ECIES-AEAD-HKDF di Tink, encapsulated_key è l'output del meccanismo di incapsulamento della chiave (KEM) e encrypted_data è l'output del meccanismo di incapsulamento dei dati (DEM).

KEM

A seconda del tipo di chiave, Tink utilizza punti della curva ellittica compressi e non compressi, seguendo gli standard di codifica RFC 8422/ANSI.X9-62.2005. Per i punti non compressi, il byte 0x04 è seguito dalle coordinate x e y come numeri interi di dimensioni fisse. Per le coordinate compresse, vengono utilizzati il byte 0x02 o 0x03 e la coordinata x come numero intero di dimensioni fisse. Per X25519, viene utilizzata la definizione RFC 7748 (coordinata x come numero intero di dimensioni fisse).

DEM

Per encrypted_data, Tink utilizza lo stesso formato di AEAD. Ciò include la specifica di un IV.

Derivazione delle chiavi

Innanzitutto, viene calcolata la coordinata x x_ss del punto condiviso. La chiave per AEAD viene quindi impostata su:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

dove encapsulated_key è l'output KEM completo in byte.

Firme digitali

Tink segue le RFC corrispondenti. I primitivi potrebbero aggiungere un prefisso di output Tink di 5 byte al tag generato.

ECDSA

A seconda del campo EcdsaSignatureEncoding nella chiave, il formato di una firma ECDSA è IEEE P1363 o ASN.1 DER.

Il formato della firma IEEE P1363 è r || s, dove r e s sono riempiti con zeri e hanno le stesse dimensioni in byte dell'ordine della curva. Ad esempio, per la curva NIST P-256, r e s vengono riempiti con zeri fino a 32 byte.

La firma DER è codificata utilizzando ASN.1:

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

In particolare, la codifica è:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink segue le best practice per la verifica della firma, accettando solo firme ECDSA con codifica DER (le firme con codifica BER alternativa non sono valide).

Ciò contribuisce a prevenire attacchi di malleabilità della firma, che spesso interessano i sistemi di criptovalute.

Valori prehash ML-DSA di Mu esterno

La primitiva Prehash trasforma un messaggio in un valore prehash, che viene poi firmato dalla primitiva SignPrehash. Per ML-DSA in modalità External Mu, come descritto in RFC 9881, il valore pre-hash è di 69 byte con il seguente layout:

0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
  • mu è il rappresentante del messaggio ML-DSA, calcolato come SHAKE256(tr || 0x00 || 0x00 || message, 64), dove tr è l'hash a 64 byte della chiave pubblica, il primo 0x00 è il separatore di dominio FIPS 204 per ML-DSA puro e il secondo 0x00 è la lunghezza della stringa di contesto (vuota). Poiché tr deriva dalla chiave pubblica, mu è crittograficamente associato a questa chiave, anche se il controllo dell'associazione richiede il messaggio originale.
  • Il prefisso di 5 byte è l'inquadratura di Tink, non fa parte di mu. Associa il valore pre-hash a una chiave specifica, in modo che SignPrehash sappia con quale chiave firmare e possa rifiutare un valore pre-hash per cui non ha una chiave. Il prefisso è un semplice metadato e non vincola nulla a livello crittografico: chiunque può riscriverlo.

La firma rifiuta qualsiasi input che non sia esattamente di 69 byte, che non inizi con 0xff o il cui ID chiave non corrisponda a una chiave abilitata nel relativo keyset.