Panduan untuk Google Tink

1. Pengenalan

Pada masa kini, banyak pembangun menggunakan teknik kriptografi untuk melindungi data pengguna.

Dalam kriptografi, kesalahan pelaksanaan kecil boleh membawa akibat yang serius, dan memahami bagaimana melaksanakan kriptografi dengan betul adalah tugas yang kompleks dan memakan masa.

Dalam tutorial ini, kita akan menerangkan Tink - pustaka kriptografi pelbagai platform dan pelbagai platform yang dapat membantu kita melaksanakan kod kriptografi yang selamat.

2. Kebergantungan

Kita boleh menggunakan Maven atau Gradle untuk mengimport Tink.

Untuk tutorial kami, kami hanya akan menambahkan ketergantungan Tink's Maven:

 com.google.crypto.tink tink 1.2.2 

Walaupun kita boleh menggunakan Gradle sebagai gantinya:

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

3. Permulaan

Sebelum menggunakan Tink API mana pun, kita perlu menginisialisasi mereka.

Sekiranya kita perlu menggunakan semua implementasi dari semua primitif di Tink, kita dapat menggunakan kaedah TinkConfig.register () :

TinkConfig.register();

Sebagai contoh, jika kita hanya memerlukan AEAD primitif, kita dapat menggunakan kaedah AeadConfig.register () :

AeadConfig.register();

Inisialisasi disesuaikan juga disediakan untuk setiap pelaksanaan.

4. Tink Primitives

Objek utama yang digunakan perpustakaan disebut primitif yang, bergantung pada jenisnya, mengandungi fungsi kriptografi yang berbeza.

Primitif boleh mempunyai pelbagai pelaksanaan:

Primitif Pelaksanaan
AEAD AES-EAX, AES-GCM, AES-CTR-HMAC, Sampul surat KMS, CHACHA20-POLY1305
Menstrim AEAD STREAMING AES-GCM-HKDF, STREAMING AES-CTR-HMAC
AEAD Deterministik AEAD: AES-SIV
MAC HMAC-SHA2
Tandatangan digital ECDSA melengkung NIST, ED25519
Penyulitan Hibrid ECIES dengan AEAD dan HKDF, (NaCl CryptoBox)

Kita boleh memperoleh primitif dengan memanggil kaedah getPrimitive () dari kelas kilang yang sesuai yang menjadikannya KeysetHandle :

Aead aead = AeadFactory.getPrimitive(keysetHandle); 

4.1. Kekunci Kekunci

Untuk menyediakan fungsi kriptografi, setiap primitif memerlukan struktur kunci yang mengandungi semua bahan dan parameter utama.

Tink menyediakan objek - KeysetHandle - yang membungkus set kunci dengan beberapa parameter dan metadata tambahan.

Oleh itu, sebelum mewujudkan primitif, kita perlu membuat objek KeysetHandle :

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

Dan setelah menghasilkan kunci, kami mungkin ingin mengekalkannya:

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

Kemudian, kita boleh memuatkannya:

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

5. Penyulitan

Tink menyediakan pelbagai cara untuk menerapkan algoritma AEAD. Mari kita lihat.

5.1. AEAD

AEAD menyediakan Penyulitan yang Disahkan dengan Data Bersekutu yang bermaksud bahawa kami dapat mengenkripsi teks biasa dan, secara pilihan, menyediakan data yang berkaitan yang harus disahkan tetapi tidak dienkripsi .

Perhatikan bahawa algoritma ini memastikan keaslian dan integriti data yang berkaitan tetapi bukan kerahsiaannya.

Untuk menyulitkan data dengan salah satu pelaksanaan AEAD, seperti yang kita lihat sebelumnya, kita perlu menginisialisasi perpustakaan dan membuat keyetHandle:

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

Setelah berjaya melakukannya, kita dapat memperoleh primitif dan menyulitkan data yang diinginkan:

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

Seterusnya, kita dapat menyahsulit ciphertext menggunakan kaedah dekripsi () :

String decrypted = new String(aead.decrypt(ciphertext, associatedData.getBytes()));

5.2. Menstrim AEAD

Similarly, when the data to be encrypted is too large to be processed in a single step, we can use the streaming AEAD primitive:

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

Basically, we needed WriteableByteChannel to achieve this.

So, to decrypt the cipherTextFile, we'd want to use a ReadableByteChannel:

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

6. Hybrid Encryption

In addition to symmetric encryption, Tink implements a couple of primitives for hybrid encryption.

With Hybrid Encryption we can get the efficiency of symmetric keys and the convenience of asymmetric keys.

Simply put, we'll use a symmetric key to encrypt the plaintext and a public key to encrypt the symmetric key only.

Notice that it provides secrecy only, not identity authenticity of the sender.

So, let's see how to use HybridEncrypt and 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());

The contextInfo is implicit public data from the context that can be null or empty or used as “associated data” input for the AEAD encryption or as “CtxInfo” input for HKDF.

The ciphertext allows for checking the integrity of contextInfo but not its secrecy or authenticity.

7. Message Authentication Code

Tink also supports Message Authentication Codes or MACs.

A MAC is a block of a few bytes that we can use to authenticate a message.

Let's see how we can create a MAC and then verify its authenticity:

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());

In the event that the data isn't authentic, the method verifyMac() throws a GeneralSecurityException.

8. Digital Signature

As well as encryption APIs, Tink supports digital signatures.

To implement digital signature, the library uses the PublicKeySign primitive for the signing of data, and PublickeyVerify for verification:

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[] signature = signer.sign(data.getBytes()); verifier.verify(signature, data.getBytes());

Similar to the previous encryption method, when the signature is invalid, we'll get a GeneralSecurityException.

9. Conclusion

In this article, we introduced the Google Tink library using its Java implementation.

We've seen how to use to encrypt and decrypt data and how to protect its integrity and authenticity. Moreover, we've seen how to sign data using digital signature APIs.

Seperti biasa, contoh kod boleh didapati di GitHub.