KmsEnvelopeAead raises "TinkError: 400 {kek_URI} is not a valid resource type for this request."
Opened this issue · 2 comments
Describe the bug:
Following the Client-side encryption with Tink and Cloud KMS example for Python. I run into a "TinkError: 400 {kek_URI} is not a valid resource type for this request.
" on line 91: env_aead.decrypt(ciphertext, associated_data)
.
I have defined the KEK_URI correctly, I have tested env_aead.encrypt
several times and everything works perfectly with this KEK_URI, which follows the template: gcp-kms://projects/<PROJECT>/locations/<LOCATION>/keyRings/ <KEY RING>/cryptoKeys/<KEY NAME>/cryptoKeyVersions/<VERSION>
How can we reproduce the bug?
Since this worked some months ago, I think this could be related with a change either Google KMS or in my GCP account, I've tried both with Tink 1.8.0 and 1.9.0, the same happens. I have also tried with two different key rings and versions, and the error still appears.
KEK_URI = "gcp-kms://projects/ait-mlops/locations/us-central1/keyRings/test-keys/cryptoKeys/aitor-test/cryptoKeyVersions/1"
CYPHER_FILE_PATH = "path_to_encrypted_file_with_same_kek_uri"
ASSOCIATED_DATA = b''
import tink
from tink import aead
from tink.integration import gcpkms
# Initialise Tink
aead.register()
try:
# Read the GCP credentials and setup client
client = gcpkms.GcpKmsClient(KEK_URI, {})
except tink.TinkError as e:
logging.exception('Error creating GCP KMS client: %s', e)
# Create envelope AEAD primitive using AES256 GCM for encrypting the data
try:
remote_aead = client.get_aead(KEK_URI)
env_aead = aead.KmsEnvelopeAead(
aead.aead_key_templates.AES256_GCM, remote_aead
)
except tink.TinkError as e:
logging.exception('Error creating primitive: %s', e)
with open(CYPHER_FILE_PATH, 'rb') as f:
ciphertext = f.read()
env_aead.decrypt(ciphertext, ASSOCIATED_DATA)
Do you have any debugging information?
TinkError Traceback (most recent call last)
Cell In[24], line 3
1 with open(CYPHER_FILE_PATH, 'rb') as f:
2 ciphertext = f.read()
----> 3 env_aead.decrypt(ciphertext, ASSOCIATED_DATA)
File [~/micromamba/envs/p38/lib/python3.8/site-packages/tink/aead/_kms_envelope_aead.py:107](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/tink/aead/_kms_envelope_aead.py#line=106), in KmsEnvelopeAead.decrypt(self, ciphertext, associated_data)
104 # Decrypt DEK with remote AEAD
105 encrypted_dek_bytes = ciphertext[self.DEK_LEN_BYTES:self.DEK_LEN_BYTES +
106 dek_len]
--> 107 dek_bytes = self.remote_aead.decrypt(encrypted_dek_bytes, b'')
109 # Get AEAD primitive based on DEK
110 dek = tink_pb2.KeyData(
111 type_url=self.key_template.type_url,
112 value=dek_bytes,
113 key_material_type=tink_pb2.KeyData.SYMMETRIC,
114 )
File [~/micromamba/envs/p38/lib/python3.8/site-packages/tink/integration/gcpkms/_gcp_kms_client.py:63](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/tink/integration/gcpkms/_gcp_kms_client.py#line=62), in _GcpKmsAead.decrypt(self, ciphertext, associated_data)
61 return response.plaintext
62 except core_exceptions.GoogleAPIError as e:
---> 63 raise tink.TinkError(e)
TinkError: 400 projects[/{PROJECT}/locations/us-central1/keyRings/{KEY RING}/cryptoKeys/{KEY}/cryptoKeyVersions/1](http://localhost:33425/{PROJECT}/locations/us-central1/keyRings/{KEY RING}/cryptoKeys/{KEY}/cryptoKeyVersions/1) is not a valid resource type for this request.
What version of Tink are you using?
This happens both for Tink 1.8.0 and Tink 1.9.0.
Can you tell us more about your development environment?
- Python 3.8.11
Extended traceback
InvalidArgument Traceback (most recent call last)
File [~/micromamba/envs/p38/lib/python3.8/site-packages/tink/integration/gcpkms/_gcp_kms_client.py:54](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/tink/integration/gcpkms/_gcp_kms_client.py#line=53), in _GcpKmsAead.decrypt(self, ciphertext, associated_data)
53 try:
---> 54 response = self.client.decrypt(
55 request=kms_v1.types.service.DecryptRequest(
56 name=self.name,
57 ciphertext=ciphertext,
58 additional_authenticated_data=associated_data
59 )
60 )
61 return response.plaintext
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/cloud/kms_v1/services/key_management_service/client.py:3490](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/cloud/kms_v1/services/key_management_service/client.py#line=3489), in KeyManagementServiceClient.decrypt(self, request, name, ciphertext, retry, timeout, metadata)
3489 # Send the request.
-> 3490 response = rpc(
3491 request,
3492 retry=retry,
3493 timeout=timeout,
3494 metadata=metadata,
3495 )
3497 # Done; return the response.
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/gapic_v1/method.py:131](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/gapic_v1/method.py#line=130), in _GapicCallable.__call__(self, timeout, retry, compression, *args, **kwargs)
129 kwargs["compression"] = compression
--> 131 return wrapped_func(*args, **kwargs)
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py:293](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py#line=292), in Retry.__call__.<locals>.retry_wrapped_func(*args, **kwargs)
290 sleep_generator = exponential_sleep_generator(
291 self._initial, self._maximum, multiplier=self._multiplier
292 )
--> 293 return retry_target(
294 target,
295 self._predicate,
296 sleep_generator,
297 timeout=self._timeout,
298 on_error=on_error,
299 )
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py:153](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py#line=152), in retry_target(target, predicate, sleep_generator, timeout, on_error, exception_factory, **kwargs)
151 except Exception as exc:
152 # defer to shared logic for handling errors
--> 153 _retry_error_helper(
154 exc,
155 deadline,
156 sleep,
157 error_list,
158 predicate,
159 on_error,
160 exception_factory,
161 timeout,
162 )
163 # if exception not raised, sleep before next attempt
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_base.py:212](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_base.py#line=211), in _retry_error_helper(exc, deadline, next_sleep, error_list, predicate_fn, on_error_fn, exc_factory_fn, original_timeout)
207 final_exc, source_exc = exc_factory_fn(
208 error_list,
209 RetryFailureReason.NON_RETRYABLE_ERROR,
210 original_timeout,
211 )
--> 212 raise final_exc from source_exc
213 if on_error_fn is not None:
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py:144](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/retry/retry_unary.py#line=143), in retry_target(target, predicate, sleep_generator, timeout, on_error, exception_factory, **kwargs)
143 try:
--> 144 result = target()
145 if inspect.isawaitable(result):
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/timeout.py:120](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/timeout.py#line=119), in TimeToDeadlineTimeout.__call__.<locals>.func_with_timeout(*args, **kwargs)
118 kwargs["timeout"] = max(0, self._timeout - time_since_first_attempt)
--> 120 return func(*args, **kwargs)
File [~/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/grpc_helpers.py:78](http://localhost:33425/lab/tree/algotive/aiengine/aitrials_test/data_anonymization/micromamba/envs/p38/lib/python3.8/site-packages/google/api_core/grpc_helpers.py#line=77), in _wrap_unary_errors.<locals>.error_remapped_callable(*args, **kwargs)
77 except grpc.RpcError as exc:
---> 78 raise exceptions.from_grpc_error(exc) from exc
InvalidArgument: 400 projects[/{PROJECT}/locations/us-central1/keyRings/{KEY RING}/cryptoKeys/{KEY}/cryptoKeyVersions/1](http://localhost:33425/{PROJECT}/locations/us-central1/keyRings/{KEY RING}/cryptoKeys/{KEY}/cryptoKeyVersions/1) is not a valid resource type for this request.
This is related to having the /cryptoKeyVersions/1
at the end of KEK_URI. Normally you wouldn't need it and something like:
KEK_URI = "gcp-kms://projects/ait-mlops/locations/us-central1/keyRings/test-keys/cryptoKeys/aitor-test"
is enough. However, you may need it for decryption if using a non-primary key.
The issue has been addressed and will be available in the next release.
@mdetemad do you know when the next release will be available?
I have a use case where I want to choose the key version for encryption. That is important for me because setting the primary key is only eventually consistent on Cloud KMS, but I need to make sure that I'm using the new key version right after it is created.