Public key encryption involves protecting data with two keys, one public and one private. This allows you to share encrypted data with anyone who has the public key, but any data they send back can only be decrypted with the private key. If you need to encrypt data with a public key because the sender cannot store any secrets, use the Hybrid Encryption primitive.
We recommend the DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM key type for most hybrid encryption use cases. For all supported key types, see Supported Key Types.
The following examples get you started using the Hybrid Encryption primitive.
Python
Java
package hybrid; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.crypto.tink.CleartextKeysetHandle; import com.google.crypto.tink.HybridDecrypt; import com.google.crypto.tink.HybridEncrypt; import com.google.crypto.tink.JsonKeysetReader; import com.google.crypto.tink.KeysetHandle; import com.google.crypto.tink.hybrid.HybridConfig; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.security.GeneralSecurityException; /** * A command-line utility for hybrid encryption. * * <p>It loads cleartext keys from disk - this is not recommended! * * <p>It requires the following arguments: * * <ul> * <li>mode: either 'encrypt' or 'decrypt'. * <li>key-file: Read the key material from this file. * <li>input-file: Read the input from this file. * <li>output-file: Write the result to this file. * <li>[optional] contex-info: Bind the encryption to this context info. */ public final class HybridExample { public static void main(String[] args) throws Exception { if (args.length != 4 && args.length != 5) { System.err.printf("Expected 4 or 5 parameters, got %d\n", args.length); System.err.println( "Usage: java HybridExample encrypt/decrypt key-file input-file output-file context-info"); System.exit(1); } String mode = args[0]; if (!mode.equals("encrypt") && !mode.equals("decrypt")) { System.err.println("Incorrect mode. Please select encrypt or decrypt."); System.exit(1); } File keyFile = new File(args[1]); File inputFile = new File(args[2]); byte[] input = Files.readAllBytes(inputFile.toPath()); File outputFile = new File(args[3]); byte[] contextInfo = new byte[0]; if (args.length == 5) { contextInfo = args[4].getBytes(UTF_8); } // Register all hybrid encryption key types with the Tink runtime. HybridConfig.register(); // Read the keyset into a KeysetHandle. KeysetHandle handle = null; try (FileInputStream inputStream = new FileInputStream(keyFile)) { handle = CleartextKeysetHandle.read(JsonKeysetReader.withInputStream(inputStream)); } catch (GeneralSecurityException | IOException ex) { System.err.println("Cannot read keyset, got error: " + ex); System.exit(1); } if (mode.equals("encrypt")) { // Get the primitive. HybridEncrypt encryptor = null; try { encryptor = handle.getPrimitive(HybridEncrypt.class); } catch (GeneralSecurityException ex) { System.err.println("Cannot create primitive, got error: " + ex); System.exit(1); } // Use the primitive to encrypt data. byte[] ciphertext = encryptor.encrypt(input, contextInfo); try (FileOutputStream stream = new FileOutputStream(outputFile)) { stream.write(ciphertext); } System.exit(0); } // Get the primitive. HybridDecrypt decryptor = null; try { decryptor = handle.getPrimitive(HybridDecrypt.class); } catch (GeneralSecurityException ex) { System.err.println("Cannot create primitive, got error: " + ex); System.exit(1); } // Use the primitive to decrypt data. byte[] plaintext = decryptor.decrypt(input, contextInfo); try (FileOutputStream stream = new FileOutputStream(outputFile)) { stream.write(plaintext); } System.exit(0); } private HybridExample() {} }
C++
Go