huaweicloud-encryption-sdk-python 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- examples/file_encryption_example.py +57 -0
- examples/key_capsule_encryption_example.py +240 -0
- examples/kms_discovery_encryption_example.py +56 -0
- examples/local_aes_encryption_example.py +59 -0
- examples/test_rsa.py +42 -0
- examples/test_sm2.py +38 -0
- examples/test_sm4_cbc.py +37 -0
- examples/test_sm4_gcm.py +37 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/METADATA +18 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/RECORD +174 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/WHEEL +5 -0
- huaweicloud_encryption_sdk_python-1.2.1.dist-info/top_level.txt +3 -0
- huaweicloud_encryptionsdk/__init__.py +5 -0
- huaweicloud_encryptionsdk/_apig_sdk/__init__.py +1 -0
- huaweicloud_encryptionsdk/_apig_sdk/signer.py +278 -0
- huaweicloud_encryptionsdk/_apig_sdk/signer_v11.py +70 -0
- huaweicloud_encryptionsdk/_apig_sdk/sm3_hash.py +141 -0
- huaweicloud_encryptionsdk/_lts_sdk/auth/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/auth/signer.py +174 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/consumer_client_adapter.py +59 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/client/http_client.py +211 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/client_consumer_worker.py +106 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/consumer_heartbeat.py +73 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/core/log_shard_consumer.py +179 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_check_point_tracker.py +120 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor_factory.py +3 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/check_point.py +20 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/consumer_config.py +27 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/log_data.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/model/task_result.py +40 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/consumer_fetch_task.py +53 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/initial_task.py +55 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/process_task.py +25 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer/task/shutdown_task.py +24 -0
- huaweicloud_encryptionsdk/_lts_sdk/consumer_main.py +88 -0
- huaweicloud_encryptionsdk/_lts_sdk/parallel_main.py +64 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/callback/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/callback/call_back.py +7 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/accumulator.py +135 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_thread_pool.py +107 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_worker.py +124 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/mover.py +69 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/core/producer.py +98 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/http_client.py +63 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/simple_request.py +14 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/config.py +50 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/error.py +18 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/log.py +87 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/log_batch.py +154 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/lts_store.py +21 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/result.py +17 -0
- huaweicloud_encryptionsdk/_lts_sdk/producer/model/retry_queue.py +39 -0
- huaweicloud_encryptionsdk/_lts_sdk/serial_main.py +77 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/__init__.py +0 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/common.py +57 -0
- huaweicloud_encryptionsdk/_lts_sdk/utils/lts_threading.py +32 -0
- huaweicloud_encryptionsdk/cache/__init__.py +0 -0
- huaweicloud_encryptionsdk/cache/data_key_cache.py +79 -0
- huaweicloud_encryptionsdk/cache/local_data_key_cache.py +161 -0
- huaweicloud_encryptionsdk/common/__init__.py +0 -0
- huaweicloud_encryptionsdk/common/constants.py +15 -0
- huaweicloud_encryptionsdk/common/counting_output_stream.py +18 -0
- huaweicloud_encryptionsdk/common/crypto_factory.py +48 -0
- huaweicloud_encryptionsdk/common/ec_private_key_loader.py +43 -0
- huaweicloud_encryptionsdk/common/ecs_metadata_service.py +42 -0
- huaweicloud_encryptionsdk/common/file_path_for_example_constants.py +4 -0
- huaweicloud_encryptionsdk/common/utils.py +162 -0
- huaweicloud_encryptionsdk/exception/__init__.py +0 -0
- huaweicloud_encryptionsdk/exception/errors.py +109 -0
- huaweicloud_encryptionsdk/handler/__init__.py +0 -0
- huaweicloud_encryptionsdk/handler/cipher_handler.py +294 -0
- huaweicloud_encryptionsdk/handler/crypto_handler.py +24 -0
- huaweicloud_encryptionsdk/handler/default_crypto_handler.py +148 -0
- huaweicloud_encryptionsdk/handler/default_serialize_handler.py +45 -0
- huaweicloud_encryptionsdk/handler/file_decrypt_handler.py +101 -0
- huaweicloud_encryptionsdk/handler/file_encrypt_handler.py +30 -0
- huaweicloud_encryptionsdk/handler/serialize_handler.py +14 -0
- huaweicloud_encryptionsdk/huawei_config.py +49 -0
- huaweicloud_encryptionsdk/huawei_crypto.py +311 -0
- huaweicloud_encryptionsdk/keyrings/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/keyring.py +14 -0
- huaweicloud_encryptionsdk/keyrings/keyring_factory.py +10 -0
- huaweicloud_encryptionsdk/keyrings/kms_keyring_factory.py +21 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_discovery_keyring.py +51 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_key_capsule_keyring.py +100 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_keyring.py +155 -0
- huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_multi_region_keyring.py +8 -0
- huaweicloud_encryptionsdk/keyrings/raw_keyring_factory.py +27 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/__init__.py +0 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_aes_keyring.py +63 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_keyring.py +112 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_rsa_keyring.py +55 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm2_keyring.py +75 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_cbc_keyring.py +66 -0
- huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_keyring.py +70 -0
- huaweicloud_encryptionsdk/kms/__init__.py +0 -0
- huaweicloud_encryptionsdk/kms/create_key_capsule_request.py +35 -0
- huaweicloud_encryptionsdk/kms/create_key_capsule_response.py +19 -0
- huaweicloud_encryptionsdk/kms/decrypt_key_capsule_request.py +32 -0
- huaweicloud_encryptionsdk/kms/decrypt_key_capsule_response.py +19 -0
- huaweicloud_encryptionsdk/kms/kms_http_client.py +116 -0
- huaweicloud_encryptionsdk/log/__init__.py +0 -0
- huaweicloud_encryptionsdk/log/log_config.py +30 -0
- huaweicloud_encryptionsdk/log/log_file_backup.py +144 -0
- huaweicloud_encryptionsdk/log/log_metrics.py +132 -0
- huaweicloud_encryptionsdk/log/log_reporter_manager.py +163 -0
- huaweicloud_encryptionsdk/log/lts_sdk_producer.py +386 -0
- huaweicloud_encryptionsdk/log/lts_struct_log_builder.py +106 -0
- huaweicloud_encryptionsdk/meterialmanager/__init__.py +0 -0
- huaweicloud_encryptionsdk/meterialmanager/cache_crypto_meterial_manager.py +221 -0
- huaweicloud_encryptionsdk/meterialmanager/crypto_meterial_manager.py +19 -0
- huaweicloud_encryptionsdk/meterialmanager/data_key_generate.py +10 -0
- huaweicloud_encryptionsdk/meterialmanager/data_key_generate_factory.py +20 -0
- huaweicloud_encryptionsdk/meterialmanager/default_crypto_meterials_manager.py +71 -0
- huaweicloud_encryptionsdk/meterialmanager/key_capsule_data_key_generate.py +63 -0
- huaweicloud_encryptionsdk/meterialmanager/kms_data_key_generate.py +65 -0
- huaweicloud_encryptionsdk/meterialmanager/local_data_key_generate.py +13 -0
- huaweicloud_encryptionsdk/model/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/access_point_config.py +9 -0
- huaweicloud_encryptionsdk/model/cipher_body.py +81 -0
- huaweicloud_encryptionsdk/model/cipher_header.py +405 -0
- huaweicloud_encryptionsdk/model/ciphertext_data_key.py +166 -0
- huaweicloud_encryptionsdk/model/crypto_result.py +11 -0
- huaweicloud_encryptionsdk/model/data_key_materials.py +17 -0
- huaweicloud_encryptionsdk/model/data_materials.py +11 -0
- huaweicloud_encryptionsdk/model/enums/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/enums/access_point_type.py +28 -0
- huaweicloud_encryptionsdk/model/enums/crypto_algorithm.py +75 -0
- huaweicloud_encryptionsdk/model/enums/data_key_generate_type.py +20 -0
- huaweicloud_encryptionsdk/model/enums/key_provider_enum.py +19 -0
- huaweicloud_encryptionsdk/model/enums/keyring_type_enum.py +27 -0
- huaweicloud_encryptionsdk/model/key_capsule.py +10 -0
- huaweicloud_encryptionsdk/model/key_capsule_config.py +12 -0
- huaweicloud_encryptionsdk/model/kms_config.py +10 -0
- huaweicloud_encryptionsdk/model/request/__init__.py +0 -0
- huaweicloud_encryptionsdk/model/request/encrypt_request.py +10 -0
- huaweicloud_encryptionsdk/model/request/sign_request.py +2 -0
- huaweicloud_encryptionsdk/model/request/verify_request.py +2 -0
- huaweicloud_encryptionsdk/proof/__init__.py +0 -0
- huaweicloud_encryptionsdk/proof/attestation_document.py +36 -0
- huaweicloud_encryptionsdk/proof/collector/__init__.py +0 -0
- huaweicloud_encryptionsdk/proof/collector/cce_proof_collector.py +24 -0
- huaweicloud_encryptionsdk/proof/collector/ecs_proof_collector.py +11 -0
- huaweicloud_encryptionsdk/proof/collector/key_pair_proof_collector.py +55 -0
- huaweicloud_encryptionsdk/proof/collector/ma_proof_collector.py +51 -0
- huaweicloud_encryptionsdk/proof/private_key_decrypt_callback.py +7 -0
- huaweicloud_encryptionsdk/proof/proof_collector.py +11 -0
- huaweicloud_encryptionsdk/proof/proof_collector_factory.py +53 -0
- huaweicloud_encryptionsdk/proof/proof_info.py +10 -0
- huaweicloud_encryptionsdk/util/__init__.py +0 -0
- huaweicloud_encryptionsdk/util/common_utils.py +12 -0
- tests/__init__.py +0 -0
- tests/test_enums.py +84 -0
- tests/test_exceptions.py +38 -0
- tests/test_factories.py +71 -0
- tests/test_huawei_crypto.py +67 -0
- tests/test_imports.py +46 -0
- tests/test_kms_models.py +95 -0
- tests/test_log_file_backup.py +45 -0
- tests/test_lts_struct_log_builder.py +97 -0
- tests/test_models.py +142 -0
- tests/test_utils.py +111 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
import base64
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
from huaweicloud_encryptionsdk.meterialmanager.crypto_meterial_manager import CryptoMaterialManager
|
|
7
|
+
from huaweicloud_encryptionsdk.meterialmanager.default_crypto_meterials_manager import DefaultCryptoMaterialsManager
|
|
8
|
+
from huaweicloud_encryptionsdk.cache.data_key_cache import DataKeyCache, UsageStatus
|
|
9
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
10
|
+
from huaweicloud_encryptionsdk.model.key_capsule import KeyCapsule
|
|
11
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
12
|
+
from huaweicloud_encryptionsdk.common.constants import NUM_1
|
|
13
|
+
from huaweicloud_encryptionsdk.common.crypto_factory import CryptoFactory
|
|
14
|
+
from huaweicloud_encryptionsdk.common.utils import serialize_context
|
|
15
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CacheCryptoMaterialsManager(CryptoMaterialManager):
|
|
21
|
+
|
|
22
|
+
CACHE_ID_ALGORITHM_SHA = "SHA-256"
|
|
23
|
+
CACHE_ID_ALGORITHM_SM3 = "SM3"
|
|
24
|
+
DEFAULT_MESSAGE_LIMIT = 0x7FFFFFFF
|
|
25
|
+
DEFAULT_BYTE_LIMIT = 0x7FFFFFFFFFFFFFFF
|
|
26
|
+
|
|
27
|
+
def __init__(self, cache: DataKeyCache, huawei_config):
|
|
28
|
+
self._cache = cache
|
|
29
|
+
self._max_byte_limit = self.DEFAULT_BYTE_LIMIT
|
|
30
|
+
self._max_message_limit = self.DEFAULT_MESSAGE_LIMIT
|
|
31
|
+
self._huawei_config = huawei_config
|
|
32
|
+
self._crypto_material_manager = DefaultCryptoMaterialsManager(huawei_config)
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def max_byte_limit(self) -> int:
|
|
36
|
+
return self._max_byte_limit
|
|
37
|
+
|
|
38
|
+
def set_survival_time(self, survival_time: int) -> "CacheCryptoMaterialsManager":
|
|
39
|
+
if survival_time <= 0:
|
|
40
|
+
raise HuaweicloudException(ErrorMessage.CACHE_PARAM_LESS_THAN_ZERO.message)
|
|
41
|
+
self._cache.set_survival_time(survival_time)
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def set_max_message_limit(self, max_message_limit: int) -> "CacheCryptoMaterialsManager":
|
|
45
|
+
if max_message_limit <= 0:
|
|
46
|
+
raise HuaweicloudException(ErrorMessage.CACHE_PARAM_LESS_THAN_ZERO.message)
|
|
47
|
+
self._max_message_limit = max_message_limit
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
def set_max_byte_limit(self, max_byte_limit: int) -> "CacheCryptoMaterialsManager":
|
|
51
|
+
if max_byte_limit <= 0:
|
|
52
|
+
raise HuaweicloudException(ErrorMessage.CACHE_PARAM_LESS_THAN_ZERO.message)
|
|
53
|
+
self._max_byte_limit = max_byte_limit
|
|
54
|
+
return self
|
|
55
|
+
|
|
56
|
+
def get_materials_for_encrypt(self, keyring, data_key_materials: DataKeyMaterials, plain_text_length: int) -> DataKeyMaterials:
|
|
57
|
+
cache_id = self._get_cache_id(data_key_materials)
|
|
58
|
+
usage_status = UsageStatus(plain_text_length, NUM_1)
|
|
59
|
+
entry_for_encrypt = self._cache.get_entry_for_encrypt(cache_id, usage_status)
|
|
60
|
+
if entry_for_encrypt is not None:
|
|
61
|
+
usage_status_new = entry_for_encrypt.get_usage_status()
|
|
62
|
+
if self._check_exceed_limit(usage_status_new):
|
|
63
|
+
logger.info("get encrypt dataKeyMaterials from cache success, cacheId %s", cache_id)
|
|
64
|
+
return entry_for_encrypt.get_data_key_materials()
|
|
65
|
+
logger.info("dataKeyMaterials of cacheId %s exceed message limit, generate data key again", cache_id)
|
|
66
|
+
entry_for_encrypt.invalidate()
|
|
67
|
+
logger.info("dataKeyMaterials of cacheId %s not exists or expired, generate data key again", cache_id)
|
|
68
|
+
self._crypto_material_manager.get_materials_for_encrypt(keyring, data_key_materials, plain_text_length)
|
|
69
|
+
self._cache.put_entry_for_encrypt(cache_id, data_key_materials, usage_status)
|
|
70
|
+
return data_key_materials
|
|
71
|
+
|
|
72
|
+
def get_materials_for_decrypt(self, keyring, cipher_text: bytes) -> DataKeyMaterials:
|
|
73
|
+
from huaweicloud_encryptionsdk.handler.default_serialize_handler import DefaultSerializeHandler
|
|
74
|
+
data_materials = DefaultSerializeHandler().deserialize(cipher_text)
|
|
75
|
+
headers = data_materials.headers
|
|
76
|
+
cache_id = self._get_cache_id_from_headers(
|
|
77
|
+
headers.algorithm, headers.encryption_context,
|
|
78
|
+
headers.ciphertext_data_keys, headers.key_capsule,
|
|
79
|
+
)
|
|
80
|
+
entry_for_decrypt = self._cache.get_entry_for_decrypt(cache_id)
|
|
81
|
+
if entry_for_decrypt is not None:
|
|
82
|
+
logger.info("get decrypt dataKeyMaterials from cache success, cacheId %s", cache_id)
|
|
83
|
+
return entry_for_decrypt.get_data_key_materials()
|
|
84
|
+
logger.info("dataKeyMaterials of cacheId %s not exists or expired, Re-decrypt the dataKey", cache_id)
|
|
85
|
+
data_key_materials = DataKeyMaterials()
|
|
86
|
+
data_key_materials.ciphertext_data_keys = headers.ciphertext_data_keys
|
|
87
|
+
data_key_materials.crypto_algorithm = headers.algorithm
|
|
88
|
+
data_key_materials.encryption_contexts = headers.encryption_context
|
|
89
|
+
if headers.key_capsule is not None:
|
|
90
|
+
data_key_materials.key_capsule = headers.key_capsule
|
|
91
|
+
data_key_materials = keyring.decrypt_data_key(data_key_materials)
|
|
92
|
+
self._cache.put_entry_for_decrypt(cache_id, data_key_materials)
|
|
93
|
+
return data_key_materials
|
|
94
|
+
|
|
95
|
+
def get_materials_for_stream_decrypt(self, keyring, input_stream) -> DataKeyMaterials:
|
|
96
|
+
from huaweicloud_encryptionsdk.handler.default_serialize_handler import DefaultSerializeHandler
|
|
97
|
+
length_byte = input_stream.read(2)
|
|
98
|
+
if len(length_byte) != 2:
|
|
99
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
100
|
+
length = struct.unpack(">h", length_byte)[0]
|
|
101
|
+
bytes_data = input_stream.read(length)
|
|
102
|
+
if len(bytes_data) != length:
|
|
103
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
104
|
+
data_materials = DefaultSerializeHandler().deserialize(bytes_data)
|
|
105
|
+
cache_id = self._get_cache_id_from_headers(
|
|
106
|
+
data_materials.headers.algorithm,
|
|
107
|
+
data_materials.headers.encryption_context,
|
|
108
|
+
data_materials.headers.ciphertext_data_keys,
|
|
109
|
+
data_materials.headers.key_capsule,
|
|
110
|
+
)
|
|
111
|
+
entry_for_decrypt = self._cache.get_entry_for_decrypt(cache_id)
|
|
112
|
+
if entry_for_decrypt is not None:
|
|
113
|
+
logger.info("get decrypt dataKeyMaterials from cache success, cacheId %s", cache_id)
|
|
114
|
+
return entry_for_decrypt.get_data_key_materials()
|
|
115
|
+
logger.info("dataKeyMaterials of cacheId %s not exists or expired, Re-decrypt the dataKey", cache_id)
|
|
116
|
+
data_key_materials = DataKeyMaterials()
|
|
117
|
+
data_key_materials.ciphertext_data_keys = data_materials.headers.ciphertext_data_keys
|
|
118
|
+
data_key_materials.crypto_algorithm = data_materials.headers.algorithm
|
|
119
|
+
data_key_materials.encryption_contexts = data_materials.headers.encryption_context
|
|
120
|
+
if data_materials.headers.key_capsule is not None:
|
|
121
|
+
data_key_materials.key_capsule = data_materials.headers.key_capsule
|
|
122
|
+
keyring.decrypt_data_key(data_key_materials)
|
|
123
|
+
self._cache.put_entry_for_decrypt(cache_id, data_key_materials)
|
|
124
|
+
return data_key_materials
|
|
125
|
+
|
|
126
|
+
def _get_cache_id(self, data_key_materials: DataKeyMaterials) -> str:
|
|
127
|
+
try:
|
|
128
|
+
algorithm = data_key_materials.crypto_algorithm
|
|
129
|
+
if algorithm in (CryptoAlgorithm.SM4_128_GCM_NOPADDING, CryptoAlgorithm.SM4_128_CBC_PADDING):
|
|
130
|
+
digest = CryptoFactory.get_message_digest(self.CACHE_ID_ALGORITHM_SM3)
|
|
131
|
+
else:
|
|
132
|
+
digest = CryptoFactory.get_message_digest(self.CACHE_ID_ALGORITHM_SHA)
|
|
133
|
+
self._digest_algorithm(algorithm, digest)
|
|
134
|
+
bytes_ctx = serialize_context(data_key_materials.encryption_contexts)
|
|
135
|
+
self._digest_context(digest, bytes_ctx)
|
|
136
|
+
self._digest_key_capsule_from_config(digest, self._huawei_config, data_key_materials)
|
|
137
|
+
return base64.b64encode(digest.digest()).decode("utf-8")
|
|
138
|
+
except Exception as e:
|
|
139
|
+
raise HuaweicloudException(ErrorMessage.MESSAGE_DIGEST_ERROR.message, e)
|
|
140
|
+
|
|
141
|
+
def _get_cache_id_from_headers(self, algorithm, encryption_context, ciphertext_data_keys, key_capsule) -> str:
|
|
142
|
+
try:
|
|
143
|
+
if algorithm in (CryptoAlgorithm.SM4_128_GCM_NOPADDING, CryptoAlgorithm.SM4_128_CBC_PADDING):
|
|
144
|
+
digest = CryptoFactory.get_message_digest(self.CACHE_ID_ALGORITHM_SM3)
|
|
145
|
+
else:
|
|
146
|
+
digest = CryptoFactory.get_message_digest(self.CACHE_ID_ALGORITHM_SHA)
|
|
147
|
+
self._digest_algorithm(algorithm, digest)
|
|
148
|
+
bytes_ctx = serialize_context(encryption_context)
|
|
149
|
+
self._digest_context(digest, bytes_ctx)
|
|
150
|
+
self._digest_ciphertext_data_keys(digest, ciphertext_data_keys)
|
|
151
|
+
self._digest_key_capsule(digest, key_capsule)
|
|
152
|
+
return base64.b64encode(digest.digest()).decode("utf-8")
|
|
153
|
+
except Exception as e:
|
|
154
|
+
raise HuaweicloudException(ErrorMessage.MESSAGE_DIGEST_ERROR.message, e)
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def _digest_context(digest, bytes_ctx: bytes) -> None:
|
|
158
|
+
if len(bytes_ctx) == 0:
|
|
159
|
+
digest.update(b'\x00')
|
|
160
|
+
else:
|
|
161
|
+
digest.update(bytes_ctx)
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def _digest_algorithm(algorithm, digest) -> None:
|
|
165
|
+
if algorithm is None:
|
|
166
|
+
digest.update(b'\x00')
|
|
167
|
+
else:
|
|
168
|
+
digest.update(b'\x01')
|
|
169
|
+
digest.update(algorithm.key_spec.encode("utf-8"))
|
|
170
|
+
|
|
171
|
+
def _check_exceed_limit(self, usage_status: UsageStatus) -> bool:
|
|
172
|
+
return (usage_status.bytes_encrypt_count <= self._max_byte_limit
|
|
173
|
+
and usage_status.message_encrypt_count <= self._max_message_limit)
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def _digest_ciphertext_data_keys(digest, ciphertext_data_keys) -> None:
|
|
177
|
+
if ciphertext_data_keys is None:
|
|
178
|
+
digest.update(b'\x00')
|
|
179
|
+
else:
|
|
180
|
+
digest.update(b'\x01')
|
|
181
|
+
digest.update(bytes([len(ciphertext_data_keys)]))
|
|
182
|
+
sorted_keys = sorted(ciphertext_data_keys, key=lambda k: k.data_key if hasattr(k, 'data_key') else b'')
|
|
183
|
+
for cdk in sorted_keys:
|
|
184
|
+
if hasattr(cdk, 'to_byte_array'):
|
|
185
|
+
digest.update(cdk.to_byte_array())
|
|
186
|
+
elif hasattr(cdk, 'data_key'):
|
|
187
|
+
digest.update(cdk.data_key)
|
|
188
|
+
|
|
189
|
+
@staticmethod
|
|
190
|
+
def _digest_key_capsule(digest, key_capsule: Optional[KeyCapsule]) -> None:
|
|
191
|
+
if key_capsule is None:
|
|
192
|
+
digest.update(b'\x00')
|
|
193
|
+
else:
|
|
194
|
+
digest.update(b'\x01')
|
|
195
|
+
if key_capsule.key_id is not None:
|
|
196
|
+
digest.update(key_capsule.key_id.encode("utf-8"))
|
|
197
|
+
if key_capsule.datakey_capsule is not None:
|
|
198
|
+
digest.update(key_capsule.datakey_capsule.encode("utf-8"))
|
|
199
|
+
digest.update(bytes([key_capsule.access_point_type]))
|
|
200
|
+
|
|
201
|
+
@staticmethod
|
|
202
|
+
def _digest_key_capsule_from_config(digest, huawei_config, data_key_materials: DataKeyMaterials) -> None:
|
|
203
|
+
key_capsule_config = huawei_config.key_capsule_config if huawei_config else None
|
|
204
|
+
if key_capsule_config is None:
|
|
205
|
+
digest.update(b'\x00')
|
|
206
|
+
else:
|
|
207
|
+
digest.update(b'\x01')
|
|
208
|
+
from huaweicloud_encryptionsdk.common.utils import get_capsule_kms_config
|
|
209
|
+
kms_config = get_capsule_kms_config(huawei_config.kms_config_list, key_capsule_config)
|
|
210
|
+
if kms_config and kms_config.key_id:
|
|
211
|
+
digest.update(kms_config.key_id.encode("utf-8"))
|
|
212
|
+
if data_key_materials.key_policy or data_key_materials.policy_id:
|
|
213
|
+
if data_key_materials.key_policy:
|
|
214
|
+
digest.update(data_key_materials.key_policy.encode("utf-8"))
|
|
215
|
+
elif data_key_materials.policy_id:
|
|
216
|
+
digest.update(data_key_materials.policy_id.encode("utf-8"))
|
|
217
|
+
else:
|
|
218
|
+
if key_capsule_config.default_key_policy:
|
|
219
|
+
digest.update(key_capsule_config.default_key_policy.encode("utf-8"))
|
|
220
|
+
elif key_capsule_config.default_policy_id:
|
|
221
|
+
digest.update(key_capsule_config.default_policy_id.encode("utf-8"))
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CryptoMaterialManager(ABC):
|
|
8
|
+
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def get_materials_for_encrypt(self, keyring, data_key_materials: DataKeyMaterials, plain_text_length: int) -> DataKeyMaterials:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def get_materials_for_decrypt(self, keyring, cipher_text: bytes) -> DataKeyMaterials:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def get_materials_for_stream_decrypt(self, keyring, input_stream) -> DataKeyMaterials:
|
|
19
|
+
pass
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DataKeyGenerate(ABC):
|
|
7
|
+
|
|
8
|
+
@abstractmethod
|
|
9
|
+
def data_key_generate(self, huawei_config, data_key_materials: DataKeyMaterials) -> None:
|
|
10
|
+
pass
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
2
|
+
from huaweicloud_encryptionsdk.meterialmanager.data_key_generate import DataKeyGenerate
|
|
3
|
+
from huaweicloud_encryptionsdk.meterialmanager.local_data_key_generate import LocalDataKeyGenerate
|
|
4
|
+
from huaweicloud_encryptionsdk.meterialmanager.kms_data_key_generate import KmsDataKeyGenerate
|
|
5
|
+
from huaweicloud_encryptionsdk.meterialmanager.key_capsule_data_key_generate import KeyCapsuleDataKeyGenerate
|
|
6
|
+
from huaweicloud_encryptionsdk.model.enums.data_key_generate_type import DataKeyGenerateType
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DataKeyGenerateFactory:
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def get_data_key_generate(data_key_generate_type: DataKeyGenerateType) -> DataKeyGenerate:
|
|
13
|
+
if data_key_generate_type == DataKeyGenerateType.LOCAL_GENERATE:
|
|
14
|
+
return LocalDataKeyGenerate()
|
|
15
|
+
elif data_key_generate_type == DataKeyGenerateType.KMS_GENERATE:
|
|
16
|
+
return KmsDataKeyGenerate()
|
|
17
|
+
elif data_key_generate_type == DataKeyGenerateType.KEY_CAPSULE_GENERATE:
|
|
18
|
+
return KeyCapsuleDataKeyGenerate()
|
|
19
|
+
else:
|
|
20
|
+
raise HuaweicloudException(ErrorMessage.DATA_KEY_GENERATE_EXCEPTION.message)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from huaweicloud_encryptionsdk.meterialmanager.crypto_meterial_manager import CryptoMaterialManager
|
|
5
|
+
from huaweicloud_encryptionsdk.meterialmanager.data_key_generate_factory import DataKeyGenerateFactory
|
|
6
|
+
from huaweicloud_encryptionsdk.model.enums.data_key_generate_type import DataKeyGenerateType
|
|
7
|
+
from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
|
|
8
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DefaultCryptoMaterialsManager(CryptoMaterialManager):
|
|
12
|
+
|
|
13
|
+
def __init__(self, huawei_config=None):
|
|
14
|
+
self._huawei_config = huawei_config
|
|
15
|
+
|
|
16
|
+
def get_materials_for_encrypt(self, keyring, data_key_materials: DataKeyMaterials, plain_text_length: int) -> DataKeyMaterials:
|
|
17
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_key_capsule_keyring import KMSKeyCapsuleKeyring
|
|
18
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
19
|
+
if isinstance(keyring, KMSKeyCapsuleKeyring):
|
|
20
|
+
data_key_generate = DataKeyGenerateFactory.get_data_key_generate(DataKeyGenerateType.KEY_CAPSULE_GENERATE)
|
|
21
|
+
if hasattr(keyring, 'set_huawei_config'):
|
|
22
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
23
|
+
elif isinstance(keyring, KMSKeyring):
|
|
24
|
+
data_key_generate = DataKeyGenerateFactory.get_data_key_generate(DataKeyGenerateType.KMS_GENERATE)
|
|
25
|
+
if hasattr(keyring, 'set_huawei_config'):
|
|
26
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
27
|
+
else:
|
|
28
|
+
data_key_generate = DataKeyGenerateFactory.get_data_key_generate(DataKeyGenerateType.LOCAL_GENERATE)
|
|
29
|
+
data_key_generate.data_key_generate(self._huawei_config, data_key_materials)
|
|
30
|
+
return keyring.encrypt_data_key(data_key_materials)
|
|
31
|
+
|
|
32
|
+
def get_materials_for_decrypt(self, keyring, cipher_text: bytes) -> DataKeyMaterials:
|
|
33
|
+
from huaweicloud_encryptionsdk.handler.default_serialize_handler import DefaultSerializeHandler
|
|
34
|
+
data_key_materials = DataKeyMaterials()
|
|
35
|
+
data_materials = DefaultSerializeHandler().deserialize(cipher_text)
|
|
36
|
+
data_key_materials.ciphertext_data_keys = data_materials.headers.ciphertext_data_keys
|
|
37
|
+
data_key_materials.crypto_algorithm = data_materials.headers.algorithm
|
|
38
|
+
data_key_materials.encryption_contexts = data_materials.headers.encryption_context
|
|
39
|
+
if data_materials.headers.key_capsule is not None:
|
|
40
|
+
data_key_materials.key_capsule = data_materials.headers.key_capsule
|
|
41
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_key_capsule_keyring import KMSKeyCapsuleKeyring
|
|
42
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
43
|
+
if isinstance(keyring, KMSKeyCapsuleKeyring) and hasattr(keyring, 'set_huawei_config'):
|
|
44
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
45
|
+
elif isinstance(keyring, KMSKeyring) and hasattr(keyring, 'set_huawei_config'):
|
|
46
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
47
|
+
return keyring.decrypt_data_key(data_key_materials)
|
|
48
|
+
|
|
49
|
+
def get_materials_for_stream_decrypt(self, keyring, input_stream) -> DataKeyMaterials:
|
|
50
|
+
from huaweicloud_encryptionsdk.handler.default_serialize_handler import DefaultSerializeHandler
|
|
51
|
+
length_byte = input_stream.read(2)
|
|
52
|
+
if len(length_byte) != 2:
|
|
53
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
54
|
+
length = struct.unpack(">h", length_byte)[0]
|
|
55
|
+
bytes_data = input_stream.read(length)
|
|
56
|
+
if len(bytes_data) != length:
|
|
57
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
58
|
+
data_materials = DefaultSerializeHandler().deserialize(bytes_data)
|
|
59
|
+
data_key_materials = DataKeyMaterials()
|
|
60
|
+
data_key_materials.ciphertext_data_keys = data_materials.headers.ciphertext_data_keys
|
|
61
|
+
data_key_materials.crypto_algorithm = data_materials.headers.algorithm
|
|
62
|
+
data_key_materials.encryption_contexts = data_materials.headers.encryption_context
|
|
63
|
+
if data_materials.headers.key_capsule is not None:
|
|
64
|
+
data_key_materials.key_capsule = data_materials.headers.key_capsule
|
|
65
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_key_capsule_keyring import KMSKeyCapsuleKeyring
|
|
66
|
+
from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
|
|
67
|
+
if isinstance(keyring, KMSKeyCapsuleKeyring) and hasattr(keyring, 'set_huawei_config'):
|
|
68
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
69
|
+
elif isinstance(keyring, KMSKeyring) and hasattr(keyring, 'set_huawei_config'):
|
|
70
|
+
keyring.set_huawei_config(self._huawei_config)
|
|
71
|
+
return keyring.decrypt_data_key(data_key_materials)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
2
|
+
from huaweicloud_encryptionsdk.meterialmanager.data_key_generate import DataKeyGenerate
|
|
3
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
4
|
+
from huaweicloud_encryptionsdk.model.key_capsule import KeyCapsule
|
|
5
|
+
from huaweicloud_encryptionsdk.common.utils import is_empty, hex_to_bytes, get_capsule_kms_config
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class KeyCapsuleDataKeyGenerate(DataKeyGenerate):
|
|
9
|
+
|
|
10
|
+
def data_key_generate(self, huawei_config, data_key_materials) -> None:
|
|
11
|
+
kms_config = get_capsule_kms_config(huawei_config.kms_config_list, huawei_config.key_capsule_config)
|
|
12
|
+
response = self._create_key_capsule_by_kms(data_key_materials, huawei_config.key_capsule_config, huawei_config, kms_config)
|
|
13
|
+
key_capsule = self._parse_key_capsule(response, huawei_config.key_capsule_config)
|
|
14
|
+
plaintext_data_key = self._parse_plaintext_data_key(response)
|
|
15
|
+
data_key_materials.key_capsule = key_capsule
|
|
16
|
+
data_key_materials.plaintext_data_key = plaintext_data_key
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def _create_key_capsule_by_kms(data_key_materials, config, huawei_config, kms_config):
|
|
20
|
+
try:
|
|
21
|
+
from huaweicloud_encryptionsdk.kms.kms_http_client import KmsHttpClient
|
|
22
|
+
from huaweicloud_encryptionsdk.kms.create_key_capsule_request import CreateKeyCapsuleRequest
|
|
23
|
+
client = KmsHttpClient(huawei_config.get_ak(), huawei_config.get_sk(), kms_config, huawei_config.security_token)
|
|
24
|
+
request = KeyCapsuleDataKeyGenerate._build_request_body(data_key_materials, config, huawei_config, kms_config)
|
|
25
|
+
return client.post("/kms/datakey-capsule/create", request)
|
|
26
|
+
except Exception as e:
|
|
27
|
+
raise HuaweicloudException(ErrorMessage.KMS_CREATE_KEY_EXCEPTION.message, e)
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def _build_request_body(data_key_materials, config, huawei_config, kms_config):
|
|
31
|
+
crypto_algorithm = huawei_config.crypto_algorithm
|
|
32
|
+
if crypto_algorithm == CryptoAlgorithm.SM4_128_GCM_NOPADDING:
|
|
33
|
+
crypto_algorithm = CryptoAlgorithm.AES_128_GCM_NOPADDING
|
|
34
|
+
from huaweicloud_encryptionsdk.kms.create_key_capsule_request import CreateKeyCapsuleRequest
|
|
35
|
+
body = CreateKeyCapsuleRequest(
|
|
36
|
+
key_id=kms_config.key_id,
|
|
37
|
+
datakey_length=crypto_algorithm.datakey_length,
|
|
38
|
+
)
|
|
39
|
+
policy_id = data_key_materials.policy_id
|
|
40
|
+
key_policy = data_key_materials.key_policy
|
|
41
|
+
if policy_id is None and key_policy is None:
|
|
42
|
+
policy_id = config.default_policy_id if config else None
|
|
43
|
+
key_policy = config.default_key_policy if config else None
|
|
44
|
+
if key_policy:
|
|
45
|
+
body.key_policy = key_policy
|
|
46
|
+
elif policy_id:
|
|
47
|
+
body.policy_id = policy_id
|
|
48
|
+
return body
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def _parse_key_capsule(response, config):
|
|
52
|
+
return KeyCapsule(
|
|
53
|
+
key_id=response.get("key_id"),
|
|
54
|
+
datakey_capsule=response.get("datakey_capsule"),
|
|
55
|
+
access_point_type=config.access_point_config.type if config and config.access_point_config else 0,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def _parse_plaintext_data_key(response):
|
|
60
|
+
try:
|
|
61
|
+
return hex_to_bytes(response.get("datakey", ""))
|
|
62
|
+
except Exception as e:
|
|
63
|
+
raise HuaweicloudException("Failed to parse plaintext data key", e)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
2
|
+
from huaweicloud_encryptionsdk.meterialmanager.data_key_generate import DataKeyGenerate
|
|
3
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
4
|
+
from huaweicloud_encryptionsdk.common.utils import is_empty, hex_to_bytes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class KmsDataKeyGenerate(DataKeyGenerate):
|
|
8
|
+
|
|
9
|
+
def data_key_generate(self, huawei_config, data_key_materials) -> None:
|
|
10
|
+
kms_config_list = huawei_config.kms_config_list
|
|
11
|
+
if is_empty(kms_config_list):
|
|
12
|
+
raise HuaweicloudException(ErrorMessage.CONFIG_NULL_ERROR.message)
|
|
13
|
+
for kms_config in kms_config_list:
|
|
14
|
+
response = self._create_data_key_by_kms(
|
|
15
|
+
kms_config.region, kms_config.key_id, kms_config.end_point,
|
|
16
|
+
huawei_config.ak, huawei_config.sk, kms_config.project_id,
|
|
17
|
+
huawei_config.crypto_algorithm,
|
|
18
|
+
huawei_config.security_token,
|
|
19
|
+
)
|
|
20
|
+
plaint_bytes = hex_to_bytes(response.get("plain_text", ""))
|
|
21
|
+
data_key_materials.plaintext_data_key = plaint_bytes
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def _create_data_key_by_kms(region_str, key_id, end_point, ak, sk, project_id, algorithm, security_token=None):
|
|
26
|
+
try:
|
|
27
|
+
from huaweicloudsdkcore.auth.credentials import BasicCredentials
|
|
28
|
+
from huaweicloudsdkkms.v2.region.kms_region import KmsRegion
|
|
29
|
+
from huaweicloudsdkkms.v2.kms_client import KmsClient
|
|
30
|
+
from huaweicloudsdkkms.v2.model.create_datakey_request import CreateDatakeyRequest
|
|
31
|
+
from huaweicloudsdkkms.v2.model.create_datakey_request_body import CreateDatakeyRequestBody
|
|
32
|
+
|
|
33
|
+
credentials = BasicCredentials(ak, sk, project_id)
|
|
34
|
+
if security_token:
|
|
35
|
+
credentials = credentials.with_security_token(security_token)
|
|
36
|
+
if end_point:
|
|
37
|
+
from huaweicloudsdkcore.region.region import Region
|
|
38
|
+
region = Region(region_str, end_point)
|
|
39
|
+
else:
|
|
40
|
+
region = KmsRegion.value_of(region_str)
|
|
41
|
+
client = (
|
|
42
|
+
KmsClient.new_builder()
|
|
43
|
+
.with_credentials(credentials)
|
|
44
|
+
.with_region(region)
|
|
45
|
+
.build()
|
|
46
|
+
)
|
|
47
|
+
request = CreateDatakeyRequest()
|
|
48
|
+
key_spec = algorithm.key_spec
|
|
49
|
+
if CryptoAlgorithm.SM4_128_GCM_NOPADDING.key_spec.lower() == key_spec.lower():
|
|
50
|
+
key_spec = CryptoAlgorithm.AES_128_GCM_NOPADDING.key_spec
|
|
51
|
+
body = CreateDatakeyRequestBody(
|
|
52
|
+
datakey_length=str(algorithm.key_len * 8),
|
|
53
|
+
key_id=key_id,
|
|
54
|
+
key_spec=key_spec,
|
|
55
|
+
)
|
|
56
|
+
request.body = body
|
|
57
|
+
response = client.create_datakey(request)
|
|
58
|
+
return {
|
|
59
|
+
"plain_text": response.plain_text,
|
|
60
|
+
"cipher_text": response.cipher_text,
|
|
61
|
+
}
|
|
62
|
+
except HuaweicloudException:
|
|
63
|
+
raise
|
|
64
|
+
except Exception as e:
|
|
65
|
+
raise HuaweicloudException(ErrorMessage.KMS_CREATE_KEY_EXCEPTION.message, e)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from huaweicloud_encryptionsdk.meterialmanager.data_key_generate import DataKeyGenerate
|
|
4
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
5
|
+
from huaweicloud_encryptionsdk.common.constants import KEY_SPEC_DELIMITER
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LocalDataKeyGenerate(DataKeyGenerate):
|
|
9
|
+
|
|
10
|
+
def data_key_generate(self, huawei_config, data_key_materials) -> None:
|
|
11
|
+
algorithm = huawei_config.crypto_algorithm
|
|
12
|
+
key_len = algorithm.key_len
|
|
13
|
+
data_key_materials.plaintext_data_key = os.urandom(key_len)
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
|
|
3
|
+
from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
|
|
4
|
+
from huaweicloud_encryptionsdk.exception.errors import HuaweicloudException, ErrorMessage
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CipherBody:
|
|
8
|
+
|
|
9
|
+
def __init__(self, iv=None, encrypted_content=None, encrypted_content_length=0, auth_tag=None):
|
|
10
|
+
self._iv = iv if iv is not None else b""
|
|
11
|
+
self._encrypted_content = encrypted_content if encrypted_content is not None else b""
|
|
12
|
+
self._encrypted_content_length = encrypted_content_length
|
|
13
|
+
self._auth_tag = auth_tag if auth_tag is not None else b""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def iv(self):
|
|
17
|
+
return self._iv
|
|
18
|
+
|
|
19
|
+
@iv.setter
|
|
20
|
+
def iv(self, value):
|
|
21
|
+
self._iv = value
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def encrypted_content(self):
|
|
25
|
+
return self._encrypted_content
|
|
26
|
+
|
|
27
|
+
@encrypted_content.setter
|
|
28
|
+
def encrypted_content(self, value):
|
|
29
|
+
self._encrypted_content = value
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def encrypted_content_length(self):
|
|
33
|
+
return self._encrypted_content_length
|
|
34
|
+
|
|
35
|
+
@encrypted_content_length.setter
|
|
36
|
+
def encrypted_content_length(self, value):
|
|
37
|
+
self._encrypted_content_length = value
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def auth_tag(self):
|
|
41
|
+
return self._auth_tag
|
|
42
|
+
|
|
43
|
+
@auth_tag.setter
|
|
44
|
+
def auth_tag(self, value):
|
|
45
|
+
self._auth_tag = value
|
|
46
|
+
|
|
47
|
+
def get_total_length(self):
|
|
48
|
+
return len(self._iv) + len(self._encrypted_content) + 8 + len(self._auth_tag)
|
|
49
|
+
|
|
50
|
+
def to_byte_array(self):
|
|
51
|
+
total = self.get_total_length()
|
|
52
|
+
buf = bytearray(total)
|
|
53
|
+
offset = 0
|
|
54
|
+
buf[offset:offset + len(self._iv)] = self._iv
|
|
55
|
+
offset += len(self._iv)
|
|
56
|
+
encrypted_content_length_bytes = struct.pack(">q", self._encrypted_content_length)
|
|
57
|
+
buf[offset:offset + 8] = encrypted_content_length_bytes
|
|
58
|
+
offset += 8
|
|
59
|
+
buf[offset:offset + len(self._encrypted_content)] = self._encrypted_content
|
|
60
|
+
offset += len(self._encrypted_content)
|
|
61
|
+
buf[offset:offset + len(self._auth_tag)] = self._auth_tag
|
|
62
|
+
return bytes(buf)
|
|
63
|
+
|
|
64
|
+
def deserialize(self, data_stream, algorithm):
|
|
65
|
+
self._iv = data_stream.read(algorithm.iv_len)
|
|
66
|
+
if len(self._iv) != algorithm.iv_len:
|
|
67
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
68
|
+
encrypted_content_length_bytes = data_stream.read(8)
|
|
69
|
+
if len(encrypted_content_length_bytes) != 8:
|
|
70
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
71
|
+
self._encrypted_content_length = struct.unpack(">q", encrypted_content_length_bytes)[0]
|
|
72
|
+
self._encrypted_content = data_stream.read(int(self._encrypted_content_length))
|
|
73
|
+
if len(self._encrypted_content) != int(self._encrypted_content_length):
|
|
74
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
75
|
+
if algorithm != CryptoAlgorithm.SM4_128_CBC_PADDING:
|
|
76
|
+
self._auth_tag = data_stream.read(algorithm.tag_len)
|
|
77
|
+
else:
|
|
78
|
+
self._auth_tag = b""
|
|
79
|
+
if len(self._auth_tag) != (algorithm.tag_len if algorithm != CryptoAlgorithm.SM4_128_CBC_PADDING else 0):
|
|
80
|
+
raise HuaweicloudException(ErrorMessage.SOURCE_FILE_INVALID.message)
|
|
81
|
+
return self
|