Veiledning til Google Tink

1. Introduksjon

I dag bruker mange utviklere kryptografiske teknikker for å beskytte brukerdata.

I kryptografi kan små implementeringsfeil få alvorlige konsekvenser, og å forstå hvordan man implementerer kryptografi riktig er en kompleks og tidkrevende oppgave.

I denne opplæringen skal vi beskrive Tink - et flerspråklig kryptografisk bibliotek på tvers av plattformer som kan hjelpe oss med å implementere sikker kryptografisk kode.

2. Avhengigheter

Vi kan bruke Maven eller Gradle til å importere Tink.

For vår opplæring legger vi bare til Tinks Maven-avhengighet:

 com.google.crypto.tink tink 1.2.2 

Selv om vi kunne ha brukt Gradle i stedet:

avhengigheter {kompiler 'com.google.crypto.tink: tink: siste'}

3. Initialisering

Før vi bruker noen av Tink APIer, må vi initialisere dem.

Hvis vi trenger å bruke alle implementeringer av alle primitiver i Tink, kan vi bruke TinkConfig.register () metode:

TinkConfig.register ();

Mens vi for eksempel bare trenger AEAD-primitive, kan vi bruke det AeadConfig.register () metode:

AeadConfig.register ();

En tilpassbar initialisering tilbys også for hver implementering.

4. Tink Primitives

Hovedobjektene biblioteket bruker kalles primitiver som avhengig av type inneholder forskjellig kryptografisk funksjonalitet.

En primitiv kan ha flere implementeringer:

PrimitivImplementeringer
FREMAES-EAX, AES-GCM, AES-CTR-HMAC, KMS-konvolutt, 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 oppnå en primitiv ved å kalle metoden getPrimitive () av tilsvarende fabrikklasse som passerer den a KeysetHandle:

Aead aead = AeadFactory.getPrimitive (keysetHandle); 

4.1. KeysetHandle

I rekkefølge For å gi kryptografisk funksjonalitet, trenger hver primitive en nøkkelstruktur som inneholder alt nøkkelmaterialet og parametrene.

Tink gir et objekt - KeysetHandle - som pakker et nøkkelsett med noen tilleggsparametere og metadata.

Så før vi starter en primitiv, må vi lage en KeysetHandle gjenstand:

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

Og etter å ha generert en nøkkel, vil vi kanskje fortsette den:

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

Deretter kan vi deretter laste den inn:

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

5. Kryptering

Tink gir flere måter å bruke AEAD-algoritmen på. La oss ta en titt.

5.1. FREM

AEAD tilbyr autentisert kryptering med tilknyttede data, noe som betyr at vi kan kryptere klartekst og eventuelt gi tilknyttede data som skal autentiseres, men ikke krypteres.

Merk at denne algoritmen sikrer ektheten og integriteten til de tilknyttede dataene, men ikke hemmeligholdet.

For å kryptere data med en av AEAD-implementeringene, som vi tidligere så, må vi initialisere biblioteket og opprette en tastesettHåndtak:

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

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

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

Deretter kan vi dekryptere krypteringstekst bruker dekryptere () metode:

String dekryptert = ny streng (aead.decrypt (ciphertext, assosiertData.getBytes ()));

5.2. Streaming AEAD

På samme måte, når dataene som skal krypteres er for store til å bli behandlet i ett enkelt trinn, kan vi bruke 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. lukk ();

I utgangspunktet trengte vi WriteableByteChannel for å oppnå dette.

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

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

6. Hybrid kryptering

I tillegg til symmetrisk kryptering implementerer Tink et par primitiver for hybrid kryptering.

Med hybrid kryptering kan vi få effektiviteten til symmetriske nøkler og bekvemmeligheten til asymmetriske nøkler.

Enkelt sagt, vi bruker en symmetrisk nøkkel til å kryptere ren tekst og en offentlig nøkkel for kun å kryptere den symmetriske nøkkelen.

Legg merke til at det bare gir hemmelighold, ikke identitetens autentisitet.

Så, la oss se hvordan du bruker 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 ());

De contextInfo er implisitte offentlige data fra konteksten som kan være null eller tom eller brukes som "tilknyttet data" -inngang for AEAD-kryptering eller som "CtxInfo" -inngang for HKDF.

De krypteringstekst muliggjør kontroll av integriteten til contextInfo men ikke dens hemmelighold eller ekthet.

7. Melding godkjenningskode

Tink støtter også meldingsautentiseringskoder eller MAC-er.

En MAC er en blokk med noen få byte som vi kan bruke til å autentisere en melding.

La oss se hvordan vi kan lage en MAC og deretter bekrefte dens ekthet:

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

I tilfelle dataene ikke er autentiske, er metoden verifisereMac () kaster en GeneralSecurityException.

8. Digital signatur

I tillegg til krypterings-API-er, støtter Tink digitale signaturer.

For å implementere digital signatur bruker biblioteket PublicKeySign primitiv for signering av data, og PublickeyVerify for bekreftelse:

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

I likhet med den forrige krypteringsmetoden, når signaturen er ugyldig, får vi en GeneralSecurityException.

9. Konklusjon

I denne artikkelen introduserte vi Google Tink-biblioteket ved hjelp av Java-implementeringen.

Vi har sett hvordan vi kan bruke til å kryptere og dekryptere data og hvordan vi kan beskytte dets integritet og ekthet. Videre har vi sett hvordan du signerer data ved hjelp av APIer for digital signatur.

Som alltid er eksempelkoden tilgjengelig på GitHub.


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