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,162 @@
1
+ import os
2
+ import struct
3
+ import hashlib
4
+ import base64
5
+ from io import BytesIO
6
+
7
+ from huaweicloud_encryptionsdk.common.crypto_factory import CryptoFactory
8
+
9
+
10
+ def is_empty(t):
11
+ if t is None:
12
+ return True
13
+ if isinstance(t, (str, list, dict, tuple, set)):
14
+ return len(t) == 0
15
+ return False
16
+
17
+
18
+ def read_master_key(key_paths):
19
+ public_key_list = []
20
+ for path in key_paths:
21
+ try:
22
+ with open(path, "rb") as f:
23
+ data = f.read()
24
+ cleaned = remove_line_symbol(data)
25
+ original_key = base64.b64decode(cleaned)
26
+ public_key_list.append(original_key)
27
+ except FileNotFoundError:
28
+ raise Exception("file not exists:" + os.path.basename(path))
29
+ return public_key_list
30
+
31
+
32
+ def long_to_bytes(num):
33
+ return struct.pack(">q", num)
34
+
35
+
36
+ def bytes_to_long(b):
37
+ return struct.unpack(">q", b)[0]
38
+
39
+
40
+ def bytes_to_int(b):
41
+ return struct.unpack(">i", b)[0]
42
+
43
+
44
+ def add_prevent_overflow(a, b):
45
+ r = a + b
46
+ if a > 0 and b > 0 and r < a:
47
+ return (1 << 63) - 1
48
+ if a < 0 and b < 0 and r > a:
49
+ return -(1 << 63)
50
+ return r
51
+
52
+
53
+ def common_hash(data, alg):
54
+ try:
55
+ md = CryptoFactory.get_message_digest(alg)
56
+ md.update(data)
57
+ return md.digest()
58
+ except Exception:
59
+ raise Exception("message digest error")
60
+
61
+
62
+ def byte_to_string(b):
63
+ if b is None:
64
+ return ""
65
+ return b.decode("utf-8", errors="replace")
66
+
67
+
68
+ def remove_line_symbol(b):
69
+ s = b.decode("utf-8", errors="replace").replace("\r\n", "").replace("\n", "").replace("\\n", "")
70
+ return s.encode("utf-8")
71
+
72
+
73
+ def byte_to_secret_key(b, algorithm):
74
+ return b
75
+
76
+
77
+ def get_public_key(public_key_bytes, alg_flag):
78
+ from cryptography.hazmat.primitives.serialization import load_der_public_key
79
+ try:
80
+ return load_der_public_key(public_key_bytes)
81
+ except Exception as e:
82
+ raise Exception("public key parse exception", e)
83
+
84
+
85
+ def get_private_key(private_key_bytes, alg_flag):
86
+ from cryptography.hazmat.primitives.serialization import load_der_private_key
87
+ try:
88
+ return load_der_private_key(private_key_bytes, password=None)
89
+ except Exception as e:
90
+ raise Exception("private key parse exception", e)
91
+
92
+
93
+ def serialize_context(encryption_context):
94
+ if encryption_context is None or len(encryption_context) == 0:
95
+ return b""
96
+ sorted_items = sorted(encryption_context.items(), key=lambda x: x[1])
97
+ buf = BytesIO()
98
+ buf.write(struct.pack(">h", len(encryption_context)))
99
+ for key, value in sorted_items:
100
+ key_bytes = key.encode("utf-8")
101
+ buf.write(struct.pack(">h", len(key_bytes)))
102
+ buf.write(key_bytes)
103
+ value_bytes = value.encode("utf-8")
104
+ buf.write(struct.pack(">h", len(value_bytes)))
105
+ buf.write(value_bytes)
106
+ return buf.getvalue()
107
+
108
+
109
+ def deserialize_context(data):
110
+ if data is None or len(data) == 0:
111
+ return {}
112
+ buf = BytesIO(data)
113
+ remaining = buf.read(2)
114
+ if len(remaining) < 2:
115
+ raise ValueError("insufficient data for context size")
116
+ context_size = struct.unpack(">h", remaining)[0]
117
+ result = {}
118
+ for _ in range(context_size):
119
+ key_len_data = buf.read(2)
120
+ if len(key_len_data) < 2:
121
+ raise ValueError("insufficient data for key length")
122
+ key_len = struct.unpack(">h", key_len_data)[0]
123
+ key_bytes = buf.read(key_len)
124
+ if len(key_bytes) < key_len:
125
+ raise ValueError("insufficient data for key")
126
+ value_len_data = buf.read(2)
127
+ if len(value_len_data) < 2:
128
+ raise ValueError("insufficient data for value length")
129
+ value_len = struct.unpack(">h", value_len_data)[0]
130
+ value_bytes = buf.read(value_len)
131
+ if len(value_bytes) < value_len:
132
+ raise ValueError("insufficient data for value")
133
+ result[key_bytes.decode("utf-8")] = value_bytes.decode("utf-8")
134
+ return result
135
+
136
+
137
+ def hex_to_bytes(hex_string):
138
+ _HEX_CHARS = set("0123456789abcdefABCDEF")
139
+ if hex_string is None or len(hex_string) == 0 or len(hex_string) % 2 != 0:
140
+ raise ValueError("invalid string length.")
141
+ for c in hex_string:
142
+ if c not in _HEX_CHARS:
143
+ raise ValueError("invalid string char. " + c)
144
+ return bytes.fromhex(hex_string)
145
+
146
+
147
+ def bytes_to_hex(b):
148
+ return b.hex()
149
+
150
+
151
+ def get_capsule_kms_config(kms_config_list, key_capsule_config):
152
+ if is_empty(kms_config_list):
153
+ raise Exception("config null error")
154
+ if key_capsule_config is None:
155
+ raise Exception("KeyCapsuleConfig is required for key capsule mode")
156
+ kms_config = None
157
+ for temp_config in kms_config_list:
158
+ if temp_config.region.lower() == key_capsule_config.region.lower():
159
+ kms_config = temp_config
160
+ if kms_config is None:
161
+ raise Exception("key capsule region not found " + key_capsule_config.region)
162
+ return kms_config
File without changes
@@ -0,0 +1,109 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ErrorMessage(Enum):
5
+
6
+ DECRYPT_EXCEPTION = (1000, "process wrong when decrypt data")
7
+ CIPHER_EXCEPTION = (1001, "process wrong when cipher data")
8
+ TAMPERED_EXCEPTION = (1002, "Header integrity check failed.")
9
+ ENCRYPT_EXCEPTION = (1003, "encrypt error")
10
+ AK_NULL_EXCEPTION = (1004, "ak of kms server should be not null")
11
+ SK_NULL_EXCEPTION = (1005, "sk of kms server should be not null")
12
+ DATA_KEY_GENERATE_EXCEPTION = (1006, "The data key generation type is not the specified type")
13
+ KMS_CREATE_KEY_EXCEPTION = (1007, "create data key from kms error")
14
+ SERIALIZE_EXCEPTION = (1008, "Failed to serialize cipher text headers")
15
+ DESERIALIZE_EXCEPTION = (1009, "Failed to deserialize cipher text headers,the cipher header may be changed")
16
+ PUBLIC_KEY_PARSE_EXCEPTION = (1010, "publicKey can not be parsed")
17
+ PRIVATE_KEY_PARSE_EXCEPTION = (1011, "privateKey can not be parsed")
18
+ KEYRING_NULL_EXCEPTION = (1012, "key ring should not be null")
19
+ KEYRING_NOT_FOUND_EXCEPTION = (1013, "not found such type of Keyring")
20
+ KEYRING_NOT_MATCH_EXCEPTION = (1014, "there is no master key match when decrypt data key")
21
+ DATA_EXCEED_LIMIT = (1015, "plaintext data exceed cache limit")
22
+ MESSAGE_DIGEST_ERROR = (1016, "MessageDigest error")
23
+ PROCESS_FILE_ERROR = (1017, "process file error when encrypt or decrypt the file")
24
+ FILE_CHANGED_ERROR = (1018, "the content of the file may be changed")
25
+ CONFIG_NULL_ERROR = (1019, "the kms config information should not be null")
26
+ CIPHER_TEXT_CHANGED_ERROR = (1020, "the cipher text may be changed")
27
+ NOT_FOUND_CIPHER_TEXT_DATA_KEY = (1021, "cipher header may be changed,the count of data key should not less than 0")
28
+ NOT_SUPPORT_DISCOVERY_DECRYPT = (1022, "the cipher text not support discovery Keyring")
29
+ ENCRYPT_DATA_KEY_EXCEPTION = (1023, "encrypt data key error,please confirm your information is right")
30
+ CACHE_PARAM_LESS_THAN_ZERO = (1024, "the param of cache should not less than 0!")
31
+ MASTER_KEY_SHOULD_NOT_NULL = (1025, "Master Key should not null")
32
+ SOURCE_FILE_INVALID = (1026, "The length of the source file is insufficient.")
33
+ KMS_CREATE_KEY_CAPSULE_EXCEPTION = (1027, "create key capsule from KMS error")
34
+ PARSE_KEY_CAPSULE_EXCEPTION = (1028, "parse key capsule exception")
35
+ DECRYPT_KEY_CAPSULE_EXCEPTION = (1029, "decrypt key capsule exception")
36
+ KEY_CAPSULE_NULL = (1030, "key capsule is null")
37
+ UNSUPPORTED_ACCESS_POINT_TYPE = (1031, "unsupported access point type")
38
+ CIPHER_TEXT_DATA_KEY_NOT_NULL = (1032, "the cipher text data key should not be null")
39
+ END_POINT_NOT_NULL = (1033, "the region is not support or endpoint should not be null")
40
+ KEY_CAPSULE_REGION_NOT_FOUND = (1034, "the region of key capsule is not found, region is ")
41
+ ACCESS_POINT_KEY_EXCEPTION = (1035, "The access point key material is incorrectly parsed.")
42
+ COLLECT_PROOF_EXCEPTION = (1036, "Failed to collect the proof document.")
43
+ GET_PUB_KEY_EXCEPTION = (1037, "Get ecc public key from private key error.")
44
+
45
+ def __init__(self, code, message):
46
+ self._code = code
47
+ self._message = message
48
+
49
+ @property
50
+ def code(self):
51
+ return self._code
52
+
53
+ @property
54
+ def message(self):
55
+ return self._message
56
+
57
+ @message.setter
58
+ def message(self, value):
59
+ self._message = value
60
+
61
+
62
+ class HuaweicloudException(RuntimeError):
63
+
64
+ def __init__(self, *args):
65
+ if len(args) == 0:
66
+ super().__init__()
67
+ elif len(args) == 1:
68
+ if isinstance(args[0], BaseException):
69
+ super().__init__(args[0])
70
+ else:
71
+ super().__init__(args[0])
72
+ else:
73
+ super().__init__(args[0], args[1])
74
+
75
+
76
+ class KeyringNotFoundException(HuaweicloudException):
77
+
78
+ def __init__(self, *args):
79
+ super().__init__(*args)
80
+
81
+
82
+ class KeyringNotMatchException(HuaweicloudException):
83
+
84
+ def __init__(self, *args):
85
+ super().__init__(*args)
86
+
87
+
88
+ class KeyParseException(HuaweicloudException):
89
+
90
+ def __init__(self, message, cause):
91
+ super().__init__(message, cause)
92
+
93
+
94
+ class EncryptException(HuaweicloudException):
95
+
96
+ def __init__(self, *args):
97
+ super().__init__(*args)
98
+
99
+
100
+ class CipherTamperedException(HuaweicloudException):
101
+
102
+ def __init__(self, *args):
103
+ super().__init__(*args)
104
+
105
+
106
+ class CipherDataException(HuaweicloudException):
107
+
108
+ def __init__(self, *args):
109
+ super().__init__(*args)
File without changes
@@ -0,0 +1,294 @@
1
+ import os
2
+ import struct
3
+ from io import BytesIO
4
+
5
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
6
+ from cryptography.hazmat.backends import default_backend
7
+
8
+ from huaweicloud_encryptionsdk.common.utils import serialize_context
9
+ from huaweicloud_encryptionsdk.model.cipher_header import CipherHeader
10
+ from huaweicloud_encryptionsdk.model.enums.crypto_algorithm import CryptoAlgorithm
11
+
12
+
13
+ ENCRYPT_MODE = 1
14
+ DECRYPT_MODE = 2
15
+
16
+
17
+ class CipherHandler:
18
+
19
+ def __init__(self, algorithm, secret_key, mode):
20
+ self._mode = mode
21
+ self._secret_key = secret_key
22
+ self._algorithm = algorithm
23
+ self._iv = self._generate_iv(algorithm)
24
+
25
+ @staticmethod
26
+ def _generate_iv(algorithm):
27
+ return os.urandom(algorithm.iv_len)
28
+
29
+ def get_iv(self):
30
+ return self._iv
31
+
32
+ def set_iv(self, iv):
33
+ self._iv = iv
34
+
35
+ def reset_iv(self):
36
+ self._iv = self._generate_iv(self._algorithm)
37
+
38
+ def _get_parameter_spec(self, plain_text=None):
39
+ crypto_mode = self._algorithm.get_crypto_mode()
40
+ if crypto_mode.upper() == "CBC":
41
+ return modes.CBC(self._iv)
42
+ if self._mode == DECRYPT_MODE and crypto_mode.upper() == "GCM":
43
+ tag = plain_text[-self._algorithm.tag_len:]
44
+ return modes.GCM(self._iv, tag, min_tag_length=self._algorithm.tag_len)
45
+ return modes.GCM(self._iv)
46
+
47
+ def _create_cipher(self, mode_spec):
48
+ alg_name = self._algorithm.crypto_alg.split("/")[0]
49
+ if alg_name.upper() == "SM4":
50
+ from cryptography.hazmat.primitives.ciphers import algorithms as _algs
51
+ return Cipher(_algs.SM4(self._secret_key), mode_spec, backend=default_backend())
52
+ if alg_name.upper() == "AES":
53
+ return Cipher(
54
+ algorithms.AES(self._secret_key), mode_spec, backend=default_backend()
55
+ )
56
+ raise Exception("unsupported algorithm: " + alg_name)
57
+
58
+ def _do_sm4_cbc(self, data, mode_int):
59
+ from gmssl.sm4 import CryptSM4, SM4_DECRYPT, SM4_ENCRYPT
60
+ crypt_sm4 = CryptSM4()
61
+ if mode_int == ENCRYPT_MODE:
62
+ crypt_sm4.set_key(self._secret_key, SM4_ENCRYPT)
63
+ else:
64
+ crypt_sm4.set_key(self._secret_key, SM4_DECRYPT)
65
+ return crypt_sm4.crypt_cbc(self._iv, data)
66
+
67
+ def _do_sm4_gcm(self, data, aad, mode_int):
68
+ from cryptography.hazmat.primitives.ciphers import Cipher as _Cipher
69
+ from cryptography.hazmat.primitives.ciphers import algorithms as _algs, modes as _modes
70
+
71
+ sm4_alg = _algs.SM4(self._secret_key)
72
+
73
+ if mode_int == ENCRYPT_MODE:
74
+ gcm = _modes.GCM(self._iv)
75
+ cipher = _Cipher(sm4_alg, gcm, backend=default_backend())
76
+ encryptor = cipher.encryptor()
77
+ if aad:
78
+ encryptor.authenticate_additional_data(aad)
79
+ ct = encryptor.update(data) + encryptor.finalize()
80
+ return ct + encryptor.tag
81
+ else:
82
+ if len(data) < self._algorithm.tag_len:
83
+ raise ValueError("data too short for GCM tag")
84
+ tag = data[-self._algorithm.tag_len:]
85
+ ct = data[:-self._algorithm.tag_len]
86
+ gcm = _modes.GCM(self._iv, tag, min_tag_length=self._algorithm.tag_len)
87
+ cipher = _Cipher(sm4_alg, gcm, backend=default_backend())
88
+ decryptor = cipher.decryptor()
89
+ if aad:
90
+ decryptor.authenticate_additional_data(aad)
91
+ return decryptor.update(ct) + decryptor.finalize()
92
+
93
+ def cipher_data(self, plain_text, encryption_context, offset, length):
94
+ try:
95
+ aad = serialize_context(encryption_context)
96
+ crypto_mode = self._algorithm.get_crypto_mode()
97
+ alg_name = self._algorithm.crypto_alg.split("/")[0]
98
+ data = plain_text[offset: offset + length]
99
+
100
+ if self._algorithm == CryptoAlgorithm.SM4_128_CBC_PADDING:
101
+ from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
102
+ padded = self._pkcs7_pad(data, 16)
103
+ crypt_sm4 = CryptSM4()
104
+ if self._mode == ENCRYPT_MODE:
105
+ crypt_sm4.set_key(self._secret_key, SM4_ENCRYPT)
106
+ return crypt_sm4.crypt_cbc(self._iv, padded)
107
+ else:
108
+ crypt_sm4.set_key(self._secret_key, SM4_DECRYPT)
109
+ decrypted = crypt_sm4.crypt_cbc(self._iv, data)
110
+ return self._pkcs7_unpad(decrypted)
111
+
112
+ if self._algorithm == CryptoAlgorithm.SM4_128_GCM_NOPADDING:
113
+ return self._do_sm4_gcm(data, aad, self._mode)
114
+
115
+ mode_spec = self._get_parameter_spec(plain_text if self._mode == DECRYPT_MODE else None)
116
+ cipher_obj = self._create_cipher(mode_spec)
117
+
118
+ if self._mode == ENCRYPT_MODE:
119
+ encryptor = cipher_obj.encryptor()
120
+ if crypto_mode.upper() == "GCM":
121
+ if aad:
122
+ encryptor.authenticate_additional_data(aad)
123
+ ct = encryptor.update(data) + encryptor.finalize()
124
+ if crypto_mode.upper() == "GCM":
125
+ ct = ct + encryptor.tag
126
+ return ct
127
+ else:
128
+ if crypto_mode.upper() == "GCM":
129
+ gcm_data = data[:-self._algorithm.tag_len]
130
+ else:
131
+ gcm_data = data
132
+ decryptor = cipher_obj.decryptor()
133
+ if crypto_mode.upper() == "GCM":
134
+ if aad:
135
+ decryptor.authenticate_additional_data(aad)
136
+ return decryptor.update(gcm_data) + decryptor.finalize()
137
+ except Exception as e:
138
+ raise Exception("cipher exception: " + str(e)) from e
139
+
140
+ def cipher_header_data(self, content, encryption_context, offset, length):
141
+ try:
142
+ crypto_mode = self._algorithm.get_crypto_mode()
143
+ alg_name = self._algorithm.crypto_alg.split("/")[0]
144
+
145
+ if self._algorithm == CryptoAlgorithm.SM4_128_CBC_PADDING:
146
+ from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
147
+ crypt_sm4 = CryptSM4()
148
+ if self._mode == ENCRYPT_MODE:
149
+ crypt_sm4.set_key(self._secret_key, SM4_ENCRYPT)
150
+ if length == 0:
151
+ digest_data = b"\x00"
152
+ padded = self._pkcs7_pad(digest_data, 16)
153
+ return crypt_sm4.crypt_cbc(self._iv, padded)
154
+ padded = self._pkcs7_pad(content[offset:offset + length], 16)
155
+ return crypt_sm4.crypt_cbc(self._iv, padded)
156
+ else:
157
+ crypt_sm4.set_key(self._secret_key, SM4_DECRYPT)
158
+ decrypted = crypt_sm4.crypt_cbc(self._iv, content[offset:offset + length])
159
+ return self._pkcs7_unpad(decrypted)
160
+
161
+ if self._algorithm == CryptoAlgorithm.SM4_128_GCM_NOPADDING:
162
+ return self._do_sm4_gcm(
163
+ content[offset: offset + length] if length > 0 else b"",
164
+ encryption_context,
165
+ self._mode,
166
+ )
167
+
168
+ if crypto_mode.upper() == "CBC":
169
+ mode_spec = modes.CBC(self._iv)
170
+ elif crypto_mode.upper() == "GCM":
171
+ if self._mode == DECRYPT_MODE:
172
+ data = content[offset: offset + length]
173
+ tag = data[-self._algorithm.tag_len:]
174
+ ct = data[:-self._algorithm.tag_len]
175
+ mode_spec = modes.GCM(self._iv, tag, min_tag_length=self._algorithm.tag_len)
176
+ else:
177
+ mode_spec = modes.GCM(self._iv)
178
+ ct = None
179
+ else:
180
+ raise Exception("unsupported mode: " + crypto_mode)
181
+
182
+ cipher_obj = self._create_cipher(mode_spec)
183
+
184
+ if self._mode == ENCRYPT_MODE:
185
+ encryptor = cipher_obj.encryptor()
186
+ if crypto_mode.upper() == "GCM":
187
+ if encryption_context:
188
+ encryptor.authenticate_additional_data(encryption_context)
189
+ ct = encryptor.update(content[offset: offset + length]) + encryptor.finalize()
190
+ if crypto_mode.upper() == "GCM":
191
+ ct = ct + encryptor.tag
192
+ return ct
193
+ else:
194
+ decryptor = cipher_obj.decryptor()
195
+ if crypto_mode.upper() == "GCM":
196
+ if encryption_context:
197
+ decryptor.authenticate_additional_data(encryption_context)
198
+ return decryptor.update(ct) + decryptor.finalize()
199
+ return decryptor.update(content[offset: offset + length]) + decryptor.finalize()
200
+ except Exception as e:
201
+ raise Exception("cipher exception: " + str(e)) from e
202
+
203
+ def process_encrypt_byte(self, read_bytes, read_len, output_stream, aad):
204
+ try:
205
+ self._init_cipher()
206
+ crypto_mode = self._algorithm.get_crypto_mode()
207
+ data = read_bytes[:read_len]
208
+
209
+ if self._algorithm == CryptoAlgorithm.SM4_128_CBC_PADDING:
210
+ from gmssl.sm4 import CryptSM4, SM4_ENCRYPT
211
+ padded = self._pkcs7_pad(data, 16)
212
+ crypt_sm4 = CryptSM4()
213
+ crypt_sm4.set_key(self._secret_key, SM4_ENCRYPT)
214
+ encrypted = crypt_sm4.crypt_cbc(self._iv, padded)
215
+ elif self._algorithm == CryptoAlgorithm.SM4_128_GCM_NOPADDING:
216
+ encrypted = self._do_sm4_gcm(data, aad, ENCRYPT_MODE)
217
+ else:
218
+ if crypto_mode.upper() == "GCM":
219
+ mode_spec = modes.GCM(self._iv)
220
+ else:
221
+ mode_spec = modes.CBC(self._iv)
222
+ cipher_obj = self._create_cipher(mode_spec)
223
+ encryptor = cipher_obj.encryptor()
224
+ if crypto_mode.upper() == "GCM" and aad:
225
+ encryptor.authenticate_additional_data(aad)
226
+ ct = encryptor.update(data) + encryptor.finalize()
227
+ if crypto_mode.upper() == "GCM":
228
+ encrypted = ct + encryptor.tag
229
+ else:
230
+ encrypted = ct
231
+
232
+ cipher_header = CipherHeader()
233
+ cipher_header.iv = self._iv
234
+ cipher_header.content_length = len(encrypted)
235
+ header_byte = cipher_header.serialize_file_fields()
236
+ output_stream.write(header_byte)
237
+ output_stream.write(encrypted)
238
+ return encrypted
239
+ except Exception as e:
240
+ raise Exception("process file error: " + str(e)) from e
241
+
242
+ def process_decrypt_byte(self, read_bytes, read_len, output_stream, aad):
243
+ try:
244
+ self._init_cipher()
245
+ crypto_mode = self._algorithm.get_crypto_mode()
246
+ data = read_bytes[:read_len]
247
+
248
+ if self._algorithm == CryptoAlgorithm.SM4_128_CBC_PADDING:
249
+ from gmssl.sm4 import CryptSM4, SM4_DECRYPT
250
+ crypt_sm4 = CryptSM4()
251
+ crypt_sm4.set_key(self._secret_key, SM4_DECRYPT)
252
+ result = crypt_sm4.crypt_cbc(self._iv, data)
253
+ decrypted = self._pkcs7_unpad(result)
254
+ elif self._algorithm == CryptoAlgorithm.SM4_128_GCM_NOPADDING:
255
+ decrypted = self._do_sm4_gcm(data, aad, DECRYPT_MODE)
256
+ else:
257
+ if crypto_mode.upper() == "GCM":
258
+ tag = data[-self._algorithm.tag_len:]
259
+ gcm_data = data[:-self._algorithm.tag_len]
260
+ mode_spec = modes.GCM(self._iv, tag, min_tag_length=self._algorithm.tag_len)
261
+ else:
262
+ mode_spec = modes.CBC(self._iv)
263
+ gcm_data = data
264
+ cipher_obj = self._create_cipher(mode_spec)
265
+ decryptor = cipher_obj.decryptor()
266
+ if crypto_mode.upper() == "GCM" and aad:
267
+ decryptor.authenticate_additional_data(aad)
268
+ decrypted = decryptor.update(gcm_data) + decryptor.finalize()
269
+ if crypto_mode.upper() != "GCM":
270
+ decrypted = self._pkcs7_unpad(decrypted)
271
+
272
+ output_stream.write(decrypted)
273
+ return decrypted
274
+ except Exception as e:
275
+ raise Exception("process file error: " + str(e)) from e
276
+
277
+ def _init_cipher(self):
278
+ pass
279
+
280
+ @staticmethod
281
+ def _pkcs7_pad(data, block_size):
282
+ pad_len = block_size - (len(data) % block_size)
283
+ return data + bytes([pad_len] * pad_len)
284
+
285
+ @staticmethod
286
+ def _pkcs7_unpad(data, block_size=16):
287
+ if not data or len(data) % block_size != 0:
288
+ raise ValueError("invalid data length")
289
+ pad_len = data[-1]
290
+ if pad_len < 1 or pad_len > block_size:
291
+ raise ValueError("invalid padding length")
292
+ if data[-pad_len:] != bytes([pad_len] * pad_len):
293
+ raise ValueError("invalid padding bytes")
294
+ return data[:-pad_len]
@@ -0,0 +1,24 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from huaweicloud_encryptionsdk.model.crypto_result import CryptoResult
4
+ from huaweicloud_encryptionsdk.model.data_key_materials import DataKeyMaterials
5
+ from huaweicloud_encryptionsdk.model.request.encrypt_request import EncryptRequest
6
+
7
+
8
+ class CryptoHandler(ABC):
9
+
10
+ @abstractmethod
11
+ def encrypt(self, request, data_key_materials):
12
+ pass
13
+
14
+ @abstractmethod
15
+ def decrypt(self, cipher_text, data_key_materials):
16
+ pass
17
+
18
+ @abstractmethod
19
+ def encrypt_stream(self, input_stream, output_stream, data_key_materials, encryption_context):
20
+ pass
21
+
22
+ @abstractmethod
23
+ def decrypt_stream(self, input_stream, output_stream, data_key_materials):
24
+ pass