Sprievodca Google Tink
1. Úvod
V súčasnosti mnoho vývojárov používa na ochranu používateľských údajov kryptografické techniky.
V kryptografii môžu mať malé chyby pri implementácii vážne následky a pochopiť, ako správne implementovať kryptografiu, je zložitá a časovo náročná úloha.
V tomto výučbe popíšeme Tink - viacjazyčnú medziplatformovú kryptografickú knižnicu, ktorá nám môže pomôcť implementovať bezpečný kryptografický kód.
2. Závislosti
Na importovanie Tink môžeme použiť Maven alebo Gradle.
Pre náš tutoriál pridáme iba závislosť Tink's Maven:
com.google.crypto.tink tink 1.2.2
Aj keď sme namiesto toho mohli použiť Gradle:
závislosti {compile 'com.google.crypto.tink: tink: latest'}
3. Inicializácia
Pred použitím niektorého z Tink API je potrebné ich inicializovať.
Ak potrebujeme v Tinke použiť všetky implementácie všetkých primitívov, môžeme použiť TinkConfig.register () metóda:
TinkConfig.register ();
Aj keď napríklad potrebujeme iba primitív AEAD, môžeme použiť AeadConfig.register () metóda:
AeadConfig.register ();
Pre každú implementáciu je tiež k dispozícii prispôsobiteľná inicializácia.
4. Tink Primitive
Hlavné objekty, ktoré knižnica používa, sa nazývajú primitívne objekty, ktoré v závislosti od typu obsahujú rôzne kryptografické funkcie.
Primitív môže mať viac implementácií:
Primitívne | Implementácie |
---|---|
AEAD | AES-EAX, AES-GCM, AES-CTR-HMAC, obálka KMS, CHACHA20-POLY1305 |
Streamovanie AEAD | AES-GCM-HKDF-STREAMING, AES-CTR-HMAC-STREAMING |
Deterministické AEAD | AEAD: AES-SIV |
MAC | HMAC-SHA2 |
Digitálny podpis | ECDSA nad NIST krivkami, ED25519 |
Hybridné šifrovanie | ECIES s AEAD a HKDF, (NaCl CryptoBox) |
Primitívum môžeme získať volaním metódy getPrimitive () zodpovedajúcej továrenskej triedy a Sada kľúčov:
Aead aead = AeadFactory.getPrimitive (keysetHandle);
4.1. Sada kľúčov
V poriadku na zabezpečenie kryptografických funkcií potrebuje každý primitív kľúčovú štruktúru ktorý obsahuje všetky kľúčové materiály a parametre.
Tink poskytuje objekt - KeysetHandle - ktorý obsahuje sadu kľúčov s niektorými ďalšími parametrami a metadátami.
Pred inštanciou primitívu teda musíme vytvoriť a Sada kľúčov objekt:
KeysetHandle keysetHandle = KeysetHandle.generateNew (AeadKeyTemplates.AES256_GCM);
A po vygenerovaní kľúča by sme ho možno chceli vytrvať:
Reťazec keysetFilename = "keyset.json"; CleartextKeysetHandle.write (keysetHandle, JsonKeysetWriter.withFile (nový súbor (keysetFilename)));
Potom ho môžeme následne načítať:
Reťazec keysetFilename = "keyset.json"; KeysetHandle keysetHandle = CleartextKeysetHandle.read (JsonKeysetReader.withFile (nový súbor (keysetFilename)));
5. Šifrovanie
Tink poskytuje niekoľko spôsobov použitia algoritmu AEAD. Pozrime sa.
5.1. AEAD
AEAD poskytuje overené šifrovanie s pridruženými údajmi, čo znamená, že môžeme šifrovať holý text a voliteľne poskytnúť súvisiace údaje, ktoré by mali byť autentifikované, ale nie šifrované.
Upozorňujeme, že tento algoritmus zaisťuje autenticitu a integritu súvisiacich údajov, nie však ich utajenie.
Na zašifrovanie údajov jednou z implementácií AEAD, ako sme už videli, je potrebné inicializovať knižnicu a vytvoriť sada kľúčov:
AeadConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (AeadKeyTemplates.AES256_GCM);
Keď to urobíme, môžeme získať primitív a zašifrovať požadované údaje:
Reťazec holý text = "baeldung"; Reťazec associatedData = "Tink"; Aead aead = AeadFactory.getPrimitive (keysetHandle); byte [] ciphertext = aead.encrypt (holý text.getBytes (), associatedData.getBytes ());
Ďalej môžeme dešifrovať šifrový text pomocou dešifrovať () metóda:
Reťazec dešifrovaný = nový Reťazec (aead.decrypt (ciphertext, associatedData.getBytes ()));
5.2. Streamovanie AEAD
Podobne keď sú dáta na šifrovanie príliš veľké na to, aby sa dali spracovať v jednom kroku, môžeme použiť streamovací primitív AEAD:
AeadConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (StreamingAeadKeyTemplates.AES128_CTR_HMAC_SHA256_4KB); StreamingAead streamingAead = StreamingAeadFactory.getPrimitive (keysetHandle); FileChannel cipherTextDestination = nový FileOutputStream ("cipherTextFile"). GetChannel (); WritableByteChannel encryptingChannel = streamingAead.newEncryptingChannel (cipherTextDestination, associatedData.getBytes ()); ByteBuffer buffer = ByteBuffer.allocate (CHUNK_SIZE); InputStream in = nový FileInputStream ("plainTextFile"); while (in.available ()> 0) {in.read (buffer.array ()); encryptingChannel.write (vyrovnávacia pamäť); } encryptingChannel.close (); in.close ();
V podstate sme potrebovali WriteableByteChannel aby sme to dosiahli.
Takže na dešifrovanie cipherTextFile, chceli by sme použiť a ReadableByteChannel:
FileChannel cipherTextSource = nový FileInputStream ("cipherTextFile"). GetChannel (); ReadableByteChannel decryptingChannel = streamingAead.newDecryptingChannel (cipherTextSource, associatedData.getBytes ()); OutputStream out = nový FileOutputStream ("plainTextFile"); int cnt = 1; do {buffer.clear (); cnt = decryptingChannel.read (vyrovnávacia pamäť); out.write (buffer.array ()); } while (cnt> 0); decryptingChannel.close (); out.close ();
6. Hybridné šifrovanie
Okrem symetrického šifrovania implementuje Tink aj niekoľko primitívov pre hybridné šifrovanie.
S hybridným šifrovaním môžeme získať efektívnosť symetrických kľúčov a pohodlie asymetrických kľúčov.
Jednoducho povedané, na šifrovanie holého textu použijeme symetrický kľúč a verejný kľúč na šifrovanie iba symetrického kľúča.
Všimnite si, že poskytuje iba tajomstvo, nie autenticitu totožnosti odosielateľa.
Pozrime sa teda, ako sa používa HybridEncrypt a HybridDecrypt:
TinkConfig.register (); KeysetHandle privateKeysetHandle = KeysetHandle.generateNew (HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256); KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle (); Reťazec holý text = "baeldung"; String contextInfo = "Tink"; HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive (publicKeysetHandle); HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive (privateKeysetHandle); byte [] ciphertext = hybridEncrypt.encrypt (holý text.getBytes (), contextInfo.getBytes ()); byte [] plaintextDecrypted = hybridDecrypt.decrypt (ciphertext, contextInfo.getBytes ());
The contextInfo sú implicitné verejné údaje z kontextu, ktorý môže byť nulový alebo prázdne alebo použité ako vstup „asociovaných údajov“ pre šifrovanie AEAD alebo ako vstup „CtxInfo“ pre HKDF.
The šifrový text umožňuje kontrolu integrity contextInfo ale nie jeho tajomstvo alebo autenticita.
7. Overovací kód správy
Tink podporuje aj overovacie kódy správ alebo MAC.
MAC je blok niekoľkých bajtov, ktorý môžeme použiť na autentifikáciu správy.
Pozrime sa, ako môžeme vytvoriť MAC a potom overiť jeho pravosť:
TinkConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (MacKeyTemplates.HMAC_SHA256_128BITTAG); Údaje reťazca = "baeldung"; Mac mac = MacFactory.getPrimitive (keysetHandle); byte [] tag = mac.computeMac (data.getBytes ()); mac.verifyMac (tag, data.getBytes ());
V prípade, že údaje nie sú autentické, použite metódu verifyMac () hodí a GeneralSecurityException.
8. Digitálny podpis
Rovnako ako šifrovacie API, Tink podporuje digitálne podpisy.
Na implementáciu digitálneho podpisu používa knižnica PublicKeySign - primitívne na podpisovanie údajov a - PublickeyVerify na overenie:
TinkConfig.register (); KeysetHandle privateKeysetHandle = KeysetHandle.generateNew (SignatureKeyTemplates.ECDSA_P256); KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle (); Údaje reťazca = "baeldung"; PublicKeySign signer = PublicKeySignFactory.getPrimitive (privateKeysetHandle); Verifikátor PublicKeyVerify = PublicKeyVerifyFactory.getPrimitive (publicKeysetHandle); byte [] podpis = signer.sign (data.getBytes ()); verifier.verify (podpis, data.getBytes ());
Podobne ako v predchádzajúcej metóde šifrovania, keď je podpis neplatný, dostaneme a GeneralSecurityException.
9. Záver
V tomto článku sme predstavili knižnicu Google Tink pomocou jej implementácie Java.
Videli sme, ako sa používajú na šifrovanie a dešifrovanie údajov a ako chrániť ich integritu a autenticitu. Okrem toho sme videli, ako podpisovať údaje pomocou rozhraní API pre digitálny podpis.
Vzorový kód je ako vždy k dispozícii na stránkach GitHub.