|
1 | 1 | #!/usr/bin/env python
|
2 | 2 |
|
3 |
| -# Copyright 2016 Google Inc. All Rights Reserved. |
| 3 | +# Copyright 2016 Google LLC |
4 | 4 | #
|
5 |
| -# Licensed under the Apache License, Version 2.0 (the "License"); |
6 |
| -# you may not use this file except in compliance with the License. |
7 |
| -# You may obtain a copy of the License at |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
8 | 8 | #
|
9 |
| -# http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
10 | 10 | #
|
11 |
| -# Unless required by applicable law or agreed to in writing, software |
12 |
| -# distributed under the License is distributed on an "AS IS" BASIS, |
13 |
| -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 |
| -# See the License for the specific language governing permissions and |
15 |
| -# limitations under the License. |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
16 | 16 |
|
17 | 17 | """Example of authenticating using access tokens directly on Compute Engine.
|
18 | 18 |
|
19 | 19 | For more information, see the README.md under /compute.
|
20 | 20 | """
|
21 | 21 |
|
22 | 22 | # [START all]
|
23 |
| - |
| 23 | +# [START compute_generate_wrapped_rsa_key] |
24 | 24 | import argparse
|
25 | 25 | import base64
|
26 | 26 | import os
|
| 27 | +from typing import Optional |
27 | 28 |
|
28 | 29 | from cryptography import x509
|
29 | 30 | from cryptography.hazmat.backends import default_backend
|
30 | 31 | from cryptography.hazmat.primitives import hashes
|
31 | 32 | from cryptography.hazmat.primitives.asymmetric import padding
|
| 33 | +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey |
32 | 34 | import requests
|
33 | 35 |
|
34 | 36 |
|
35 | 37 | GOOGLE_PUBLIC_CERT_URL = (
|
36 |
| - 'https://cloud-certs.storage.googleapis.com/google-cloud-csek-ingress.pem') |
| 38 | + "https://cloud-certs.storage.googleapis.com/google-cloud-csek-ingress.pem" |
| 39 | +) |
| 40 | + |
37 | 41 |
|
| 42 | +def get_google_public_cert_key() -> RSAPublicKey: |
| 43 | + """ |
| 44 | + Downloads the Google public certificate. |
38 | 45 |
|
39 |
| -def get_google_public_cert_key(): |
| 46 | + Returns: |
| 47 | + RSAPublicKey object with the Google public certificate. |
| 48 | + """ |
40 | 49 | r = requests.get(GOOGLE_PUBLIC_CERT_URL)
|
41 | 50 | r.raise_for_status()
|
42 | 51 |
|
43 | 52 | # Load the certificate.
|
44 |
| - certificate = x509.load_pem_x509_certificate( |
45 |
| - r.content, default_backend()) |
| 53 | + certificate = x509.load_pem_x509_certificate(r.content, default_backend()) |
46 | 54 |
|
47 | 55 | # Get the certicate's public key.
|
48 | 56 | public_key = certificate.public_key()
|
49 | 57 |
|
50 | 58 | return public_key
|
51 | 59 |
|
52 | 60 |
|
53 |
| -def wrap_rsa_key(public_key, private_key_bytes): |
54 |
| - # Use the Google public key to encrypt the customer private key. |
55 |
| - # This means that only the Google private key is capable of decrypting |
56 |
| - # the customer private key. |
| 61 | +def wrap_rsa_key(public_key: RSAPublicKey, private_key_bytes: bytes) -> bytes: |
| 62 | + """ |
| 63 | + Use the Google public key to encrypt the customer private key. |
| 64 | +
|
| 65 | + This means that only the Google private key is capable of decrypting |
| 66 | + the customer private key. |
| 67 | +
|
| 68 | + Args: |
| 69 | + public_key: The public key to use for encrypting. |
| 70 | + private_key_bytes: The private key to be encrypted. |
| 71 | +
|
| 72 | + Returns: |
| 73 | + private_key_bytes encrypted using the public_key. Encoded using |
| 74 | + base64. |
| 75 | + """ |
57 | 76 | wrapped_key = public_key.encrypt(
|
58 | 77 | private_key_bytes,
|
59 | 78 | padding.OAEP(
|
60 | 79 | mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
61 | 80 | algorithm=hashes.SHA1(),
|
62 |
| - label=None)) |
| 81 | + label=None, |
| 82 | + ), |
| 83 | + ) |
63 | 84 | encoded_wrapped_key = base64.b64encode(wrapped_key)
|
64 | 85 | return encoded_wrapped_key
|
65 | 86 |
|
66 | 87 |
|
67 |
| -def main(key_file): |
| 88 | +def main(key_file: Optional[str]) -> None: |
| 89 | + """ |
| 90 | + This script will encrypt a private key with Google public key. |
| 91 | +
|
| 92 | + Args: |
| 93 | + key_file: path to a file containing your private key. If not |
| 94 | + provided, a new key will be generated (256 bit). |
| 95 | + """ |
68 | 96 | # Generate a new 256-bit private key if no key is specified.
|
69 | 97 | if not key_file:
|
70 | 98 | customer_key_bytes = os.urandom(32)
|
71 | 99 | else:
|
72 |
| - with open(key_file, 'rb') as f: |
| 100 | + with open(key_file, "rb") as f: |
73 | 101 | customer_key_bytes = f.read()
|
74 | 102 |
|
75 | 103 | google_public_key = get_google_public_cert_key()
|
76 | 104 | wrapped_rsa_key = wrap_rsa_key(google_public_key, customer_key_bytes)
|
77 | 105 |
|
78 |
| - print('Base-64 encoded private key: {}'.format( |
79 |
| - base64.b64encode(customer_key_bytes).decode('utf-8'))) |
80 |
| - print('Wrapped RSA key: {}'.format(wrapped_rsa_key.decode('utf-8'))) |
| 106 | + b64_key = base64.b64encode(customer_key_bytes).decode("utf-8") |
| 107 | + |
| 108 | + print(f"Base-64 encoded private key: {b64_key}") |
| 109 | + print(f"Wrapped RSA key: {wrapped_rsa_key.decode('utf-8')}") |
81 | 110 |
|
82 | 111 |
|
83 |
| -if __name__ == '__main__': |
| 112 | +if __name__ == "__main__": |
84 | 113 | parser = argparse.ArgumentParser(
|
85 |
| - description=__doc__, |
86 |
| - formatter_class=argparse.RawDescriptionHelpFormatter) |
87 |
| - parser.add_argument( |
88 |
| - '--key_file', help='File containing your binary private key.') |
| 114 | + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter |
| 115 | + ) |
| 116 | + parser.add_argument("--key_file", help="File containing your binary private key.") |
89 | 117 |
|
90 | 118 | args = parser.parse_args()
|
91 | 119 |
|
92 | 120 | main(args.key_file)
|
| 121 | +# [END compute_generate_wrapped_rsa_key] |
93 | 122 | # [END all]
|
0 commit comments