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.
Files changed (174) hide show
  1. examples/file_encryption_example.py +57 -0
  2. examples/key_capsule_encryption_example.py +240 -0
  3. examples/kms_discovery_encryption_example.py +56 -0
  4. examples/local_aes_encryption_example.py +59 -0
  5. examples/test_rsa.py +42 -0
  6. examples/test_sm2.py +38 -0
  7. examples/test_sm4_cbc.py +37 -0
  8. examples/test_sm4_gcm.py +37 -0
  9. huaweicloud_encryption_sdk_python-1.2.1.dist-info/METADATA +18 -0
  10. huaweicloud_encryption_sdk_python-1.2.1.dist-info/RECORD +174 -0
  11. huaweicloud_encryption_sdk_python-1.2.1.dist-info/WHEEL +5 -0
  12. huaweicloud_encryption_sdk_python-1.2.1.dist-info/top_level.txt +3 -0
  13. huaweicloud_encryptionsdk/__init__.py +5 -0
  14. huaweicloud_encryptionsdk/_apig_sdk/__init__.py +1 -0
  15. huaweicloud_encryptionsdk/_apig_sdk/signer.py +278 -0
  16. huaweicloud_encryptionsdk/_apig_sdk/signer_v11.py +70 -0
  17. huaweicloud_encryptionsdk/_apig_sdk/sm3_hash.py +141 -0
  18. huaweicloud_encryptionsdk/_lts_sdk/auth/__init__.py +0 -0
  19. huaweicloud_encryptionsdk/_lts_sdk/auth/signer.py +174 -0
  20. huaweicloud_encryptionsdk/_lts_sdk/consumer/__init__.py +0 -0
  21. huaweicloud_encryptionsdk/_lts_sdk/consumer/client/__init__.py +0 -0
  22. huaweicloud_encryptionsdk/_lts_sdk/consumer/client/consumer_client_adapter.py +59 -0
  23. huaweicloud_encryptionsdk/_lts_sdk/consumer/client/http_client.py +211 -0
  24. huaweicloud_encryptionsdk/_lts_sdk/consumer/core/__init__.py +0 -0
  25. huaweicloud_encryptionsdk/_lts_sdk/consumer/core/client_consumer_worker.py +106 -0
  26. huaweicloud_encryptionsdk/_lts_sdk/consumer/core/consumer_heartbeat.py +73 -0
  27. huaweicloud_encryptionsdk/_lts_sdk/consumer/core/log_shard_consumer.py +179 -0
  28. huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/__init__.py +0 -0
  29. huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_check_point_tracker.py +120 -0
  30. huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor.py +18 -0
  31. huaweicloud_encryptionsdk/_lts_sdk/consumer/interface/consumer_processor_factory.py +3 -0
  32. huaweicloud_encryptionsdk/_lts_sdk/consumer/model/__init__.py +0 -0
  33. huaweicloud_encryptionsdk/_lts_sdk/consumer/model/check_point.py +20 -0
  34. huaweicloud_encryptionsdk/_lts_sdk/consumer/model/consumer_config.py +27 -0
  35. huaweicloud_encryptionsdk/_lts_sdk/consumer/model/log_data.py +18 -0
  36. huaweicloud_encryptionsdk/_lts_sdk/consumer/model/task_result.py +40 -0
  37. huaweicloud_encryptionsdk/_lts_sdk/consumer/task/__init__.py +0 -0
  38. huaweicloud_encryptionsdk/_lts_sdk/consumer/task/consumer_fetch_task.py +53 -0
  39. huaweicloud_encryptionsdk/_lts_sdk/consumer/task/initial_task.py +55 -0
  40. huaweicloud_encryptionsdk/_lts_sdk/consumer/task/process_task.py +25 -0
  41. huaweicloud_encryptionsdk/_lts_sdk/consumer/task/shutdown_task.py +24 -0
  42. huaweicloud_encryptionsdk/_lts_sdk/consumer_main.py +88 -0
  43. huaweicloud_encryptionsdk/_lts_sdk/parallel_main.py +64 -0
  44. huaweicloud_encryptionsdk/_lts_sdk/producer/__init__.py +0 -0
  45. huaweicloud_encryptionsdk/_lts_sdk/producer/callback/__init__.py +0 -0
  46. huaweicloud_encryptionsdk/_lts_sdk/producer/callback/call_back.py +7 -0
  47. huaweicloud_encryptionsdk/_lts_sdk/producer/core/__init__.py +0 -0
  48. huaweicloud_encryptionsdk/_lts_sdk/producer/core/accumulator.py +135 -0
  49. huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_thread_pool.py +107 -0
  50. huaweicloud_encryptionsdk/_lts_sdk/producer/core/io_worker.py +124 -0
  51. huaweicloud_encryptionsdk/_lts_sdk/producer/core/mover.py +69 -0
  52. huaweicloud_encryptionsdk/_lts_sdk/producer/core/producer.py +98 -0
  53. huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/__init__.py +0 -0
  54. huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/http_client.py +63 -0
  55. huaweicloud_encryptionsdk/_lts_sdk/producer/lts_http/simple_request.py +14 -0
  56. huaweicloud_encryptionsdk/_lts_sdk/producer/model/__init__.py +0 -0
  57. huaweicloud_encryptionsdk/_lts_sdk/producer/model/config.py +50 -0
  58. huaweicloud_encryptionsdk/_lts_sdk/producer/model/error.py +18 -0
  59. huaweicloud_encryptionsdk/_lts_sdk/producer/model/log.py +87 -0
  60. huaweicloud_encryptionsdk/_lts_sdk/producer/model/log_batch.py +154 -0
  61. huaweicloud_encryptionsdk/_lts_sdk/producer/model/lts_store.py +21 -0
  62. huaweicloud_encryptionsdk/_lts_sdk/producer/model/result.py +17 -0
  63. huaweicloud_encryptionsdk/_lts_sdk/producer/model/retry_queue.py +39 -0
  64. huaweicloud_encryptionsdk/_lts_sdk/serial_main.py +77 -0
  65. huaweicloud_encryptionsdk/_lts_sdk/utils/__init__.py +0 -0
  66. huaweicloud_encryptionsdk/_lts_sdk/utils/common.py +57 -0
  67. huaweicloud_encryptionsdk/_lts_sdk/utils/lts_threading.py +32 -0
  68. huaweicloud_encryptionsdk/cache/__init__.py +0 -0
  69. huaweicloud_encryptionsdk/cache/data_key_cache.py +79 -0
  70. huaweicloud_encryptionsdk/cache/local_data_key_cache.py +161 -0
  71. huaweicloud_encryptionsdk/common/__init__.py +0 -0
  72. huaweicloud_encryptionsdk/common/constants.py +15 -0
  73. huaweicloud_encryptionsdk/common/counting_output_stream.py +18 -0
  74. huaweicloud_encryptionsdk/common/crypto_factory.py +48 -0
  75. huaweicloud_encryptionsdk/common/ec_private_key_loader.py +43 -0
  76. huaweicloud_encryptionsdk/common/ecs_metadata_service.py +42 -0
  77. huaweicloud_encryptionsdk/common/file_path_for_example_constants.py +4 -0
  78. huaweicloud_encryptionsdk/common/utils.py +162 -0
  79. huaweicloud_encryptionsdk/exception/__init__.py +0 -0
  80. huaweicloud_encryptionsdk/exception/errors.py +109 -0
  81. huaweicloud_encryptionsdk/handler/__init__.py +0 -0
  82. huaweicloud_encryptionsdk/handler/cipher_handler.py +294 -0
  83. huaweicloud_encryptionsdk/handler/crypto_handler.py +24 -0
  84. huaweicloud_encryptionsdk/handler/default_crypto_handler.py +148 -0
  85. huaweicloud_encryptionsdk/handler/default_serialize_handler.py +45 -0
  86. huaweicloud_encryptionsdk/handler/file_decrypt_handler.py +101 -0
  87. huaweicloud_encryptionsdk/handler/file_encrypt_handler.py +30 -0
  88. huaweicloud_encryptionsdk/handler/serialize_handler.py +14 -0
  89. huaweicloud_encryptionsdk/huawei_config.py +49 -0
  90. huaweicloud_encryptionsdk/huawei_crypto.py +311 -0
  91. huaweicloud_encryptionsdk/keyrings/__init__.py +0 -0
  92. huaweicloud_encryptionsdk/keyrings/keyring.py +14 -0
  93. huaweicloud_encryptionsdk/keyrings/keyring_factory.py +10 -0
  94. huaweicloud_encryptionsdk/keyrings/kms_keyring_factory.py +21 -0
  95. huaweicloud_encryptionsdk/keyrings/kmskeyring/__init__.py +0 -0
  96. huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_discovery_keyring.py +51 -0
  97. huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_key_capsule_keyring.py +100 -0
  98. huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_keyring.py +155 -0
  99. huaweicloud_encryptionsdk/keyrings/kmskeyring/kms_multi_region_keyring.py +8 -0
  100. huaweicloud_encryptionsdk/keyrings/raw_keyring_factory.py +27 -0
  101. huaweicloud_encryptionsdk/keyrings/rawkeyring/__init__.py +0 -0
  102. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_aes_keyring.py +63 -0
  103. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_keyring.py +112 -0
  104. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_rsa_keyring.py +55 -0
  105. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm2_keyring.py +75 -0
  106. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_cbc_keyring.py +66 -0
  107. huaweicloud_encryptionsdk/keyrings/rawkeyring/raw_sm4_keyring.py +70 -0
  108. huaweicloud_encryptionsdk/kms/__init__.py +0 -0
  109. huaweicloud_encryptionsdk/kms/create_key_capsule_request.py +35 -0
  110. huaweicloud_encryptionsdk/kms/create_key_capsule_response.py +19 -0
  111. huaweicloud_encryptionsdk/kms/decrypt_key_capsule_request.py +32 -0
  112. huaweicloud_encryptionsdk/kms/decrypt_key_capsule_response.py +19 -0
  113. huaweicloud_encryptionsdk/kms/kms_http_client.py +116 -0
  114. huaweicloud_encryptionsdk/log/__init__.py +0 -0
  115. huaweicloud_encryptionsdk/log/log_config.py +30 -0
  116. huaweicloud_encryptionsdk/log/log_file_backup.py +144 -0
  117. huaweicloud_encryptionsdk/log/log_metrics.py +132 -0
  118. huaweicloud_encryptionsdk/log/log_reporter_manager.py +163 -0
  119. huaweicloud_encryptionsdk/log/lts_sdk_producer.py +386 -0
  120. huaweicloud_encryptionsdk/log/lts_struct_log_builder.py +106 -0
  121. huaweicloud_encryptionsdk/meterialmanager/__init__.py +0 -0
  122. huaweicloud_encryptionsdk/meterialmanager/cache_crypto_meterial_manager.py +221 -0
  123. huaweicloud_encryptionsdk/meterialmanager/crypto_meterial_manager.py +19 -0
  124. huaweicloud_encryptionsdk/meterialmanager/data_key_generate.py +10 -0
  125. huaweicloud_encryptionsdk/meterialmanager/data_key_generate_factory.py +20 -0
  126. huaweicloud_encryptionsdk/meterialmanager/default_crypto_meterials_manager.py +71 -0
  127. huaweicloud_encryptionsdk/meterialmanager/key_capsule_data_key_generate.py +63 -0
  128. huaweicloud_encryptionsdk/meterialmanager/kms_data_key_generate.py +65 -0
  129. huaweicloud_encryptionsdk/meterialmanager/local_data_key_generate.py +13 -0
  130. huaweicloud_encryptionsdk/model/__init__.py +0 -0
  131. huaweicloud_encryptionsdk/model/access_point_config.py +9 -0
  132. huaweicloud_encryptionsdk/model/cipher_body.py +81 -0
  133. huaweicloud_encryptionsdk/model/cipher_header.py +405 -0
  134. huaweicloud_encryptionsdk/model/ciphertext_data_key.py +166 -0
  135. huaweicloud_encryptionsdk/model/crypto_result.py +11 -0
  136. huaweicloud_encryptionsdk/model/data_key_materials.py +17 -0
  137. huaweicloud_encryptionsdk/model/data_materials.py +11 -0
  138. huaweicloud_encryptionsdk/model/enums/__init__.py +0 -0
  139. huaweicloud_encryptionsdk/model/enums/access_point_type.py +28 -0
  140. huaweicloud_encryptionsdk/model/enums/crypto_algorithm.py +75 -0
  141. huaweicloud_encryptionsdk/model/enums/data_key_generate_type.py +20 -0
  142. huaweicloud_encryptionsdk/model/enums/key_provider_enum.py +19 -0
  143. huaweicloud_encryptionsdk/model/enums/keyring_type_enum.py +27 -0
  144. huaweicloud_encryptionsdk/model/key_capsule.py +10 -0
  145. huaweicloud_encryptionsdk/model/key_capsule_config.py +12 -0
  146. huaweicloud_encryptionsdk/model/kms_config.py +10 -0
  147. huaweicloud_encryptionsdk/model/request/__init__.py +0 -0
  148. huaweicloud_encryptionsdk/model/request/encrypt_request.py +10 -0
  149. huaweicloud_encryptionsdk/model/request/sign_request.py +2 -0
  150. huaweicloud_encryptionsdk/model/request/verify_request.py +2 -0
  151. huaweicloud_encryptionsdk/proof/__init__.py +0 -0
  152. huaweicloud_encryptionsdk/proof/attestation_document.py +36 -0
  153. huaweicloud_encryptionsdk/proof/collector/__init__.py +0 -0
  154. huaweicloud_encryptionsdk/proof/collector/cce_proof_collector.py +24 -0
  155. huaweicloud_encryptionsdk/proof/collector/ecs_proof_collector.py +11 -0
  156. huaweicloud_encryptionsdk/proof/collector/key_pair_proof_collector.py +55 -0
  157. huaweicloud_encryptionsdk/proof/collector/ma_proof_collector.py +51 -0
  158. huaweicloud_encryptionsdk/proof/private_key_decrypt_callback.py +7 -0
  159. huaweicloud_encryptionsdk/proof/proof_collector.py +11 -0
  160. huaweicloud_encryptionsdk/proof/proof_collector_factory.py +53 -0
  161. huaweicloud_encryptionsdk/proof/proof_info.py +10 -0
  162. huaweicloud_encryptionsdk/util/__init__.py +0 -0
  163. huaweicloud_encryptionsdk/util/common_utils.py +12 -0
  164. tests/__init__.py +0 -0
  165. tests/test_enums.py +84 -0
  166. tests/test_exceptions.py +38 -0
  167. tests/test_factories.py +71 -0
  168. tests/test_huawei_crypto.py +67 -0
  169. tests/test_imports.py +46 -0
  170. tests/test_kms_models.py +95 -0
  171. tests/test_log_file_backup.py +45 -0
  172. tests/test_lts_struct_log_builder.py +97 -0
  173. tests/test_models.py +142 -0
  174. tests/test_utils.py +111 -0
@@ -0,0 +1,8 @@
1
+ from huaweicloud_encryptionsdk.keyrings.kmskeyring.kms_keyring import KMSKeyring
2
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
3
+
4
+
5
+ class KMSMultiRegionKeyring(KMSKeyring):
6
+
7
+ def do_decrypt(self, data_key_materials: DataKeyMaterials):
8
+ self.real_decrypt(data_key_materials)
@@ -0,0 +1,27 @@
1
+ from huaweicloud_encryptionsdk.exception.errors import KeyringNotFoundException, ErrorMessage
2
+ from huaweicloud_encryptionsdk.keyrings.keyring_factory import KeyringFactory
3
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_aes_keyring import RawAesKeyring
4
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_rsa_keyring import RawRSAKeyring
5
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_sm2_keyring import RawSM2Keyring
6
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_sm4_keyring import RawSM4Keyring
7
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_sm4_cbc_keyring import RawSM4CBCKeyring
8
+ from huaweicloud_encryptionsdk.model.enums.keyring_type_enum import KeyringTypeEnum
9
+
10
+
11
+ class RawKeyringFactory(KeyringFactory):
12
+
13
+ def get_keyring(self, type: str):
14
+ keyring_type_enum = KeyringTypeEnum.get_raw_keyring_type(type)
15
+ if keyring_type_enum is None:
16
+ raise KeyringNotFoundException(ErrorMessage.KEYRING_NOT_FOUND_EXCEPTION.message)
17
+ if keyring_type_enum == KeyringTypeEnum.RAW_AES:
18
+ return RawAesKeyring()
19
+ elif keyring_type_enum == KeyringTypeEnum.RAW_RSA:
20
+ return RawRSAKeyring()
21
+ elif keyring_type_enum == KeyringTypeEnum.RAW_SM2:
22
+ return RawSM2Keyring()
23
+ elif keyring_type_enum == KeyringTypeEnum.RAW_SM4_GCM:
24
+ return RawSM4Keyring()
25
+ elif keyring_type_enum == KeyringTypeEnum.RAW_SM4_CBC:
26
+ return RawSM4CBCKeyring()
27
+ return None
@@ -0,0 +1,63 @@
1
+ import os
2
+ import logging
3
+
4
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
5
+
6
+ from huaweicloud_encryptionsdk.common.utils import serialize_context, byte_to_secret_key
7
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, ErrorMessage
8
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_keyring import RawKeyring
9
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
10
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
11
+ from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ AES_IV_LEN = 12
16
+ AES_TAG_LEN = 16
17
+
18
+
19
+ class RawAesKeyring(RawKeyring):
20
+
21
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
22
+ try:
23
+ iv = os.urandom(AES_IV_LEN)
24
+ cipher = Cipher(algorithms.AES(key_bytes), modes.GCM(iv))
25
+ encryptor = cipher.encryptor()
26
+ aad = serialize_context(data_key_materials.encryption_contexts)
27
+ if aad:
28
+ encryptor.authenticate_additional_data(aad)
29
+ original_data_key = data_key_materials.plaintext_data_key
30
+ encrypted = encryptor.update(original_data_key) + encryptor.finalize()
31
+ encrypted_with_tag = encrypted + encryptor.tag
32
+ message = iv + encrypted_with_tag
33
+ ciphertext_data_keys.append(CiphertextDataKey(data_key=message))
34
+ except Exception as e:
35
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
36
+
37
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
38
+ try:
39
+ data_key = ciphertext_data_key.data_key
40
+ algo = data_key_materials.crypto_algorithm
41
+ if algo is not None and len(data_key) < AES_IV_LEN + AES_TAG_LEN:
42
+ raise ValueError("data key too short")
43
+ iv = data_key[:AES_IV_LEN]
44
+ tag = data_key[-AES_TAG_LEN:]
45
+ ct = data_key[AES_IV_LEN:-AES_TAG_LEN]
46
+ cipher = Cipher(algorithms.AES(key_bytes), modes.GCM(iv, tag, min_tag_length=AES_TAG_LEN))
47
+ decryptor = cipher.decryptor()
48
+ aad = serialize_context(data_key_materials.encryption_contexts)
49
+ if aad:
50
+ decryptor.authenticate_additional_data(aad)
51
+ decrypted = decryptor.update(ct) + decryptor.finalize()
52
+ algo_name = data_key_materials.crypto_algorithm.get_algorithm_name() if data_key_materials.crypto_algorithm else "AES"
53
+ data_key_materials.plaintext_data_key = byte_to_secret_key(decrypted, algo_name)
54
+ return True
55
+ except Exception:
56
+ logger.warning("one master key may be not match when decrypt data key in RawAesKeyring")
57
+ return False
58
+
59
+ def get_decrypt_secret_key(self) -> list[bytes]:
60
+ return self.symmetric_key
61
+
62
+ def get_encrypt_secret_key(self) -> list[bytes]:
63
+ return self.symmetric_key
@@ -0,0 +1,112 @@
1
+ import logging
2
+ from abc import abstractmethod
3
+ from concurrent.futures import ThreadPoolExecutor, as_completed
4
+
5
+ from huaweicloud_encryptionsdk.common.utils import is_empty
6
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, HuaweicloudException, KeyringNotMatchException, ErrorMessage
7
+ from huaweicloud_encryptionsdk.keyrings.keyring import Keyring
8
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
9
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class RawKeyring(Keyring):
15
+
16
+ def __init__(self):
17
+ self._private_key: list[bytes] = []
18
+ self._public_key: list[bytes] = []
19
+ self._symmetric_key: list[bytes] = []
20
+
21
+ @property
22
+ def private_key(self):
23
+ return self._private_key
24
+
25
+ def set_private_key(self, keys):
26
+ if isinstance(keys, list):
27
+ self._private_key.extend(keys)
28
+ else:
29
+ self._private_key.extend(keys)
30
+
31
+ @property
32
+ def public_key(self):
33
+ return self._public_key
34
+
35
+ def set_public_key(self, keys):
36
+ if isinstance(keys, list):
37
+ self._public_key.extend(keys)
38
+ else:
39
+ self._public_key.extend(keys)
40
+
41
+ @property
42
+ def symmetric_key(self):
43
+ return self._symmetric_key
44
+
45
+ def set_symmetric_key(self, keys):
46
+ if isinstance(keys, list):
47
+ self._symmetric_key.extend(keys)
48
+ else:
49
+ self._symmetric_key.extend(keys)
50
+
51
+ @abstractmethod
52
+ def get_decrypt_secret_key(self) -> list[bytes]:
53
+ pass
54
+
55
+ @abstractmethod
56
+ def get_encrypt_secret_key(self) -> list[bytes]:
57
+ pass
58
+
59
+ @abstractmethod
60
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
61
+ pass
62
+
63
+ @abstractmethod
64
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
65
+ pass
66
+
67
+ def encrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
68
+ encrypt_secret_key = self.get_encrypt_secret_key()
69
+ if is_empty(encrypt_secret_key):
70
+ raise HuaweicloudException(ErrorMessage.MASTER_KEY_SHOULD_NOT_NULL.message)
71
+ try:
72
+ self._do_encrypt(data_key_materials, encrypt_secret_key)
73
+ except Exception as e:
74
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
75
+ return data_key_materials
76
+
77
+ def _do_encrypt(self, data_key_materials: DataKeyMaterials, master_secret_key: list[bytes]):
78
+ ciphertext_data_keys = data_key_materials.ciphertext_data_keys
79
+ with ThreadPoolExecutor() as executor:
80
+ futures = []
81
+ for key_bytes in master_secret_key:
82
+ future = executor.submit(self._encrypt_with_key, key_bytes, ciphertext_data_keys, data_key_materials)
83
+ futures.append(future)
84
+ for future in as_completed(futures):
85
+ try:
86
+ future.result()
87
+ except Exception as e:
88
+ logger.warning("encrypt data key error by local master key: %s", e)
89
+ if len(ciphertext_data_keys) <= 0:
90
+ raise EncryptException(ErrorMessage.ENCRYPT_DATA_KEY_EXCEPTION.message)
91
+ data_key_materials.ciphertext_data_keys = ciphertext_data_keys
92
+
93
+ def _encrypt_with_key(self, key_bytes, ciphertext_data_keys, data_key_materials):
94
+ self.real_encrypt(key_bytes, ciphertext_data_keys, data_key_materials)
95
+
96
+ def decrypt_data_key(self, data_key_materials: DataKeyMaterials) -> DataKeyMaterials:
97
+ decrypt_secret_key = self.get_decrypt_secret_key()
98
+ if is_empty(decrypt_secret_key):
99
+ raise HuaweicloudException(ErrorMessage.MASTER_KEY_SHOULD_NOT_NULL.message)
100
+ self._do_decrypt(data_key_materials, decrypt_secret_key)
101
+ if is_empty(data_key_materials.ciphertext_data_keys):
102
+ raise KeyringNotMatchException(ErrorMessage.KEYRING_NOT_MATCH_EXCEPTION.message)
103
+ return data_key_materials
104
+
105
+ def _do_decrypt(self, data_key_materials: DataKeyMaterials, master_secret_key: list[bytes]):
106
+ ciphertext_data_keys = data_key_materials.ciphertext_data_keys
107
+ for key_bytes in master_secret_key:
108
+ for ciphertext_data_key in ciphertext_data_keys:
109
+ is_decrypted = self.real_decrypt(key_bytes, ciphertext_data_key, data_key_materials)
110
+ if is_decrypted:
111
+ return
112
+ raise KeyringNotMatchException(ErrorMessage.KEYRING_NOT_MATCH_EXCEPTION.message)
@@ -0,0 +1,55 @@
1
+ import logging
2
+
3
+ from cryptography.hazmat.primitives.asymmetric import padding
4
+ from cryptography.hazmat.primitives import hashes, serialization
5
+
6
+ from huaweicloud_encryptionsdk.common.utils import byte_to_secret_key, get_public_key, get_private_key
7
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, ErrorMessage
8
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_keyring import RawKeyring
9
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
10
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class RawRSAKeyring(RawKeyring):
16
+
17
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
18
+ try:
19
+ public_key = serialization.load_der_public_key(key_bytes)
20
+ encode_datakey = data_key_materials.plaintext_data_key
21
+ encrypted = public_key.encrypt(
22
+ encode_datakey,
23
+ padding.OAEP(
24
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
25
+ algorithm=hashes.SHA256(),
26
+ label=None
27
+ )
28
+ )
29
+ ciphertext_data_keys.append(CiphertextDataKey(data_key=encrypted))
30
+ except Exception as e:
31
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
32
+
33
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
34
+ try:
35
+ private_key = serialization.load_der_private_key(key_bytes, password=None)
36
+ decrypted = private_key.decrypt(
37
+ ciphertext_data_key.data_key,
38
+ padding.OAEP(
39
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
40
+ algorithm=hashes.SHA256(),
41
+ label=None
42
+ )
43
+ )
44
+ algo_name = data_key_materials.crypto_algorithm.get_algorithm_name() if data_key_materials.crypto_algorithm else "AES"
45
+ data_key_materials.plaintext_data_key = byte_to_secret_key(decrypted, algo_name)
46
+ return True
47
+ except Exception:
48
+ logger.warning("one master key may be not match when decrypt data key in RawRSAKeyring")
49
+ return False
50
+
51
+ def get_encrypt_secret_key(self) -> list[bytes]:
52
+ return self.public_key
53
+
54
+ def get_decrypt_secret_key(self) -> list[bytes]:
55
+ return self.private_key
@@ -0,0 +1,75 @@
1
+ import logging
2
+
3
+ from huaweicloud_encryptionsdk.common.utils import byte_to_secret_key
4
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, ErrorMessage
5
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_keyring import RawKeyring
6
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
7
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def _extract_ec_point_from_der(der_bytes: bytes) -> tuple:
13
+ idx = der_bytes.find(b'\x03')
14
+ if idx < 0:
15
+ raise ValueError("Invalid EC public key DER: BIT STRING not found")
16
+ pos = idx + 1
17
+ if der_bytes[pos] == 0x81:
18
+ content_start = pos + 2
19
+ elif der_bytes[pos] == 0x82:
20
+ content_start = pos + 3
21
+ else:
22
+ content_start = pos + 1
23
+ content_start += 1
24
+ if der_bytes[content_start] != 0x04:
25
+ raise ValueError("Invalid EC public key DER: uncompressed point not found")
26
+ coord_len = (len(der_bytes) - content_start - 1) // 2
27
+ x = int.from_bytes(der_bytes[content_start + 1:content_start + 1 + coord_len], 'big')
28
+ y = int.from_bytes(der_bytes[content_start + 1 + coord_len:content_start + 1 + 2 * coord_len], 'big')
29
+ return x, y
30
+
31
+
32
+ def _extract_ec_private_from_der(der_bytes: bytes) -> int:
33
+ from cryptography.hazmat.primitives.serialization import load_der_private_key
34
+ pri_key = load_der_private_key(der_bytes, password=None)
35
+ return pri_key.private_numbers().private_value
36
+
37
+
38
+ class RawSM2Keyring(RawKeyring):
39
+
40
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
41
+ try:
42
+ from gmssl import sm2
43
+ try:
44
+ x, y = _extract_ec_point_from_der(key_bytes)
45
+ public_key_hex = "04" + format(x, '064x') + format(y, '064x')
46
+ except Exception:
47
+ public_key_hex = key_bytes.hex()
48
+ sm2_crypt = sm2.CryptSM2(public_key=public_key_hex, private_key="")
49
+ encrypted = sm2_crypt.encrypt(data_key_materials.plaintext_data_key)
50
+ ciphertext_data_keys.append(CiphertextDataKey(data_key=encrypted))
51
+ except Exception as e:
52
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
53
+
54
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
55
+ try:
56
+ from gmssl import sm2
57
+ try:
58
+ d = _extract_ec_private_from_der(key_bytes)
59
+ private_key_hex = format(d, '064x')
60
+ except Exception:
61
+ private_key_hex = key_bytes.hex()
62
+ sm2_crypt = sm2.CryptSM2(public_key="", private_key=private_key_hex)
63
+ decrypted = sm2_crypt.decrypt(ciphertext_data_key.data_key)
64
+ algo_name = data_key_materials.crypto_algorithm.get_algorithm_name() if data_key_materials.crypto_algorithm else "SM4"
65
+ data_key_materials.plaintext_data_key = byte_to_secret_key(decrypted, algo_name)
66
+ return True
67
+ except Exception:
68
+ logger.warning("one master key may be not match when decrypt data key in RawSM2Keyring")
69
+ return False
70
+
71
+ def get_encrypt_secret_key(self) -> list[bytes]:
72
+ return self.public_key
73
+
74
+ def get_decrypt_secret_key(self) -> list[bytes]:
75
+ return self.private_key
@@ -0,0 +1,66 @@
1
+ import os
2
+ import logging
3
+
4
+ from huaweicloud_encryptionsdk.common.utils import serialize_context, byte_to_secret_key
5
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, ErrorMessage
6
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_keyring import RawKeyring
7
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
8
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
9
+ from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ SM4_CBC_IV_LEN = 16
14
+
15
+
16
+ class RawSM4CBCKeyring(RawKeyring):
17
+
18
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
19
+ try:
20
+ iv = os.urandom(SM4_CBC_IV_LEN)
21
+ from gmssl.sm4 import CryptSM4, SM4_ENCRYPT
22
+ original_data_key = data_key_materials.plaintext_data_key
23
+ padded = self._pkcs7_pad(original_data_key, 16)
24
+ crypt_sm4 = CryptSM4()
25
+ crypt_sm4.set_key(key_bytes, SM4_ENCRYPT)
26
+ encrypted = crypt_sm4.crypt_cbc(iv, padded)
27
+ message = iv + encrypted
28
+ ciphertext_data_keys.append(CiphertextDataKey(data_key=message))
29
+ except Exception as e:
30
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
31
+
32
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
33
+ try:
34
+ data_key = ciphertext_data_key.data_key
35
+ algo = data_key_materials.crypto_algorithm
36
+ if algo is not None and len(data_key) < SM4_CBC_IV_LEN:
37
+ raise ValueError("data key too short")
38
+ iv = data_key[:SM4_CBC_IV_LEN]
39
+ ct = data_key[SM4_CBC_IV_LEN:]
40
+ from gmssl.sm4 import CryptSM4, SM4_DECRYPT
41
+ crypt_sm4 = CryptSM4()
42
+ crypt_sm4.set_key(key_bytes, SM4_DECRYPT)
43
+ decrypted = crypt_sm4.crypt_cbc(iv, ct)
44
+ decrypted = self._pkcs7_unpad(decrypted)
45
+ algo_name = data_key_materials.crypto_algorithm.get_algorithm_name() if data_key_materials.crypto_algorithm else "SM4"
46
+ data_key_materials.plaintext_data_key = byte_to_secret_key(decrypted, algo_name)
47
+ return True
48
+ except Exception:
49
+ logger.warning("one master key may be not match when decrypt data key in RawSM4CBCKeyring")
50
+ return False
51
+
52
+ def get_encrypt_secret_key(self) -> list[bytes]:
53
+ return self.symmetric_key
54
+
55
+ def get_decrypt_secret_key(self) -> list[bytes]:
56
+ return self.symmetric_key
57
+
58
+ @staticmethod
59
+ def _pkcs7_pad(data, block_size):
60
+ pad_len = block_size - (len(data) % block_size)
61
+ return data + bytes([pad_len] * pad_len)
62
+
63
+ @staticmethod
64
+ def _pkcs7_unpad(data):
65
+ pad_len = data[-1]
66
+ return data[:-pad_len]
@@ -0,0 +1,70 @@
1
+ import os
2
+ import logging
3
+
4
+ from huaweicloud_encryptionsdk.common.utils import serialize_context, byte_to_secret_key
5
+ from huaweicloud_encryptionsdk.exception.errors import EncryptException, ErrorMessage
6
+ from huaweicloud_encryptionsdk.keyrings.rawkeyring.raw_keyring import RawKeyring
7
+ from huaweicloud_encryptionsdk.model.ciphertext_data_key import CiphertextDataKey
8
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
9
+ from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ SM4_GCM_IV_LEN = 12
14
+ SM4_GCM_TAG_LEN = 16
15
+
16
+
17
+ class RawSM4Keyring(RawKeyring):
18
+
19
+ def real_encrypt(self, key_bytes: bytes, ciphertext_data_keys: list, data_key_materials: DataKeyMaterials):
20
+ try:
21
+ iv = os.urandom(SM4_GCM_IV_LEN)
22
+ from cryptography.hazmat.primitives.ciphers import Cipher as _Cipher, algorithms as _algs, modes as _modes
23
+
24
+ sm4_alg = _algs.SM4(key_bytes)
25
+ gcm = _modes.GCM(iv)
26
+ cipher = _Cipher(sm4_alg, gcm)
27
+ encryptor = cipher.encryptor()
28
+ aad = serialize_context(data_key_materials.encryption_contexts)
29
+ if aad:
30
+ encryptor.authenticate_additional_data(aad)
31
+ original_data_key = data_key_materials.plaintext_data_key
32
+ encrypted = encryptor.update(original_data_key) + encryptor.finalize()
33
+ encrypted_with_tag = encrypted + encryptor.tag
34
+ message = iv + encrypted_with_tag
35
+ ciphertext_data_keys.append(CiphertextDataKey(data_key=message))
36
+ except Exception as e:
37
+ raise EncryptException(ErrorMessage.ENCRYPT_EXCEPTION.message, e)
38
+
39
+ def real_decrypt(self, key_bytes: bytes, ciphertext_data_key: CiphertextDataKey, data_key_materials: DataKeyMaterials) -> bool:
40
+ try:
41
+ data_key = ciphertext_data_key.data_key
42
+ algo = data_key_materials.crypto_algorithm
43
+ if algo is not None and len(data_key) < SM4_GCM_IV_LEN + SM4_GCM_TAG_LEN:
44
+ raise ValueError("data key too short")
45
+ iv = data_key[:SM4_GCM_IV_LEN]
46
+ tag = data_key[-SM4_GCM_TAG_LEN:]
47
+ ct = data_key[SM4_GCM_IV_LEN:-SM4_GCM_TAG_LEN]
48
+
49
+ from cryptography.hazmat.primitives.ciphers import Cipher as _Cipher, algorithms as _algs, modes as _modes
50
+
51
+ sm4_alg = _algs.SM4(key_bytes)
52
+ gcm = _modes.GCM(iv, tag, min_tag_length=SM4_GCM_TAG_LEN)
53
+ cipher = _Cipher(sm4_alg, gcm)
54
+ decryptor = cipher.decryptor()
55
+ aad = serialize_context(data_key_materials.encryption_contexts)
56
+ if aad:
57
+ decryptor.authenticate_additional_data(aad)
58
+ decrypted = decryptor.update(ct) + decryptor.finalize()
59
+ algo_name = data_key_materials.crypto_algorithm.get_algorithm_name() if data_key_materials.crypto_algorithm else "SM4"
60
+ data_key_materials.plaintext_data_key = byte_to_secret_key(decrypted, algo_name)
61
+ return True
62
+ except Exception:
63
+ logger.warning("one master key may be not match when decrypt data key in RawSM4Keyring")
64
+ return False
65
+
66
+ def get_encrypt_secret_key(self) -> list[bytes]:
67
+ return self.symmetric_key
68
+
69
+ def get_decrypt_secret_key(self) -> list[bytes]:
70
+ return self.symmetric_key
File without changes
@@ -0,0 +1,35 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class CreateKeyCapsuleRequest:
7
+ key_id: Optional[str] = None
8
+ datakey_length: int = 0
9
+ public_key: Optional[str] = None
10
+ policy_id: Optional[str] = None
11
+ key_policy: Optional[str] = None
12
+
13
+ def to_dict(self):
14
+ result = {}
15
+ if self.key_id is not None:
16
+ result["key_id"] = self.key_id
17
+ if self.datakey_length is not None:
18
+ result["datakey_length"] = self.datakey_length
19
+ if self.public_key is not None:
20
+ result["public_key"] = self.public_key
21
+ if self.policy_id is not None:
22
+ result["policy_id"] = self.policy_id
23
+ if self.key_policy is not None:
24
+ result["key_policy"] = self.key_policy
25
+ return result
26
+
27
+ @classmethod
28
+ def from_dict(cls, data):
29
+ return cls(
30
+ key_id=data.get("key_id"),
31
+ datakey_length=data.get("datakey_length", 0),
32
+ public_key=data.get("public_key"),
33
+ policy_id=data.get("policy_id"),
34
+ key_policy=data.get("key_policy"),
35
+ )
@@ -0,0 +1,19 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class CreateKeyCapsuleResponse:
7
+ key_id: Optional[str] = None
8
+ datakey_cipher: Optional[str] = None
9
+ datakey: Optional[str] = None
10
+ datakey_capsule: Optional[str] = None
11
+
12
+ @classmethod
13
+ def from_dict(cls, data):
14
+ return cls(
15
+ key_id=data.get("key_id"),
16
+ datakey_cipher=data.get("datakey_cipher"),
17
+ datakey=data.get("datakey"),
18
+ datakey_capsule=data.get("datakey_capsule"),
19
+ )
@@ -0,0 +1,32 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class DecryptKeyCapsuleRequest:
7
+ key_id: Optional[str] = None
8
+ datakey_capsule: Optional[str] = None
9
+ attestation_document: Optional[object] = None
10
+
11
+ def to_dict(self):
12
+ result = {}
13
+ if self.key_id is not None:
14
+ result["key_id"] = self.key_id
15
+ if self.datakey_capsule is not None:
16
+ result["datakey_capsule"] = self.datakey_capsule
17
+ if self.attestation_document is not None:
18
+ if hasattr(self.attestation_document, 'to_dict'):
19
+ result["attestation_document"] = self.attestation_document.to_dict()
20
+ elif hasattr(self.attestation_document, '__dict__'):
21
+ result["attestation_document"] = self.attestation_document.__dict__
22
+ else:
23
+ result["attestation_document"] = self.attestation_document
24
+ return result
25
+
26
+ @classmethod
27
+ def from_dict(cls, data):
28
+ return cls(
29
+ key_id=data.get("key_id"),
30
+ datakey_capsule=data.get("datakey_capsule"),
31
+ attestation_document=data.get("attestation_document"),
32
+ )
@@ -0,0 +1,19 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class DecryptKeyCapsuleResponse:
7
+ key_id: Optional[str] = None
8
+ datakey: Optional[str] = None
9
+ datakey_cipher: Optional[str] = None
10
+ instance_id: Optional[str] = None
11
+
12
+ @classmethod
13
+ def from_dict(cls, data):
14
+ return cls(
15
+ key_id=data.get("key_id"),
16
+ datakey=data.get("datakey"),
17
+ datakey_cipher=data.get("datakey_cipher"),
18
+ instance_id=data.get("instance_id"),
19
+ )