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