Guide til Google Tink

1. Introduktion

I dag bruger mange udviklere kryptografiske teknikker til at beskytte brugerdata.

I kryptografi kan små implementeringsfejl have alvorlige konsekvenser, og det er en kompleks og tidskrævende opgave at forstå, hvordan man implementerer kryptografi korrekt.

I denne vejledning beskriver vi Tink - et kryptografisk bibliotek på tværs af platforme, der kan hjælpe os med at implementere sikker, kryptografisk kode.

2. Afhængigheder

Vi kan bruge Maven eller Gradle til at importere Tink.

Til vores vejledning tilføjer vi bare Tinks Maven-afhængighed:

 com.google.crypto.tink tink 1.2.2 

Selvom vi kunne have brugt Gradle i stedet:

afhængigheder {kompilér 'com.google.crypto.tink: tink: seneste'}

3. Initialisering

Før vi bruger nogen af ​​Tink API'er, skal vi initialisere dem.

Hvis vi har brug for alle implementeringer af alle primitiver i Tink, kan vi bruge TinkConfig.register () metode:

TinkConfig.register ();

Mens vi f.eks. Kun har brug for AEAD-primitiv, kan vi bruge det AeadConfig.register () metode:

AeadConfig.register ();

En tilpasset initialisering leveres også til hver implementering.

4. Tink-primitiver

De vigtigste objekter, som biblioteket bruger, kaldes primitiver, der afhængigt af typen indeholder forskellige kryptografiske funktioner.

En primitiv kan have flere implementeringer:

PrimitivImplementeringer
FREMAES-EAX, AES-GCM, AES-CTR-HMAC, KMS-konvolut, CHACHA20-POLY1305
Streaming AEADAES-GCM-HKDF-STREAMING, AES-CTR-HMAC-STREAMING
Deterministisk AEADFREM: AES-SIV
MACHMAC-SHA2
Digital signaturECDSA over NIST-kurver, ED25519
Hybrid krypteringECIES med AEAD og HKDF, (NaCl CryptoBox)

Vi kan opnå en primitiv ved at kalde metoden getPrimitive () af den tilsvarende fabriksklasse, der passerer den a KeysetHandle:

Aead aead = AeadFactory.getPrimitive (keysetHandle); 

4.1. KeysetHandle

I orden for at give kryptografisk funktionalitet har hver primitiv brug for en nøglestruktur der indeholder alt nøglemateriale og parametre.

Tink giver et objekt - KeysetHandle - som ombryder et nøglesæt med nogle yderligere parametre og metadata.

Så inden vi opretter en primitiv, er vi nødt til at oprette en KeysetHandle objekt:

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

Og efter at have genereret en nøgle, vil vi måske fortsætte den:

String keysetFilename = "keyset.json"; CleartextKeysetHandle.write (keysetHandle, JsonKeysetWriter.withFile (ny fil (keysetFilename)));

Derefter kan vi efterfølgende indlæse det:

String keysetFilename = "keyset.json"; KeysetHandle keysetHandle = CleartextKeysetHandle.read (JsonKeysetReader.withFile (ny fil (keysetFilename)));

5. Kryptering

Tink giver flere måder at anvende AEAD-algoritmen på. Lad os se.

5.1. FREM

AEAD leverer godkendt kryptering med tilknyttede data, hvilket betyder det vi kan kryptere almindelig tekst og eventuelt levere tilknyttede data, der skal godkendes, men ikke krypteres.

Bemærk, at denne algoritme sikrer ægtheden og integriteten af ​​de tilknyttede data, men ikke dens hemmeligholdelse.

For at kryptere data med en af ​​AEAD-implementeringerne, som vi tidligere har set, er vi nødt til at initialisere biblioteket og oprette en nøglesætHåndtag:

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

Når vi har gjort det, kan vi hente det primitive og kryptere de ønskede data:

String plaintext = "baeldung"; String associatedData = "Tink"; Aead aead = AeadFactory.getPrimitive (keysetHandle); byte [] ciphertext = aead.encrypt (plaintext.getBytes (), associeretData.getBytes ());

Dernæst kan vi dekryptere ciphertext bruger dekryptere () metode:

Streng dekrypteret = ny streng (aead.decrypt (ciphertext, associatedData.getBytes ()));

5.2. Streaming AEAD

Tilsvarende når dataene, der skal krypteres, er for store til at blive behandlet i et enkelt trin, kan vi bruge streaming AEAD primitive:

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

Dybest set havde vi brug for WriteableByteChannel for at opnå dette.

Så for at dekryptere cipherTextFile, vi ønsker at bruge en ReadableByteChannel:

FileChannel cipherTextSource = ny FileInputStream ("cipherTextFile"). GetChannel (); ReadableByteChannel decryptingChannel = streamingAead.newDecryptingChannel (cipherTextSource, associatedData.getBytes ()); OutputStream out = ny FileOutputStream ("plainTextFile"); int cnt = 1; gør {buffer.clear (); cnt = dekrypteringChannel.read (buffer); out.write (buffer.array ()); } mens (cnt> 0); dekrypteringChannel.close (); out.close ();

6. Hybrid kryptering

Ud over symmetrisk kryptering implementerer Tink et par primitiver til hybrid kryptering.

Med hybrid kryptering kan vi få effektiviteten af ​​symmetriske nøgler og bekvemmeligheden ved asymmetriske nøgler.

Kort sagt, vi bruger en symmetrisk nøgle til at kryptere almindelig tekst og en offentlig nøgle til kun at kryptere den symmetriske nøgle.

Bemærk, at det kun giver hemmeligholdelse, ikke afsenderens identitetsægthed.

Så lad os se, hvordan du bruger HybridEncrypt og HybridDecrypt:

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

Det contextInfo er implicitte offentlige data fra den sammenhæng, der kan være nul eller tom eller bruges som "tilknyttet data" -indgang til AEAD-kryptering eller som "CtxInfo" -indgang til HKDF.

Det ciphertext muliggør kontrol af integriteten af contextInfo men ikke dens hemmeligholdelse eller ægthed.

7. Meddelelsesgodkendelseskode

Tink understøtter også meddelelsesgodkendelseskoder eller MAC'er.

En MAC er en blok på et par byte, som vi kan bruge til at godkende en besked.

Lad os se, hvordan vi kan oprette en MAC og derefter kontrollere dens ægthed:

TinkConfig.register (); KeysetHandle keysetHandle = KeysetHandle.generateNew (MacKeyTemplates.HMAC_SHA256_128BITTAG); Strengdata = "baeldung"; Mac mac = MacFactory.getPrimitive (keysetHandle); byte [] tag = mac.computeMac (data.getBytes ()); mac.verifyMac (tag, data.getBytes ());

I tilfælde af at dataene ikke er autentiske, er metoden verificereMac () kaster en GeneralSecurityException.

8. Digital signatur

Ud over krypterings-API'er understøtter Tink digitale signaturer.

For at implementere digital signatur bruger biblioteket PublicKeySign primitiv til signering af data, og PublickeyVerify til verifikation:

TinkConfig.register (); KeysetHandle privateKeysetHandle = KeysetHandle.generateNew (SignatureKeyTemplates.ECDSA_P256); KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle (); Strengdata = "baeldung"; PublicKeySign signer = PublicKeySignFactory.getPrimitive (privateKeysetHandle); PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive (publicKeysetHandle); byte [] signatur = signer.sign (data.getBytes ()); verifier.verify (signatur, data.getBytes ());

Svarende til den tidligere krypteringsmetode, når signaturen er ugyldig, får vi en GeneralSecurityException.

9. Konklusion

I denne artikel introducerede vi Google Tink-biblioteket ved hjælp af dets Java-implementering.

Vi har set, hvordan man bruger til at kryptere og dekryptere data, og hvordan man beskytter dets integritet og ægthed. Desuden har vi set, hvordan man underskriver data ved hjælp af digitale signatur-API'er.

Som altid er prøvekoden tilgængelig på GitHub.


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