Skip to content

Commit 1e8220d

Browse files
daniel-sanchedandhlee
authored andcommitted
KMS: Updated for new client library [(#1903)](#1903)
* updated kms samples to use new gapic client library
1 parent a78302e commit 1e8220d

File tree

8 files changed

+573
-612
lines changed

8 files changed

+573
-612
lines changed

kms/snippets/README.rst

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,5 @@ To run this sample:
9292
9393
$ python snippets.py
9494
95-
usage: snippets.py [-h]
96-
{create_key_ring,create_crypto_key,encrypt,decrypt,disable_crypto_key_version,enable_crypto_key_version,destroy_crypto_key_version,restore_crypto_key_version,add_member_to_crypto_key_policy,get_key_ring_policy}
97-
...
9895
99-
positional arguments:
100-
{create_key_ring,create_crypto_key,encrypt,decrypt,disable_crypto_key_version,enable_crypto_key_version,destroy_crypto_key_version,restore_crypto_key_version,add_member_to_crypto_key_policy,get_key_ring_policy}
101-
102-
optional arguments:
103-
-h, --help show this help message and exit
104-
105-
106-
107-
108-
109-
.. _Google Cloud SDK: https://cloud.google.com/sdk/
96+
.. _Google Cloud SDK: https://cloud.google.com/sdk/

kms/snippets/README.rst.in

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ samples:
1818
- name: Snippets
1919
file: snippets.py
2020
show_help: True
21+
- name: Asymmetric
22+
file: asymmetric.py
2123

22-
folder: kms/api-client
24+
folder: kms/api-client

kms/snippets/asymmetric.py

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,71 +13,103 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.rom googleapiclient import discovery
1515

16-
import base64
1716
import hashlib
1817

1918
from cryptography.exceptions import InvalidSignature
2019
from cryptography.hazmat.backends import default_backend
2120
from cryptography.hazmat.primitives import hashes, serialization
2221
from cryptography.hazmat.primitives.asymmetric import ec, padding, utils
2322

23+
from google.cloud import kms_v1
24+
from google.cloud.kms_v1 import enums
25+
26+
27+
# [START kms_create_asymmetric_key]
28+
def create_asymmetric_key(project_id, location_id, key_ring_id, crypto_key_id):
29+
"""Creates an RSA encrypt/decrypt key pair within a specified KeyRing."""
30+
31+
# Creates an API client for the KMS API.
32+
client = kms_v1.KeyManagementServiceClient()
33+
34+
# The resource name of the KeyRing associated with the CryptoKey.
35+
parent = client.key_ring_path(project_id, location_id, key_ring_id)
36+
37+
# Create the CryptoKey object template
38+
purpose = enums.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_DECRYPT
39+
algorithm = enums.CryptoKeyVersion.CryptoKeyVersionAlgorithm.\
40+
RSA_DECRYPT_OAEP_2048_SHA256
41+
crypto_key = {'purpose': purpose,
42+
'version_template': {'algorithm': algorithm}}
43+
44+
# Create a CryptoKey for the given KeyRing.
45+
response = client.create_crypto_key(parent, crypto_key_id, crypto_key)
46+
47+
print('Created CryptoKey {}.'.format(response.name))
48+
return response
49+
# [END kms_create_asymmetric_key]
50+
2451

2552
# [START kms_get_asymmetric_public]
26-
def getAsymmetricPublicKey(client, key_path):
53+
def get_asymmetric_public_key(key_name):
2754
"""
2855
Retrieves the public key from a saved asymmetric key pair on Cloud KMS
2956
57+
Example key_name:
58+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
59+
/KEY_ID/cryptoKeyVersions/1"
60+
3061
Requires:
3162
cryptography.hazmat.backends.default_backend
3263
cryptography.hazmat.primitives.serialization
3364
"""
34-
request = client.projects() \
35-
.locations() \
36-
.keyRings() \
37-
.cryptoKeys() \
38-
.cryptoKeyVersions() \
39-
.getPublicKey(name=key_path)
40-
response = request.execute()
41-
key_txt = response['pem'].encode('ascii')
65+
66+
client = kms_v1.KeyManagementServiceClient()
67+
response = client.get_public_key(key_name)
68+
69+
key_txt = response.pem.encode('ascii')
4270
key = serialization.load_pem_public_key(key_txt, default_backend())
4371
return key
4472
# [END kms_get_asymmetric_public]
4573

4674

4775
# [START kms_decrypt_rsa]
48-
def decryptRSA(ciphertext, client, key_path):
76+
def decrypt_rsa(ciphertext, key_name):
4977
"""
5078
Decrypt the input ciphertext (bytes) using an
5179
'RSA_DECRYPT_OAEP_2048_SHA256' private key stored on Cloud KMS
5280
53-
Requires:
54-
base64
81+
Example key_name:
82+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
83+
/KEY_ID/cryptoKeyVersions/1"
5584
"""
56-
request_body = {'ciphertext': base64.b64encode(ciphertext).decode('utf-8')}
57-
request = client.projects() \
58-
.locations() \
59-
.keyRings() \
60-
.cryptoKeys() \
61-
.cryptoKeyVersions() \
62-
.asymmetricDecrypt(name=key_path,
63-
body=request_body)
64-
response = request.execute()
65-
plaintext = base64.b64decode(response['plaintext'])
66-
return plaintext
85+
86+
client = kms_v1.KeyManagementServiceClient()
87+
response = client.asymmetric_decrypt(key_name, ciphertext)
88+
return response.plaintext
6789
# [END kms_decrypt_rsa]
6890

6991

7092
# [START kms_encrypt_rsa]
71-
def encryptRSA(plaintext, client, key_path):
93+
def encrypt_rsa(plaintext, key_name):
7294
"""
7395
Encrypt the input plaintext (bytes) locally using an
7496
'RSA_DECRYPT_OAEP_2048_SHA256' public key retrieved from Cloud KMS
7597
98+
Example key_name:
99+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
100+
/KEY_ID/cryptoKeyVersions/1"
101+
76102
Requires:
77103
cryptography.hazmat.primitives.asymmetric.padding
78104
cryptography.hazmat.primitives.hashes
79105
"""
80-
public_key = getAsymmetricPublicKey(client, key_path)
106+
# get the public key
107+
client = kms_v1.KeyManagementServiceClient()
108+
response = client.get_public_key(key_name)
109+
key_txt = response.pem.encode('ascii')
110+
public_key = serialization.load_pem_public_key(key_txt, default_backend())
111+
112+
# encrypt plaintext
81113
pad = padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
82114
algorithm=hashes.SHA256(),
83115
label=None)
@@ -86,46 +118,53 @@ def encryptRSA(plaintext, client, key_path):
86118

87119

88120
# [START kms_sign_asymmetric]
89-
def signAsymmetric(message, client, key_path):
121+
def sign_asymmetric(message, key_name):
90122
"""
91123
Create a signature for a message using a private key stored on Cloud KMS
92124
125+
Example key_name:
126+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
127+
/KEY_ID/cryptoKeyVersions/1"
128+
93129
Requires:
94-
base64
95130
hashlib
96131
"""
97132
# Note: some key algorithms will require a different hash function
98133
# For example, EC_SIGN_P384_SHA384 requires SHA384
134+
client = kms_v1.KeyManagementServiceClient()
99135
digest_bytes = hashlib.sha256(message).digest()
100-
digest64 = base64.b64encode(digest_bytes)
101-
102-
digest_JSON = {'sha256': digest64.decode('utf-8')}
103-
request = client.projects() \
104-
.locations() \
105-
.keyRings() \
106-
.cryptoKeys() \
107-
.cryptoKeyVersions() \
108-
.asymmetricSign(name=key_path,
109-
body={'digest': digest_JSON})
110-
response = request.execute()
111-
return base64.b64decode(response.get('signature', None))
136+
137+
digest_json = {'sha256': digest_bytes}
138+
139+
response = client.asymmetric_sign(key_name, digest_json)
140+
return response.signature
112141
# [END kms_sign_asymmetric]
113142

114143

115144
# [START kms_verify_signature_rsa]
116-
def verifySignatureRSA(signature, message, client, key_path):
145+
def verify_signature_rsa(signature, message, key_name):
117146
"""
118147
Verify the validity of an 'RSA_SIGN_PSS_2048_SHA256' signature for the
119148
specified message
120149
150+
Example key_name:
151+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
152+
/KEY_ID/cryptoKeyVersions/1"
153+
121154
Requires:
122155
cryptography.exceptions.InvalidSignature
123156
cryptography.hazmat.primitives.asymmetric.padding
124157
cryptography.hazmat.primitives.asymmetric.utils
125158
cryptography.hazmat.primitives.hashes
126159
hashlib
127160
"""
128-
public_key = getAsymmetricPublicKey(client, key_path)
161+
# get the public key
162+
client = kms_v1.KeyManagementServiceClient()
163+
response = client.get_public_key(key_name)
164+
key_txt = response.pem.encode('ascii')
165+
public_key = serialization.load_pem_public_key(key_txt, default_backend())
166+
167+
# get the digest of the message
129168
digest_bytes = hashlib.sha256(message).digest()
130169

131170
try:
@@ -143,19 +182,29 @@ def verifySignatureRSA(signature, message, client, key_path):
143182

144183

145184
# [START kms_verify_signature_ec]
146-
def verifySignatureEC(signature, message, client, key_path):
185+
def verify_signature_ec(signature, message, key_name):
147186
"""
148187
Verify the validity of an 'EC_SIGN_P256_SHA256' signature
149188
for the specified message
150189
190+
Example key_name:
191+
"projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
192+
/KEY_ID/cryptoKeyVersions/1"
193+
151194
Requires:
152195
cryptography.exceptions.InvalidSignature
153196
cryptography.hazmat.primitives.asymmetric.ec
154197
cryptography.hazmat.primitives.asymmetric.utils
155198
cryptography.hazmat.primitives.hashes
156199
hashlib
157200
"""
158-
public_key = getAsymmetricPublicKey(client, key_path)
201+
# get the public key
202+
client = kms_v1.KeyManagementServiceClient()
203+
response = client.get_public_key(key_name)
204+
key_txt = response.pem.encode('ascii')
205+
public_key = serialization.load_pem_public_key(key_txt, default_backend())
206+
207+
# get the digest of the message
159208
digest_bytes = hashlib.sha256(message).digest()
160209

161210
try:

0 commit comments

Comments
 (0)