xref: /aosp_15_r20/external/tink/python/examples/signature/signature_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 signature API."""
15# [START signature-basic-example]
16import tink
17from tink import cleartext_keyset_handle
18from tink import signature
19
20
21def example():
22  """Sign and verify using digital signatures."""
23  # Register the signature key managers. This is needed to create
24  # PublicKeySign and PublicKeyVerify primitives later.
25  signature.register()
26
27  # A private keyset created with
28  # "tinkey create-keyset --key-template=ECDSA_P256 --out private_keyset.cfg".
29  # Note that this keyset has the secret key information in cleartext.
30  private_keyset = r"""{
31      "key": [{
32          "keyData": {
33              "keyMaterialType":
34                  "ASYMMETRIC_PRIVATE",
35              "typeUrl":
36                  "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
37              "value":
38                  "EkwSBggDEAIYAhogEiSZ9u2nDtvZuDgWgGsVTIZ5/V08N4ycUspTX0RYRrkiIHpEwHxQd1bImkyMvV2bqtUbgMh5uPSTdnUEGrPXdt56GiEA3iUi+CRN71qy0fOCK66xAW/IvFyjOGtxjppRhSFUneo="
39          },
40          "keyId": 611814836,
41          "outputPrefixType": "TINK",
42          "status": "ENABLED"
43      }],
44      "primaryKeyId": 611814836
45  }"""
46
47  # The corresponding public keyset created with
48  # "tinkey create-public-keyset --in private_keyset.cfg"
49  public_keyset = r"""{
50      "key": [{
51          "keyData": {
52              "keyMaterialType":
53                  "ASYMMETRIC_PUBLIC",
54              "typeUrl":
55                  "type.googleapis.com/google.crypto.tink.EcdsaPublicKey",
56              "value":
57                  "EgYIAxACGAIaIBIkmfbtpw7b2bg4FoBrFUyGef1dPDeMnFLKU19EWEa5IiB6RMB8UHdWyJpMjL1dm6rVG4DIebj0k3Z1BBqz13beeg=="
58          },
59          "keyId": 611814836,
60          "outputPrefixType": "TINK",
61          "status": "ENABLED"
62      }],
63      "primaryKeyId": 611814836
64  }"""
65
66  # Create a keyset handle from the cleartext keyset in the previous
67  # step. The keyset handle provides abstract access to the underlying keyset to
68  # limit the exposure of accessing the raw key material. WARNING: In practice,
69  # it is unlikely you will want to use a cleartext_keyset_handle, as it implies
70  # that your key material is passed in cleartext which is a security risk.
71  private_keyset_handle = cleartext_keyset_handle.read(
72      tink.JsonKeysetReader(private_keyset))
73
74  # Retrieve the PublicKeySign primitive we want to use from the keyset
75  # handle.
76  sign_primitive = private_keyset_handle.primitive(signature.PublicKeySign)
77
78  # Use the primitive to sign a message. In this case the primary key of the
79  # keyset will be used (which is also the only key in this example).
80  sig = sign_primitive.sign(b'msg')
81
82  # Create a keyset handle from the keyset containing the public key. Because
83  # this keyset does not contain any secrets, we can use
84  # `tink.read_no_secret_keyset_handle`.
85  public_keyset_handle = tink.read_no_secret_keyset_handle(
86      tink.JsonKeysetReader(public_keyset))
87
88  # Retrieve the PublicKeyVerify primitive we want to use from the keyset
89  # handle.
90  verify_primitive = public_keyset_handle.primitive(signature.PublicKeyVerify)
91
92  # Use the primitive to verify that `sig` is valid signature for the message.
93  # Verify finds the correct key in the keyset. If no key is found or
94  # verification fails, it raises an error.
95  verify_primitive.verify(sig, b'msg')
96
97  # Note that we can also get the public keyset handle from the private keyset
98  # handle. The verification works the same as above.
99  public_keyset_handle2 = private_keyset_handle.public_keyset_handle()
100  verify_primitive2 = public_keyset_handle2.primitive(signature.PublicKeyVerify)
101  verify_primitive2.verify(sig, b'msg')
102  # [END signature-basic-example]
103