xref: /aosp_15_r20/external/tink/python/examples/hybrid/hybrid_basic.py (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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