Vodič za Google Tink

1. Uvod

U današnje vrijeme mnogi programeri koriste kriptografske tehnike za zaštitu korisničkih podataka.

U kriptografiji male pogreške u implementaciji mogu imati ozbiljne posljedice, a razumijevanje pravilne implementacije kriptografije složen je i dugotrajan zadatak.

U ovom uputstvu opisat ćemo Tink - višejezičnu kriptografsku knjižnicu s više platformi koja nam može pomoći u implementaciji sigurnog kriptografskog koda.

2. Ovisnosti

Za uvoz Tinka možemo koristiti Maven ili Gradle.

Za naš vodič samo ćemo dodati Tinkovu ovisnost o Mavenu:

 com.google.crypto.tink tink 1.2.2 

Iako smo umjesto toga mogli koristiti Gradle:

ovisnosti {compile 'com.google.crypto.tink: tink: latest'}

3. Inicijalizacija

Prije upotrebe bilo kojeg API-ja Tink, moramo ih inicijalizirati.

Ako trebamo koristiti sve implementacije svih primitiva u Tinku, možemo koristiti TinkConfig.register () metoda:

TinkConfig.register ();

Dok, na primjer, ako nam je potreban samo AEAD primitiv, možemo koristiti AeadConfig.register () metoda:

AeadConfig.register ();

Također je predviđena prilagodljiva inicijalizacija za svaku implementaciju.

4. Tink primitivi

Glavni objekti koje knjižnica koristi nazivaju se primitivima koji, ovisno o vrsti, sadrže različite kriptografske funkcije.

Primitiv može imati više implementacija:

PrimitivnoProvedbe
AEADAES-EAX, AES-GCM, AES-CTR-HMAC, omotnica KMS, CHACHA20-POLY1305
Strujanje AEADAES-GCM-HKDF-STREAMING, AES-CTR-HMAC-STREAMING
Deterministički AEADAEAD: AES-SIV
MACHMAC-SHA2
Digitalni potpisECDSA preko NIST krivulja, ED25519
Hibridno šifriranjeECIES s AEAD i HKDF, (NaCl CryptoBox)

Primitiv možemo dobiti pozivanjem metode getPrimitive () odgovarajuće tvorničke klase koja ga prolazi a KeysetHandle:

Aead aead = AeadFactory.getPrimitive (keysetHandle); 

4.1. KeysetHandle

U redu kako bi pružio kriptografsku funkcionalnost, svaki primitiv treba ključnu strukturu koji sadrži sav ključni materijal i parametre.

Tink pruža objekt - KeysetHandle - koji obavija skup ključeva s nekim dodatnim parametrima i metapodacima.

Dakle, prije instanciranja primitiva, moramo stvoriti KeysetHandle objekt:

KeysetHandle keysetHandle = KeysetHandle.generateNew (AeadKeyTemplates.AES256_GCM);

A nakon generiranja ključa, možda bismo ga željeli ustrajati:

Niz keysetFilename = "keyset.json"; CleartextKeysetHandle.write (keysetHandle, JsonKeysetWriter.withFile (nova datoteka (keysetFilename)));

Zatim ga možemo naknadno učitati:

Niz keysetFilename = "keyset.json"; KeysetHandle keysetHandle = CleartextKeysetHandle.read (JsonKeysetReader.withFile (nova datoteka (keysetFilename)));

5. Šifriranje

Tink pruža više načina primjene AEAD algoritma. Pogledajmo.

5.1. AEAD

AEAD omogućuje provjeru autentičnosti šifriranja s pridruženim podacima, što znači da možemo šifrirati otvoreni tekst i, prema želji, pružiti povezane podatke koji bi trebali biti ovjereni, ali ne i šifrirani.

Imajte na umu da ovaj algoritam osigurava autentičnost i cjelovitost povezanih podataka, ali ne i njihovu tajnost.

Za šifriranje podataka s jednom od implementacija AEAD-a, kao što smo prethodno vidjeli, moramo inicijalizirati knjižnicu i stvoriti keysetHandle:

AeadConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (AeadKeyTemplates.AES256_GCM);

Nakon što to učinimo, možemo dobiti primitiv i šifrirati željene podatke:

Niz otvoreni tekst = "baeldung"; String linkedData = "Tink"; Aead aead = AeadFactory.getPrimitive (keysetHandle); bajt [] ciphertext = aead.encrypt (plaintext.getBytes (), associatedData.getBytes ());

Dalje, možemo dešifrirati šifrirani tekst koristiti dešifriraj () metoda:

Niz dešifriran = novi niz (aead.decrypt (šifrirani tekst, pridruženiData.getBytes ()));

5.2. Strujanje AEAD

Slično tome, kada su podaci za šifriranje preveliki da bi se mogli obraditi u jednom koraku, možemo koristiti primitivni AEAD za strujanje:

AeadConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (StreamingAeadKeyTemplates.AES128_CTR_HMAC_SHA256_4KB); StreamingAead streamingAead = StreamingAeadFactory.getPrimitive (keysetHandle); FileChannel cipherTextDestination = novi FileOutputStream ("cipherTextFile"). GetChannel (); WritableByteChannel encryptingChannel = streamingAead.newEncryptingChannel (cipherTextDestination, associatedData.getBytes ()); ByteBuffer međuspremnik = ByteBuffer.allocate (CHUNK_SIZE); InputStream u = new FileInputStream ("plainTextFile"); while (in.available ()> 0) {in.read (buffer.array ()); encryptingChannel.write (međuspremnik); } encryptingChannel.close (); in.close ();

U osnovi, trebali smo WriteableByteChannel da se to postigne.

Dakle, za dešifriranje cipherTextFile, željeli bismo koristiti ReadableByteChannel:

FileChannel cipherTextSource = novi FileInputStream ("cipherTextFile"). GetChannel (); ReadableByteChannel decryptingChannel = streamingAead.newDecryptingChannel (cipherTextSource, associatedData.getBytes ()); OutputStream out = novi FileOutputStream ("plainTextFile"); int cnt = 1; do {buffer.clear (); cnt = decryptingChannel.read (međuspremnik); out.write (buffer.array ()); } while (cnt> 0); decryptingChannel.close (); out.close ();

6. Hibridno šifriranje

Uz simetričnu enkripciju, Tink implementira nekoliko primitiva za hibridnu enkripciju.

Hibridnim šifriranjem možemo postići učinkovitost simetričnih tipki i praktičnost asimetričnih tipki.

Jednostavno rečeno, koristit ćemo simetrični ključ za šifriranje otvorenog teksta i javni ključ za šifriranje samo simetričnog ključa.

Primijetite da pruža samo tajnost, a ne autentičnost identiteta pošiljatelja.

Pa, da vidimo kako koristiti HybridEncrypt i HybridDecrypt:

TinkConfig.register (); KeysetHandle privateKeysetHandle = KeysetHandle.generateNew (HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256); KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle (); Niz otvoreni tekst = "baeldung"; String contextInfo = "Tink"; HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive (publicKeysetHandle); HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive (privateKeysetHandle); bajt [] ciphertext = hybridEncrypt.encrypt (plaintext.getBytes (), contextInfo.getBytes ()); bajt [] plaintextDecrypted = hybridDecrypt.decrypt (šifrirani tekst, contextInfo.getBytes ());

The contextInfo je implicitni javni podatak iz konteksta koji može biti null ili prazan ili se koristi kao ulaz "pridruženih podataka" za AEAD enkripciju ili kao ulaz "CtxInfo" za HKDF.

The šifrirani tekst omogućuje provjeru integriteta contextInfo ali ne i njegovu tajnost ili autentičnost.

7. Kôd za provjeru autentičnosti poruke

Tink također podržava kodove za provjeru autentičnosti poruka ili MAC-ove.

MAC je blok od nekoliko bajtova koji možemo koristiti za autentifikaciju poruke.

Pogledajmo kako možemo stvoriti MAC i zatim provjeriti njegovu autentičnost:

TinkConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (MacKeyTemplates.HMAC_SHA256_128BITTAG); Podaci o nizu = "baeldung"; Mac mac = MacFactory.getPrimitive (keysetHandle); bajt [] oznaka = mac.computeMac (data.getBytes ()); mac.verifyMac (oznaka, data.getBytes ());

U slučaju da podaci nisu autentični, metoda verifyMac () baca a GeneralSecurityException.

8. Digitalni potpis

Kao i API-ji za šifriranje, Tink podržava i digitalne potpise.

Za primjenu digitalnog potpisa knjižnica koristi PublicKeySign primitivno za potpisivanje podataka i PublickeyVerify za provjeru:

TinkConfig.register (); KeysetHandle privateKeysetHandle = KeysetHandle.generateNew (SignatureKeyTemplates.ECDSA_P256); KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle (); Podaci o nizu = "baeldung"; PublicKeySign potpisnik = PublicKeySignFactory.getPrimitive (privateKeysetHandle); PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive (publicKeysetHandle); bajt [] potpis = potpisnik.znak (data.getBytes ()); verifier.verify (potpis, data.getBytes ());

Slično prethodnom načinu šifriranja, kada je potpis nevaljan, dobit ćemo GeneralSecurityException.

9. Zaključak

U ovom smo članku predstavili biblioteku Google Tink koristeći njezinu implementaciju Jave.

Vidjeli smo kako se koristi za šifriranje i dešifriranje podataka i kako zaštititi njihov integritet i autentičnost. Štoviše, vidjeli smo kako se podaci potpisuju pomoću API-ja za digitalni potpis.

Kao i uvijek, uzorak koda dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found