xref: /aosp_15_r20/external/tink/python/examples/hybrid/hybrid.py (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang# Copyright 2021 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# [START hybrid-encryption-example]
15*e7b1675dSTing-Kang Chang"""A command-line utility for encrypting a file using hybrid encryption.
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang ChangIt loads cleartext keys from disk - this is not recommended!
18*e7b1675dSTing-Kang Chang"""
19*e7b1675dSTing-Kang Chang
20*e7b1675dSTing-Kang Changfrom absl import app
21*e7b1675dSTing-Kang Changfrom absl import flags
22*e7b1675dSTing-Kang Changfrom absl import logging
23*e7b1675dSTing-Kang Changimport tink
24*e7b1675dSTing-Kang Changfrom tink import cleartext_keyset_handle
25*e7b1675dSTing-Kang Changfrom tink import hybrid
26*e7b1675dSTing-Kang Chang
27*e7b1675dSTing-Kang Chang
28*e7b1675dSTing-Kang ChangFLAGS = flags.FLAGS
29*e7b1675dSTing-Kang Chang
30*e7b1675dSTing-Kang Changflags.DEFINE_enum('mode', None, ['encrypt', 'decrypt'],
31*e7b1675dSTing-Kang Chang                  'The operation to perform.')
32*e7b1675dSTing-Kang Changflags.DEFINE_string('keyset_path', None,
33*e7b1675dSTing-Kang Chang                    'Path to the keyset used for encryption.')
34*e7b1675dSTing-Kang Changflags.DEFINE_string('input_path', None, 'Path to the input file.')
35*e7b1675dSTing-Kang Changflags.DEFINE_string('output_path', None, 'Path to the output file.')
36*e7b1675dSTing-Kang Changflags.DEFINE_string('context_info', None,
37*e7b1675dSTing-Kang Chang                    'Context info used for encryption.')
38*e7b1675dSTing-Kang Chang
39*e7b1675dSTing-Kang Chang
40*e7b1675dSTing-Kang Changdef main(argv):
41*e7b1675dSTing-Kang Chang  del argv  # Unused
42*e7b1675dSTing-Kang Chang
43*e7b1675dSTing-Kang Chang  context_info = b'' if not FLAGS.context_info else bytes(
44*e7b1675dSTing-Kang Chang      FLAGS.context_info, 'utf-8')
45*e7b1675dSTing-Kang Chang
46*e7b1675dSTing-Kang Chang  # Initialise Tink
47*e7b1675dSTing-Kang Chang  hybrid.register()
48*e7b1675dSTing-Kang Chang
49*e7b1675dSTing-Kang Chang  # Read the keyset into a keyset_handle
50*e7b1675dSTing-Kang Chang  with open(FLAGS.keyset_path, 'rt') as keyset_file:
51*e7b1675dSTing-Kang Chang    try:
52*e7b1675dSTing-Kang Chang      text = keyset_file.read()
53*e7b1675dSTing-Kang Chang      keyset_handle = cleartext_keyset_handle.read(tink.JsonKeysetReader(text))
54*e7b1675dSTing-Kang Chang    except tink.TinkError as e:
55*e7b1675dSTing-Kang Chang      logging.exception('Error reading key: %s', e)
56*e7b1675dSTing-Kang Chang      return 1
57*e7b1675dSTing-Kang Chang
58*e7b1675dSTing-Kang Chang  with open(FLAGS.input_path, 'rb') as input_file:
59*e7b1675dSTing-Kang Chang    data = input_file.read()
60*e7b1675dSTing-Kang Chang
61*e7b1675dSTing-Kang Chang  if FLAGS.mode == 'encrypt':
62*e7b1675dSTing-Kang Chang    # Get the primitive
63*e7b1675dSTing-Kang Chang    try:
64*e7b1675dSTing-Kang Chang      primitive = keyset_handle.primitive(hybrid.HybridEncrypt)
65*e7b1675dSTing-Kang Chang    except tink.TinkError as e:
66*e7b1675dSTing-Kang Chang      logging.exception(
67*e7b1675dSTing-Kang Chang          'Error creating hybrid encrypt primitive from keyset: %s', e)
68*e7b1675dSTing-Kang Chang      return 1
69*e7b1675dSTing-Kang Chang    # Encrypt data
70*e7b1675dSTing-Kang Chang    with open(FLAGS.output_path, 'wb') as output_file:
71*e7b1675dSTing-Kang Chang      ciphertext = primitive.encrypt(data, context_info)
72*e7b1675dSTing-Kang Chang      output_file.write(ciphertext)
73*e7b1675dSTing-Kang Chang
74*e7b1675dSTing-Kang Chang  if FLAGS.mode == 'decrypt':
75*e7b1675dSTing-Kang Chang    # Get the primitive
76*e7b1675dSTing-Kang Chang    try:
77*e7b1675dSTing-Kang Chang      primitive = keyset_handle.primitive(hybrid.HybridDecrypt)
78*e7b1675dSTing-Kang Chang    except tink.TinkError as e:
79*e7b1675dSTing-Kang Chang      logging.exception(
80*e7b1675dSTing-Kang Chang          'Error creating hybrid encrypt primitive from keyset: %s', e)
81*e7b1675dSTing-Kang Chang      return 1
82*e7b1675dSTing-Kang Chang    # Decrypt data
83*e7b1675dSTing-Kang Chang    with open(FLAGS.output_path, 'wb') as output_file:
84*e7b1675dSTing-Kang Chang      plaintext = primitive.decrypt(data, context_info)
85*e7b1675dSTing-Kang Chang      output_file.write(plaintext)
86*e7b1675dSTing-Kang Chang
87*e7b1675dSTing-Kang Chang
88*e7b1675dSTing-Kang Changif __name__ == '__main__':
89*e7b1675dSTing-Kang Chang  flags.mark_flags_as_required(
90*e7b1675dSTing-Kang Chang      ['mode', 'keyset_path', 'input_path', 'output_path'])
91*e7b1675dSTing-Kang Chang  app.run(main)
92*e7b1675dSTing-Kang Chang# [END hybrid-encryption-example]
93