bk-crypto-python-sdk 1.1.0__tar.gz → 2.0.0__tar.gz
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.
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/PKG-INFO +23 -111
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/ciphers.py +1 -1
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/pyproject.toml +2 -2
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/readme.md +20 -108
- bk-crypto-python-sdk-1.1.0/setup.py +0 -42
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/LICENSE.txt +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/base.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/rsa.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/sm2.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/configs.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/interceptors.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/options.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/constants.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/basic/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/basic/ciphers.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/fields.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/init_configs.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/selectors.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/settings.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/drf/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/aes.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/base.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/sm4.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/configs.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/interceptors.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/options.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/types.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/utils/__init__.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/utils/base_interceptors.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/utils/convertors.py +0 -0
- {bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/utils/module_loding.py +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bk-crypto-python-sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: bk-crypto-python-sdk is a lightweight cryptography toolkit for Python applications based on Cryptodome / tongsuopy and other encryption libraries.
|
|
5
5
|
Author: TencentBlueKing
|
|
6
6
|
Author-email: contactus_bk@tencent.com
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.8,<3.12
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.8
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.9
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Requires-Dist: dacite (>=1.8.1,<2.0.0)
|
|
14
14
|
Requires-Dist: pycryptodomex (>=3.18.0,<4.0.0)
|
|
15
15
|
Requires-Dist: tongsuopy-crayon (>=1.0.2b5,<2.0.0)
|
|
@@ -20,7 +20,7 @@ Description-Content-Type: text/markdown
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-

|
|
24
24
|

|
|
25
25
|
[](LICENSE.txt)
|
|
26
26
|
|
|
@@ -60,22 +60,6 @@ $ pip install bk-crypto-python-sdk
|
|
|
60
60
|
|
|
61
61
|
**非对称加密**
|
|
62
62
|
|
|
63
|
-
```python
|
|
64
|
-
import os
|
|
65
|
-
|
|
66
|
-
from bkcrypto import constants
|
|
67
|
-
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
68
|
-
from bkcrypto.contrib.basic.ciphers import get_symmetric_cipher
|
|
69
|
-
|
|
70
|
-
symmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher(
|
|
71
|
-
cipher_type=constants.SymmetricCipherType.SM4.value,
|
|
72
|
-
common={"key": os.urandom(16)},
|
|
73
|
-
)
|
|
74
|
-
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**对称加密**
|
|
78
|
-
|
|
79
63
|
````python
|
|
80
64
|
from bkcrypto import constants
|
|
81
65
|
from bkcrypto.asymmetric import options
|
|
@@ -101,6 +85,22 @@ assert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))
|
|
|
101
85
|
assert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))
|
|
102
86
|
````
|
|
103
87
|
|
|
88
|
+
**对称加密**
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
import os
|
|
92
|
+
|
|
93
|
+
from bkcrypto import constants
|
|
94
|
+
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
95
|
+
from bkcrypto.contrib.basic.ciphers import get_symmetric_cipher
|
|
96
|
+
|
|
97
|
+
symmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher(
|
|
98
|
+
cipher_type=constants.SymmetricCipherType.SM4.value,
|
|
99
|
+
common={"key": os.urandom(16)},
|
|
100
|
+
)
|
|
101
|
+
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
102
|
+
```
|
|
103
|
+
|
|
104
104
|
#### 2. 结合 Django 使用
|
|
105
105
|
|
|
106
106
|
在 Django Settings 中配置加密算法类型
|
|
@@ -147,7 +147,7 @@ assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
|
147
147
|
```python
|
|
148
148
|
from bkcrypto import constants
|
|
149
149
|
from bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions
|
|
150
|
-
from bkcrypto.asymmetric.options import RSAAsymmetricOptions
|
|
150
|
+
from bkcrypto.asymmetric.options import RSAAsymmetricOptions, SM2AsymmetricOptions
|
|
151
151
|
|
|
152
152
|
BKCRYPTO = {
|
|
153
153
|
# 声明项目所使用的非对称加密算法
|
|
@@ -180,9 +180,9 @@ BKCRYPTO = {
|
|
|
180
180
|
"common": {"public_key_string": "your key"},
|
|
181
181
|
"cipher_options": {
|
|
182
182
|
constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(
|
|
183
|
-
padding=constants.RSACipherPadding.
|
|
183
|
+
padding=constants.RSACipherPadding.PKCS1_v1_5
|
|
184
184
|
),
|
|
185
|
-
constants.AsymmetricCipherType.SM2.value:
|
|
185
|
+
constants.AsymmetricCipherType.SM2.value: SM2AsymmetricOptions()
|
|
186
186
|
},
|
|
187
187
|
},
|
|
188
188
|
}
|
|
@@ -229,94 +229,6 @@ class IdentityData(models.Model):
|
|
|
229
229
|
password = SymmetricTextField("密码", blank=True, null=True)
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
#### 3. Using Django CipherManager
|
|
233
|
-
|
|
234
|
-
Configure the encryption algorithm type in Django Settings
|
|
235
|
-
|
|
236
|
-
```python
|
|
237
|
-
from bkcrypto import constants
|
|
238
|
-
from bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions
|
|
239
|
-
from bkcrypto.asymmetric.options import RSAAsymmetricOptions
|
|
240
|
-
|
|
241
|
-
BKCRYPTO = {
|
|
242
|
-
# Declare the asymmetric encryption algorithm used by the project
|
|
243
|
-
"ASYMMETRIC_CIPHER_TYPE": constants.AsymmetricCipherType.SM2.value,
|
|
244
|
-
# Declare the symmetric encryption algorithm used by the project
|
|
245
|
-
"SYMMETRIC_CIPHER_TYPE": constants.SymmetricCipherType.SM4.value,
|
|
246
|
-
"SYMMETRIC_CIPHERS": {
|
|
247
|
-
# default - The configured symmetric encryption instance can be configured with multiple instances depending on the project requirements
|
|
248
|
-
"default": {
|
|
249
|
-
# Optional, used in cases where settings cannot directly obtain the key
|
|
250
|
-
# "get_key_config": "apps.utils.encrypt.key.get_key_config",
|
|
251
|
-
# Optional, used for ModelField, encrypted with this prefix to store the database, decrypting and analyzing the prefix and selecting the appropriate decryption algorithm
|
|
252
|
-
# ⚠️ The prefix and cipher type must be in one-to-one correspondence, and there can be no prefix matching relationship
|
|
253
|
-
# "db_prefix_map": {
|
|
254
|
-
# SymmetricCipherType.AES.value: "aes_str:::",
|
|
255
|
-
# SymmetricCipherType.SM4.value: "sm4_str:::"
|
|
256
|
-
# },
|
|
257
|
-
# Common parameter configuration, sharing these parameters when initializing different ciphers
|
|
258
|
-
"common": {"key": "your key"},
|
|
259
|
-
"cipher_options": {
|
|
260
|
-
constants.SymmetricCipherType.AES.value: AESSymmetricOptions(key_size=16),
|
|
261
|
-
# Blue Whale recommended configuration
|
|
262
|
-
constants.SymmetricCipherType.SM4.value: SM4SymmetricOptions(mode=constants.SymmetricMode.CTR)
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
"ASYMMETRIC_CIPHERS": {
|
|
267
|
-
# Configuration same as SYMMETRIC_CIPHERS
|
|
268
|
-
"default": {
|
|
269
|
-
"common": {"public_key_string": "your key"},
|
|
270
|
-
"cipher_options": {
|
|
271
|
-
constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(
|
|
272
|
-
padding=constants.RSACipherPadding.PKCS1_OAEP
|
|
273
|
-
),
|
|
274
|
-
constants.AsymmetricCipherType.SM2.value: SM4SymmetricOptions()
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
**Asymmetric Encryption**
|
|
282
|
-
|
|
283
|
-
Use `asymmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.ASYMMETRIC_CIPHERS`
|
|
284
|
-
|
|
285
|
-
```python
|
|
286
|
-
from bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher
|
|
287
|
-
from bkcrypto.contrib.django.ciphers import asymmetric_cipher_manager
|
|
288
|
-
|
|
289
|
-
asymmetric_cipher: BaseAsymmetricCipher = asymmetric_cipher_manager.cipher(using="default")
|
|
290
|
-
|
|
291
|
-
# Encrypt and Decrypt
|
|
292
|
-
assert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))
|
|
293
|
-
# Signature verification
|
|
294
|
-
assert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**Symmetric Encryption**
|
|
298
|
-
|
|
299
|
-
Use `symmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.SYMMETRIC_CIPHERS`
|
|
300
|
-
|
|
301
|
-
```python
|
|
302
|
-
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
303
|
-
from bkcrypto.contrib.django.ciphers import symmetric_cipher_manager
|
|
304
|
-
|
|
305
|
-
# using - Specifies a symmetric encryption instance, defaults to 'default'
|
|
306
|
-
symmetric_cipher: BaseSymmetricCipher = symmetric_cipher_manager.cipher(using="default")
|
|
307
|
-
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**Django ModelField**
|
|
311
|
-
|
|
312
|
-
```python
|
|
313
|
-
from django.db import models
|
|
314
|
-
from bkcrypto.contrib.django.fields import SymmetricTextField
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
class IdentityData(models.Model):
|
|
318
|
-
password = SymmetricTextField("Password", blank=True, null=True)
|
|
319
|
-
```
|
|
320
232
|
|
|
321
233
|
## Roadmap
|
|
322
234
|
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/ciphers.py
RENAMED
|
@@ -41,7 +41,7 @@ def get_symmetric_cipher(
|
|
|
41
41
|
cipher_options: typing.Optional[typing.Dict[str, typing.Optional[SymmetricOptions]]] = None,
|
|
42
42
|
) -> BaseSymmetricCipher:
|
|
43
43
|
return ciphers.get_symmetric_cipher(
|
|
44
|
-
cipher_type=cipher_type or crypto_settings.
|
|
44
|
+
cipher_type=cipher_type or crypto_settings.SYMMETRIC_CIPHER_TYPE,
|
|
45
45
|
common=common,
|
|
46
46
|
cipher_options=cipher_options,
|
|
47
47
|
symmetric_cipher_classes=crypto_settings.SYMMETRIC_CIPHER_CLASSES,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "bk-crypto-python-sdk"
|
|
3
|
-
version = "
|
|
3
|
+
version = "2.0.0"
|
|
4
4
|
description = "bk-crypto-python-sdk is a lightweight cryptography toolkit for Python applications based on Cryptodome / tongsuopy and other encryption libraries."
|
|
5
5
|
authors = ["TencentBlueKing <contactus_bk@tencent.com>"]
|
|
6
6
|
readme = "readme.md"
|
|
@@ -9,7 +9,7 @@ packages = [
|
|
|
9
9
|
]
|
|
10
10
|
|
|
11
11
|
[tool.poetry.dependencies]
|
|
12
|
-
python = ">=3.
|
|
12
|
+
python = ">=3.8,<3.12"
|
|
13
13
|
tongsuopy-crayon = "^1.0.2b5"
|
|
14
14
|
pycryptodomex = "^3.18.0"
|
|
15
15
|
dacite = "^1.8.1"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
[](LICENSE.txt)
|
|
8
8
|
|
|
@@ -42,22 +42,6 @@ $ pip install bk-crypto-python-sdk
|
|
|
42
42
|
|
|
43
43
|
**非对称加密**
|
|
44
44
|
|
|
45
|
-
```python
|
|
46
|
-
import os
|
|
47
|
-
|
|
48
|
-
from bkcrypto import constants
|
|
49
|
-
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
50
|
-
from bkcrypto.contrib.basic.ciphers import get_symmetric_cipher
|
|
51
|
-
|
|
52
|
-
symmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher(
|
|
53
|
-
cipher_type=constants.SymmetricCipherType.SM4.value,
|
|
54
|
-
common={"key": os.urandom(16)},
|
|
55
|
-
)
|
|
56
|
-
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**对称加密**
|
|
60
|
-
|
|
61
45
|
````python
|
|
62
46
|
from bkcrypto import constants
|
|
63
47
|
from bkcrypto.asymmetric import options
|
|
@@ -83,6 +67,22 @@ assert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))
|
|
|
83
67
|
assert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))
|
|
84
68
|
````
|
|
85
69
|
|
|
70
|
+
**对称加密**
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import os
|
|
74
|
+
|
|
75
|
+
from bkcrypto import constants
|
|
76
|
+
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
77
|
+
from bkcrypto.contrib.basic.ciphers import get_symmetric_cipher
|
|
78
|
+
|
|
79
|
+
symmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher(
|
|
80
|
+
cipher_type=constants.SymmetricCipherType.SM4.value,
|
|
81
|
+
common={"key": os.urandom(16)},
|
|
82
|
+
)
|
|
83
|
+
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
86
|
#### 2. 结合 Django 使用
|
|
87
87
|
|
|
88
88
|
在 Django Settings 中配置加密算法类型
|
|
@@ -129,7 +129,7 @@ assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
|
129
129
|
```python
|
|
130
130
|
from bkcrypto import constants
|
|
131
131
|
from bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions
|
|
132
|
-
from bkcrypto.asymmetric.options import RSAAsymmetricOptions
|
|
132
|
+
from bkcrypto.asymmetric.options import RSAAsymmetricOptions, SM2AsymmetricOptions
|
|
133
133
|
|
|
134
134
|
BKCRYPTO = {
|
|
135
135
|
# 声明项目所使用的非对称加密算法
|
|
@@ -162,9 +162,9 @@ BKCRYPTO = {
|
|
|
162
162
|
"common": {"public_key_string": "your key"},
|
|
163
163
|
"cipher_options": {
|
|
164
164
|
constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(
|
|
165
|
-
padding=constants.RSACipherPadding.
|
|
165
|
+
padding=constants.RSACipherPadding.PKCS1_v1_5
|
|
166
166
|
),
|
|
167
|
-
constants.AsymmetricCipherType.SM2.value:
|
|
167
|
+
constants.AsymmetricCipherType.SM2.value: SM2AsymmetricOptions()
|
|
168
168
|
},
|
|
169
169
|
},
|
|
170
170
|
}
|
|
@@ -211,94 +211,6 @@ class IdentityData(models.Model):
|
|
|
211
211
|
password = SymmetricTextField("密码", blank=True, null=True)
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
#### 3. Using Django CipherManager
|
|
215
|
-
|
|
216
|
-
Configure the encryption algorithm type in Django Settings
|
|
217
|
-
|
|
218
|
-
```python
|
|
219
|
-
from bkcrypto import constants
|
|
220
|
-
from bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions
|
|
221
|
-
from bkcrypto.asymmetric.options import RSAAsymmetricOptions
|
|
222
|
-
|
|
223
|
-
BKCRYPTO = {
|
|
224
|
-
# Declare the asymmetric encryption algorithm used by the project
|
|
225
|
-
"ASYMMETRIC_CIPHER_TYPE": constants.AsymmetricCipherType.SM2.value,
|
|
226
|
-
# Declare the symmetric encryption algorithm used by the project
|
|
227
|
-
"SYMMETRIC_CIPHER_TYPE": constants.SymmetricCipherType.SM4.value,
|
|
228
|
-
"SYMMETRIC_CIPHERS": {
|
|
229
|
-
# default - The configured symmetric encryption instance can be configured with multiple instances depending on the project requirements
|
|
230
|
-
"default": {
|
|
231
|
-
# Optional, used in cases where settings cannot directly obtain the key
|
|
232
|
-
# "get_key_config": "apps.utils.encrypt.key.get_key_config",
|
|
233
|
-
# Optional, used for ModelField, encrypted with this prefix to store the database, decrypting and analyzing the prefix and selecting the appropriate decryption algorithm
|
|
234
|
-
# ⚠️ The prefix and cipher type must be in one-to-one correspondence, and there can be no prefix matching relationship
|
|
235
|
-
# "db_prefix_map": {
|
|
236
|
-
# SymmetricCipherType.AES.value: "aes_str:::",
|
|
237
|
-
# SymmetricCipherType.SM4.value: "sm4_str:::"
|
|
238
|
-
# },
|
|
239
|
-
# Common parameter configuration, sharing these parameters when initializing different ciphers
|
|
240
|
-
"common": {"key": "your key"},
|
|
241
|
-
"cipher_options": {
|
|
242
|
-
constants.SymmetricCipherType.AES.value: AESSymmetricOptions(key_size=16),
|
|
243
|
-
# Blue Whale recommended configuration
|
|
244
|
-
constants.SymmetricCipherType.SM4.value: SM4SymmetricOptions(mode=constants.SymmetricMode.CTR)
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
},
|
|
248
|
-
"ASYMMETRIC_CIPHERS": {
|
|
249
|
-
# Configuration same as SYMMETRIC_CIPHERS
|
|
250
|
-
"default": {
|
|
251
|
-
"common": {"public_key_string": "your key"},
|
|
252
|
-
"cipher_options": {
|
|
253
|
-
constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(
|
|
254
|
-
padding=constants.RSACipherPadding.PKCS1_OAEP
|
|
255
|
-
),
|
|
256
|
-
constants.AsymmetricCipherType.SM2.value: SM4SymmetricOptions()
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
**Asymmetric Encryption**
|
|
264
|
-
|
|
265
|
-
Use `asymmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.ASYMMETRIC_CIPHERS`
|
|
266
|
-
|
|
267
|
-
```python
|
|
268
|
-
from bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher
|
|
269
|
-
from bkcrypto.contrib.django.ciphers import asymmetric_cipher_manager
|
|
270
|
-
|
|
271
|
-
asymmetric_cipher: BaseAsymmetricCipher = asymmetric_cipher_manager.cipher(using="default")
|
|
272
|
-
|
|
273
|
-
# Encrypt and Decrypt
|
|
274
|
-
assert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))
|
|
275
|
-
# Signature verification
|
|
276
|
-
assert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
**Symmetric Encryption**
|
|
280
|
-
|
|
281
|
-
Use `symmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.SYMMETRIC_CIPHERS`
|
|
282
|
-
|
|
283
|
-
```python
|
|
284
|
-
from bkcrypto.symmetric.ciphers import BaseSymmetricCipher
|
|
285
|
-
from bkcrypto.contrib.django.ciphers import symmetric_cipher_manager
|
|
286
|
-
|
|
287
|
-
# using - Specifies a symmetric encryption instance, defaults to 'default'
|
|
288
|
-
symmetric_cipher: BaseSymmetricCipher = symmetric_cipher_manager.cipher(using="default")
|
|
289
|
-
assert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
**Django ModelField**
|
|
293
|
-
|
|
294
|
-
```python
|
|
295
|
-
from django.db import models
|
|
296
|
-
from bkcrypto.contrib.django.fields import SymmetricTextField
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
class IdentityData(models.Model):
|
|
300
|
-
password = SymmetricTextField("Password", blank=True, null=True)
|
|
301
|
-
```
|
|
302
214
|
|
|
303
215
|
## Roadmap
|
|
304
216
|
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
packages = \
|
|
5
|
-
['bkcrypto',
|
|
6
|
-
'bkcrypto.asymmetric',
|
|
7
|
-
'bkcrypto.asymmetric.ciphers',
|
|
8
|
-
'bkcrypto.contrib',
|
|
9
|
-
'bkcrypto.contrib.basic',
|
|
10
|
-
'bkcrypto.contrib.django',
|
|
11
|
-
'bkcrypto.contrib.drf',
|
|
12
|
-
'bkcrypto.symmetric',
|
|
13
|
-
'bkcrypto.symmetric.ciphers',
|
|
14
|
-
'bkcrypto.utils']
|
|
15
|
-
|
|
16
|
-
package_data = \
|
|
17
|
-
{'': ['*']}
|
|
18
|
-
|
|
19
|
-
install_requires = \
|
|
20
|
-
['dacite>=1.8.1,<2.0.0',
|
|
21
|
-
'pycryptodomex>=3.18.0,<4.0.0',
|
|
22
|
-
'tongsuopy-crayon>=1.0.2b5,<2.0.0',
|
|
23
|
-
'wrapt>=1.15.0,<2.0.0']
|
|
24
|
-
|
|
25
|
-
setup_kwargs = {
|
|
26
|
-
'name': 'bk-crypto-python-sdk',
|
|
27
|
-
'version': '1.1.0',
|
|
28
|
-
'description': 'bk-crypto-python-sdk is a lightweight cryptography toolkit for Python applications based on Cryptodome / tongsuopy and other encryption libraries.',
|
|
29
|
-
'long_description': '# BlueKing crypto-python-sdk\n\n---\n\n\n\n[](LICENSE.txt)\n\n\n[](https://github.com/TencentBlueKing/crypto-python-sdk/pulls)\n\n[](https://github.com/TencentBlueKing/crypto-python-sdk/actions/workflows/release.yml)\n\n[(English Documents Available)](https://github.com/TencentBlueKing/crypto-python-sdk/blob/main/readme_en.md)\n\n## Overview\n\n️🔧 BlueKing crypto-python-sdk 是一个基于 pyCryptodome / tongsuopy 等加密库的轻量级密码学工具包,为 Python 应用统一的加解密实现,\n便于项目在不同的加密方式之间进行无侵入切换\n\n## Features\n\n* [Basic] 提供加密统一抽象层,对接 Cryptodome / tongsuopy 等加密库,提供统一的加解密实现\n* [Basic] 支持国际主流密码学算法:AES、RSA\n* [Basic] 支持中国商用密码学算法:SM2、SM4\n* [Basic] 非对称加密支持 CBC、CTR、GCM、CFB 作为块密码模式\n* [Contrib] Django Support,集成 Django settings、ModelField\n\n## Getting started\n\n### Installation\n\n```bash\n$ pip install bk-crypto-python-sdk\n```\n\n### Usage\n\n> 更多用法参考:[使用文档](https://github.com/TencentBlueKing/crypto-python-sdk/blob/main/docs/usage.md)\n\n#### 1. 基础用法\n\n**非对称加密**\n\n```python\nimport os\n\nfrom bkcrypto import constants\nfrom bkcrypto.symmetric.ciphers import BaseSymmetricCipher\nfrom bkcrypto.contrib.basic.ciphers import get_symmetric_cipher\n\nsymmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher(\n cipher_type=constants.SymmetricCipherType.SM4.value,\n common={"key": os.urandom(16)},\n)\nassert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))\n```\n\n**对称加密**\n\n````python\nfrom bkcrypto import constants\nfrom bkcrypto.asymmetric import options\nfrom bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher\nfrom bkcrypto.contrib.basic.ciphers import get_asymmetric_cipher\n\nasymmetric_cipher: BaseAsymmetricCipher = get_asymmetric_cipher(\n cipher_type=constants.AsymmetricCipherType.SM2.value,\n # 传入 None 将随机生成密钥,业务可以根据场景选择传入密钥或随机生成\n cipher_options={\n constants.AsymmetricCipherType.SM2.value: options.SM2AsymmetricOptions(\n private_key_string=None\n ),\n constants.AsymmetricCipherType.RSA.value: options.SM2AsymmetricOptions(\n private_key_string=None\n ),\n }\n)\n\n# 加解密\nassert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))\n# 验签\nassert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))\n````\n\n#### 2. 结合 Django 使用\n\n在 Django Settings 中配置加密算法类型\n\n```python\nfrom bkcrypto import constants\n\nBKCRYPTO = {\n # 声明项目所使用的非对称加密算法\n "ASYMMETRIC_CIPHER_TYPE": constants.AsymmetricCipherType.SM2.value,\n # 声明项目所使用的对称加密算法\n "SYMMETRIC_CIPHER_TYPE": constants.SymmetricCipherType.SM4.value,\n}\n```\n\n**非对称加密**\n\n```python\nfrom bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import get_asymmetric_cipher\n\nasymmetric_cipher: BaseAsymmetricCipher = get_asymmetric_cipher()\n\n# 加解密\nassert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))\n# 验签\nassert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))\n```\n\n**对称加密**\n\n```python\nfrom bkcrypto.symmetric.ciphers import BaseSymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import get_symmetric_cipher\n\nsymmetric_cipher: BaseSymmetricCipher = get_symmetric_cipher()\nassert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))\n```\n\n#### 3. 使用 Django CipherManager\n\n在 Django Settings 中配置加密算法类型\n\n```python\nfrom bkcrypto import constants\nfrom bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions\nfrom bkcrypto.asymmetric.options import RSAAsymmetricOptions\n\nBKCRYPTO = {\n # 声明项目所使用的非对称加密算法\n "ASYMMETRIC_CIPHER_TYPE": constants.AsymmetricCipherType.SM2.value,\n # 声明项目所使用的对称加密算法\n "SYMMETRIC_CIPHER_TYPE": constants.SymmetricCipherType.SM4.value,\n "SYMMETRIC_CIPHERS": {\n # default - 所配置的对称加密实例,根据项目需要可以配置多个\n "default": {\n # 可选,用于在 settings 没法直接获取 key 的情况\n # "get_key_config": "apps.utils.encrypt.key.get_key_config",\n # 可选,用于 ModelField,加密时携带该前缀入库,解密时分析该前缀并选择相应的解密算法\n # ⚠️ 前缀和 cipher type 必须一一对应,且不能有前缀匹配关系\n # "db_prefix_map": {\n # SymmetricCipherType.AES.value: "aes_str:::",\n # SymmetricCipherType.SM4.value: "sm4_str:::"\n # },\n # 公共参数配置,不同 cipher 初始化时共用这部分参数\n "common": {"key": "your key"},\n "cipher_options": {\n constants.SymmetricCipherType.AES.value: AESSymmetricOptions(key_size=16),\n # 蓝鲸推荐配置\n constants.SymmetricCipherType.SM4.value: SM4SymmetricOptions(mode=constants.SymmetricMode.CTR)\n }\n },\n },\n "ASYMMETRIC_CIPHERS": {\n # 配置同 SYMMETRIC_CIPHERS\n "default": {\n "common": {"public_key_string": "your key"},\n "cipher_options": {\n constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(\n padding=constants.RSACipherPadding.PKCS1_OAEP\n ),\n constants.AsymmetricCipherType.SM2.value: SM4SymmetricOptions()\n },\n },\n }\n}\n```\n\n**非对称加密**\n\n使用 `asymmetric_cipher_manager` 获取 `BKCRYPTO.ASYMMETRIC_CIPHERS` 配置的 `cipher`\n\n```python\nfrom bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import asymmetric_cipher_manager\n\nasymmetric_cipher: BaseAsymmetricCipher = asymmetric_cipher_manager.cipher(using="default")\n\n# 加解密\nassert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))\n# 验签\nassert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))\n```\n\n**对称加密**\n\n使用 `symmetric_cipher_manager` 获取 `BKCRYPTO.SYMMETRIC_CIPHERS` 配置的 `cipher`\n\n```python\nfrom bkcrypto.symmetric.ciphers import BaseSymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import symmetric_cipher_manager\n\n# using - 指定对称加密实例,默认使用 `default`\nsymmetric_cipher: BaseSymmetricCipher = symmetric_cipher_manager.cipher(using="default")\nassert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))\n```\n\n**Django ModelField**\n\n```python\nfrom django.db import models\nfrom bkcrypto.contrib.django.fields import SymmetricTextField\n\n\nclass IdentityData(models.Model):\n password = SymmetricTextField("密码", blank=True, null=True)\n```\n\n#### 3. Using Django CipherManager\n\nConfigure the encryption algorithm type in Django Settings\n\n```python\nfrom bkcrypto import constants\nfrom bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions\nfrom bkcrypto.asymmetric.options import RSAAsymmetricOptions\n\nBKCRYPTO = {\n # Declare the asymmetric encryption algorithm used by the project\n "ASYMMETRIC_CIPHER_TYPE": constants.AsymmetricCipherType.SM2.value,\n # Declare the symmetric encryption algorithm used by the project\n "SYMMETRIC_CIPHER_TYPE": constants.SymmetricCipherType.SM4.value,\n "SYMMETRIC_CIPHERS": {\n # default - The configured symmetric encryption instance can be configured with multiple instances depending on the project requirements\n "default": {\n # Optional, used in cases where settings cannot directly obtain the key\n # "get_key_config": "apps.utils.encrypt.key.get_key_config",\n # Optional, used for ModelField, encrypted with this prefix to store the database, decrypting and analyzing the prefix and selecting the appropriate decryption algorithm\n # ⚠️ The prefix and cipher type must be in one-to-one correspondence, and there can be no prefix matching relationship\n # "db_prefix_map": {\n # SymmetricCipherType.AES.value: "aes_str:::",\n # SymmetricCipherType.SM4.value: "sm4_str:::"\n # },\n # Common parameter configuration, sharing these parameters when initializing different ciphers\n "common": {"key": "your key"},\n "cipher_options": {\n constants.SymmetricCipherType.AES.value: AESSymmetricOptions(key_size=16),\n # Blue Whale recommended configuration\n constants.SymmetricCipherType.SM4.value: SM4SymmetricOptions(mode=constants.SymmetricMode.CTR)\n }\n },\n },\n "ASYMMETRIC_CIPHERS": {\n # Configuration same as SYMMETRIC_CIPHERS\n "default": {\n "common": {"public_key_string": "your key"},\n "cipher_options": {\n constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions(\n padding=constants.RSACipherPadding.PKCS1_OAEP\n ),\n constants.AsymmetricCipherType.SM2.value: SM4SymmetricOptions()\n },\n },\n }\n}\n```\n\n**Asymmetric Encryption**\n\nUse `asymmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.ASYMMETRIC_CIPHERS`\n\n```python\nfrom bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import asymmetric_cipher_manager\n\nasymmetric_cipher: BaseAsymmetricCipher = asymmetric_cipher_manager.cipher(using="default")\n\n# Encrypt and Decrypt\nassert "123" == asymmetric_cipher.decrypt(asymmetric_cipher.encrypt("123"))\n# Signature verification\nassert asymmetric_cipher.verify(plaintext="123", signature=asymmetric_cipher.sign("123"))\n```\n\n**Symmetric Encryption**\n\nUse `symmetric_cipher_manager` to get the `cipher` configured for `BKCRYPTO.SYMMETRIC_CIPHERS`\n\n```python\nfrom bkcrypto.symmetric.ciphers import BaseSymmetricCipher\nfrom bkcrypto.contrib.django.ciphers import symmetric_cipher_manager\n\n# using - Specifies a symmetric encryption instance, defaults to \'default\'\nsymmetric_cipher: BaseSymmetricCipher = symmetric_cipher_manager.cipher(using="default")\nassert "123" == symmetric_cipher.decrypt(symmetric_cipher.encrypt("123"))\n```\n\n**Django ModelField**\n\n```python\nfrom django.db import models\nfrom bkcrypto.contrib.django.fields import SymmetricTextField\n\n\nclass IdentityData(models.Model):\n password = SymmetricTextField("Password", blank=True, null=True)\n```\n\n## Roadmap\n\n- [版本日志](https://github.com/TencentBlueKing/crypto-python-sdk/blob/main/release.md)\n\n## Support\n\n- [蓝鲸论坛](https://bk.tencent.com/s-mart/community)\n- [蓝鲸 DevOps 在线视频教程](https://bk.tencent.com/s-mart/video/)\n- [蓝鲸社区版交流群](https://jq.qq.com/?_wv=1027&k=5zk8F7G)\n\n## BlueKing Community\n\n- [BK-CMDB](https://github.com/Tencent/bk-cmdb):蓝鲸配置平台(蓝鲸 CMDB)是一个面向资产及应用的企业级配置管理平台。\n- [BK-CI](https://github.com/Tencent/bk-ci):蓝鲸持续集成平台是一个开源的持续集成和持续交付系统,可以轻松将你的研发流程呈现到你面前。\n- [BK-BCS](https://github.com/Tencent/bk-bcs):蓝鲸容器管理平台是以容器技术为基础,为微服务业务提供编排管理的基础服务平台。\n- [BK-PaaS](https://github.com/Tencent/bk-paas):蓝鲸 PaaS 平台是一个开放式的开发平台,让开发者可以方便快捷地创建、开发、部署和管理\n SaaS 应用。\n- [BK-SOPS](https://github.com/Tencent/bk-sops):标准运维(SOPS)是通过可视化的图形界面进行任务流程编排和执行的系统,是蓝鲸体系中一款轻量级的调度编排类\n SaaS 产品。\n- [BK-JOB](https://github.com/Tencent/bk-job) 蓝鲸作业平台(Job)是一套运维脚本管理系统,具备海量任务并发处理能力。\n\n## Contributing\n\n如果你有好的意见或建议,欢迎给我们提 Issues 或 Pull Requests,为蓝鲸开源社区贡献力量。 \n[腾讯开源激励计划](https://opensource.tencent.com/contribution) 鼓励开发者的参与和贡献,期待你的加入。\n\n## License\n\n基于 MIT 协议, 详细请参考 [LICENSE](https://github.com/TencentBlueKing/crypto-python-sdk/blob/main/LICENSE.txt)\n',
|
|
30
|
-
'author': 'TencentBlueKing',
|
|
31
|
-
'author_email': 'contactus_bk@tencent.com',
|
|
32
|
-
'maintainer': 'None',
|
|
33
|
-
'maintainer_email': 'None',
|
|
34
|
-
'url': 'None',
|
|
35
|
-
'packages': packages,
|
|
36
|
-
'package_data': package_data,
|
|
37
|
-
'install_requires': install_requires,
|
|
38
|
-
'python_requires': '>=3.6.2,<3.11',
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
setup(**setup_kwargs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/__init__.py
RENAMED
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/base.py
RENAMED
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/rsa.py
RENAMED
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/ciphers/sm2.py
RENAMED
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/asymmetric/interceptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/basic/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/init_configs.py
RENAMED
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/selectors.py
RENAMED
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/contrib/django/settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/ciphers/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/symmetric/interceptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bk-crypto-python-sdk-1.1.0 → bk_crypto_python_sdk-2.0.0}/bkcrypto/utils/base_interceptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|