1# Copyright 2022 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS-IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""A basic example for using the hybrid encryption API.""" 15# [START hybrid-basic-example] 16import tink 17from tink import cleartext_keyset_handle 18from tink import hybrid 19 20 21def example(): 22 """Encrypt and decrypt using hybrid encryption.""" 23 # Register the hybrid encryption key managers. This is needed to create 24 # HybridEncrypt and HybridDecrypt primitives later. 25 hybrid.register() 26 27 # A private keyset created with 28 # tinkey create-keyset \ 29 # --key-template=DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM \ 30 # --out private_keyset.cfg 31 # Note that this keyset has the secret key information in cleartext. 32 private_keyset = r"""{ 33 "key": [{ 34 "keyData": { 35 "keyMaterialType": 36 "ASYMMETRIC_PRIVATE", 37 "typeUrl": 38 "type.googleapis.com/google.crypto.tink.HpkePrivateKey", 39 "value": 40 "EioSBggBEAEYAhogVWQpmQoz74jcAp5WOD36KiBQ71MVCpn2iWfOzWLtKV4aINfn8qlMbyijNJcCzrafjsgJ493ZZGN256KTfKw0WN+p" 41 }, 42 "keyId": 958452012, 43 "outputPrefixType": "TINK", 44 "status": "ENABLED" 45 }], 46 "primaryKeyId": 958452012 47 }""" 48 49 # The corresponding public keyset created with 50 # "tinkey create-public-keyset --in private_keyset.cfg" 51 public_keyset = r"""{ 52 "key": [{ 53 "keyData": { 54 "keyMaterialType": 55 "ASYMMETRIC_PUBLIC", 56 "typeUrl": 57 "type.googleapis.com/google.crypto.tink.HpkePublicKey", 58 "value": 59 "EgYIARABGAIaIFVkKZkKM++I3AKeVjg9+iogUO9TFQqZ9olnzs1i7Sle" }, 60 "keyId": 958452012, 61 "outputPrefixType": "TINK", 62 "status": "ENABLED" 63 }], 64 "primaryKeyId": 958452012 65 }""" 66 67 # Create a keyset handle from the keyset containing the public key. Because 68 # this keyset does not contain any secrets, we can use 69 # `tink.read_no_secret_keyset_handle`. 70 public_keyset_handle = tink.read_no_secret_keyset_handle( 71 tink.JsonKeysetReader(public_keyset)) 72 73 # Retrieve the HybridEncrypt primitive from the keyset handle. 74 enc_primitive = public_keyset_handle.primitive(hybrid.HybridEncrypt) 75 76 # Use enc_primitive to encrypt a message. In this case the primary key of the 77 # keyset will be used (which is also the only key in this example). 78 ciphertext = enc_primitive.encrypt(b'message', b'context_info') 79 80 # Create a keyset handle from the private keyset. The keyset handle provides 81 # abstract access to the underlying keyset to limit the exposure of accessing 82 # the raw key material. WARNING: In practice, it is unlikely you will want to 83 # use a cleartext_keyset_handle, as it implies that your key material is 84 # passed in cleartext which is a security risk. 85 private_keyset_handle = cleartext_keyset_handle.read( 86 tink.JsonKeysetReader(private_keyset) 87 ) 88 89 # Retrieve the HybridDecrypt primitive from the private keyset handle. 90 dec_primitive = private_keyset_handle.primitive(hybrid.HybridDecrypt) 91 92 # Use dec_primitive to decrypt the message. Decrypt finds the correct key in 93 # the keyset and decrypts the ciphertext. If no key is found or decryption 94 # fails, it raises an error. 95 decrypted = dec_primitive.decrypt(ciphertext, b'context_info') 96 # [END hybrid-basic-example] 97 assert decrypted == b'message' 98