Skip to content

Commit e808b45

Browse files
authored
Merge pull request #4032 from liuliaozhong-canway/master_issue_3996
fix: 密码明文传输问题 #3996
2 parents 02ca7b4 + 1c14d15 commit e808b45

31 files changed

Lines changed: 613 additions & 27 deletions

File tree

op-tools/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,23 @@ pip install pymysql pandas openpyxl
9191
cd biz_statistics
9292
python generate_business_statictics_excel.py
9393
```
94+
95+
### 5.生成SM2加解密所需的秘钥对
96+
97+
#### 代码位置
98+
sm2_keypair
99+
100+
#### 功能简介
101+
102+
用于生成SM2加解密所需的秘钥对,生成的原始秘钥可以直接用于后端SM2Util工具,生成的PEM秘钥可以直接用于前端vue。
103+
104+
> python环境: python3.6
105+
106+
#### 执行
107+
108+
```shell
109+
# 安装依赖
110+
pip install bk-crypto-python-sdk
111+
# 生成秘钥对
112+
python generate_sm2_keypair.py
113+
```
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
生成SM2加密算法的公私钥对
5+
依赖:
6+
- bk-crypto-python-sdk
7+
"""
8+
9+
from bkcrypto.contrib.basic.ciphers import get_asymmetric_cipher
10+
from bkcrypto import constants
11+
from bkcrypto.asymmetric.ciphers import BaseAsymmetricCipher
12+
from bkcrypto.asymmetric.options import SM2AsymmetricOptions
13+
from base64 import b64encode
14+
from tongsuopy.crypto import serialization
15+
16+
17+
def generate_sm2_keypair():
18+
"""
19+
生成一套SM2密钥对:
20+
1. Job后端(SM2Utils)使用的原始公私钥
21+
2. 前端(cryptoJsSdk)使用的PEM公钥
22+
"""
23+
24+
# 1 生成SM2 Cipher对象,None表示随机生成密钥
25+
sm2_cipher: BaseAsymmetricCipher = get_asymmetric_cipher(
26+
cipher_type=constants.AsymmetricCipherType.SM2.value,
27+
cipher_options={
28+
constants.AsymmetricCipherType.SM2.value: SM2AsymmetricOptions(
29+
private_key_string=None
30+
)
31+
}
32+
)
33+
34+
private_key_obj = sm2_cipher.config.private_key
35+
public_key_obj = sm2_cipher.config.public_key
36+
37+
print('1.生成原始公私钥,可直接用于后端Java SM2Utils使用')
38+
39+
# 2.生成原始公私钥
40+
# 原始公钥 (uncompressed, 65 bytes)
41+
# 公钥点的 x,y 拼接,加上前缀 0x04
42+
numbers = public_key_obj.public_numbers()
43+
x_bytes = numbers.x.to_bytes(32, byteorder="big")
44+
y_bytes = numbers.y.to_bytes(32, byteorder="big")
45+
raw_public_bytes = b"\x04" + x_bytes + y_bytes
46+
raw_public_base64 = b64encode(raw_public_bytes).decode("utf-8")
47+
48+
# 原始私钥 (32 bytes)
49+
raw_private_bytes = private_key_obj.private_numbers().private_value.to_bytes(32, byteorder="big")
50+
raw_private_base64 = b64encode(raw_private_bytes).decode("utf-8")
51+
52+
print("原始公钥:")
53+
print(raw_public_base64)
54+
print("原始私钥:")
55+
print(raw_private_base64)
56+
57+
# 3. 生成PEM公私钥
58+
print('2.生成PEM公私钥,可直接用于前端cryptoJsSdk使用')
59+
60+
public_pem = public_key_obj.public_bytes(
61+
encoding=serialization.Encoding.PEM,
62+
format=serialization.PublicFormat.SubjectPublicKeyInfo
63+
).decode("utf-8")
64+
65+
private_pem = private_key_obj.private_bytes(
66+
encoding=serialization.Encoding.PEM,
67+
format=serialization.PrivateFormat.TraditionalOpenSSL,
68+
encryption_algorithm=serialization.NoEncryption()
69+
).decode("utf-8")
70+
71+
print("PEM公钥:")
72+
print(public_pem)
73+
print("PEM私钥:")
74+
print(private_pem)
75+
76+
77+
if __name__ == "__main__":
78+
generate_sm2_keypair()

src/backend/commons/common-crypto/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dependencies {
2626
api project(':commons:common')
2727
api project(':commons:common-utils')
2828
api 'com.tencent.bk.sdk:crypto-java-sdk'
29+
implementation 'org.bouncycastle:bcprov-jdk18on'
2930
testImplementation 'org.junit.jupiter:junit-jupiter'
3031
testImplementation 'org.springframework.boot:spring-boot-starter-test'
3132
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available.
3+
*
4+
* Copyright (C) 2021 Tencent. All rights reserved.
5+
*
6+
* BK-JOB蓝鲸智云作业平台 is licensed under the MIT License.
7+
*
8+
* License for BK-JOB蓝鲸智云作业平台:
9+
* --------------------------------------------------------------------
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
12+
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
13+
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
16+
* the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
19+
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21+
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22+
* IN THE SOFTWARE.
23+
*/
24+
25+
package com.tencent.bk.job.common.crypto;
26+
27+
import com.tencent.bk.sdk.crypto.cryptor.ASymmetricCryptor;
28+
import com.tencent.bk.sdk.crypto.cryptor.ASymmetricCryptorFactory;
29+
import lombok.extern.slf4j.Slf4j;
30+
31+
import java.security.PrivateKey;
32+
import java.security.PublicKey;
33+
import java.util.Map;
34+
import java.util.concurrent.ConcurrentHashMap;
35+
36+
/**
37+
* 非对称加解密服务
38+
*/
39+
@SuppressWarnings("unused")
40+
@Slf4j
41+
public class ASymmetricCryptoService {
42+
43+
private final CryptoConfigService cryptoConfigService;
44+
private final Map<String, ASymmetricCryptor> cryptorMap = new ConcurrentHashMap<>();
45+
46+
public ASymmetricCryptoService(CryptoConfigService cryptoConfigService) {
47+
this.cryptoConfigService = cryptoConfigService;
48+
}
49+
50+
/**
51+
* 对明文信息非对称加密,返回Base64编码后的密文信息
52+
*
53+
* @param publicKey 公钥
54+
* @param message 要加密的明文信息,不可为空
55+
* @param cryptoScenarioEnum 加密场景
56+
* @return Base64编码的加密后的密文信息
57+
*/
58+
public String encrypt(PublicKey publicKey,
59+
String message,
60+
CryptoScenarioEnum cryptoScenarioEnum) {
61+
String algorithm = cryptoConfigService.getSymmetricAlgorithmByScenario(cryptoScenarioEnum);
62+
ASymmetricCryptor cryptor = cryptorMap.computeIfAbsent(algorithm, ASymmetricCryptorFactory::getCryptor);
63+
return cryptor.encrypt(publicKey, message);
64+
}
65+
66+
/**
67+
* 对Base64编码的加密后的密文信息解密,返回解密后的明文
68+
*
69+
* @param privateKey 私钥
70+
* @param base64EncryptedMessage Base64编码的加密后的密文信息,不可为空
71+
* @param cryptoScenarioEnum 解密场景
72+
* @return 解密后的明文信息
73+
*/
74+
public String decrypt(PrivateKey privateKey,
75+
String base64EncryptedMessage,
76+
CryptoScenarioEnum cryptoScenarioEnum) {
77+
String algorithm = cryptoConfigService.getSymmetricAlgorithmByScenario(cryptoScenarioEnum);
78+
ASymmetricCryptor cryptor = cryptorMap.computeIfAbsent(algorithm, ASymmetricCryptorFactory::getCryptor);
79+
return cryptor.decrypt(privateKey, base64EncryptedMessage);
80+
}
81+
}

src/backend/commons/common-crypto/src/main/java/com/tencent/bk/job/common/crypto/CryptoConfigService.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import com.tencent.bk.sdk.crypto.cryptor.consts.CryptorNames;
2828
import lombok.extern.slf4j.Slf4j;
29+
import org.apache.commons.lang3.StringUtils;
2930

3031
import java.util.HashMap;
3132
import java.util.Map;
@@ -75,6 +76,21 @@ public String getSymmetricPassword() {
7576
return encryptConfig.getPassword();
7677
}
7778

79+
/**
80+
* 获取SM2私钥字符串
81+
*/
82+
public String getSm2PrivateKey() {
83+
return encryptConfig.getSm2PrivateKey();
84+
}
85+
86+
/**
87+
* 获取SM2公钥
88+
* @return
89+
*/
90+
public String getSm2PublicKey() {
91+
return encryptConfig.getSm2PublicKey();
92+
}
93+
7894
/**
7995
* 根据加密场景获取需要使用的加密算法
8096
*
@@ -88,6 +104,9 @@ public String getSymmetricAlgorithmByScenario(CryptoScenarioEnum cryptoScenarioE
88104
if (scenarioAlgorithms != null && scenarioAlgorithms.containsKey(cryptoScenarioEnum.getValue())) {
89105
return scenarioAlgorithms.get(cryptoScenarioEnum.getValue());
90106
}
107+
if (StringUtils.isNotEmpty(cryptoScenarioEnum.getAlgorithm())) {
108+
return cryptoScenarioEnum.getAlgorithm();
109+
}
91110
return getDefaultSymmetricAlgorithm();
92111
}
93112

src/backend/commons/common-crypto/src/main/java/com/tencent/bk/job/common/crypto/CryptoScenarioEnum.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,38 @@
2424

2525
package com.tencent.bk.job.common.crypto;
2626

27+
import com.tencent.bk.sdk.crypto.cryptor.consts.CryptorNames;
28+
2729
/**
2830
* 加密场景枚举值
2931
*/
3032
public enum CryptoScenarioEnum {
3133
// 脚本敏感参数
32-
SCRIPT_SENSITIVE_PARAM((byte) 0, "scriptSensitiveParam"),
34+
SCRIPT_SENSITIVE_PARAM((byte) 0, "scriptSensitiveParam", null),
3335
// 密文变量
34-
CIPHER_VARIABLE((byte) 0, "cipherVariable"),
36+
CIPHER_VARIABLE((byte) 0, "cipherVariable", null),
3537
// DB账号的密码
36-
DATABASE_PASSWORD((byte) 0, "databasePassword"),
38+
DATABASE_PASSWORD((byte) 0, "databasePassword", null),
3739
// 凭证信息
38-
CREDENTIAL((byte) 0, "credential"),
40+
CREDENTIAL((byte) 0, "credential", null),
3941
// 导出作业的密码
40-
EXPORT_JOB_PASSWORD((byte) 0, "exportJobPassword"),
42+
EXPORT_JOB_PASSWORD((byte) 0, "exportJobPassword", null),
4143
// 导出作业的备份文件
42-
BACKUP_FILE((byte) 0, "backupFile");
44+
BACKUP_FILE((byte) 0, "backupFile", null),
45+
// 前端给后端提交账号的密码
46+
SUBMIT_ACCOUNT_PASSWORD((byte) 1, "submitAccountPassword", CryptorNames.SM2);
4347

4448
// 加密类型:0为对称加密,1为非对称加密
4549
private final byte type;
4650
// 场景标识
4751
private final String value;
52+
// 场景默认加密算法
53+
private final String algorithm;
4854

49-
CryptoScenarioEnum(byte type, String value) {
55+
CryptoScenarioEnum(byte type, String value, String algorithm) {
5056
this.type = type;
5157
this.value = value;
58+
this.algorithm = algorithm;
5259
}
5360

5461
public String getValue() {
@@ -58,4 +65,8 @@ public String getValue() {
5865
public byte getType() {
5966
return type;
6067
}
68+
69+
public String getAlgorithm() {
70+
return algorithm;
71+
}
6172
}

src/backend/commons/common-crypto/src/main/java/com/tencent/bk/job/common/crypto/EncryptConfig.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525
package com.tencent.bk.job.common.crypto;
2626

2727
import com.tencent.bk.job.common.util.json.JsonUtils;
28+
import jakarta.annotation.PostConstruct;
2829
import lombok.Getter;
2930
import lombok.Setter;
3031
import lombok.ToString;
3132
import lombok.extern.slf4j.Slf4j;
3233
import org.springframework.boot.context.properties.ConfigurationProperties;
3334

34-
import jakarta.annotation.PostConstruct;
3535
import java.util.HashMap;
3636
import java.util.Map;
3737

@@ -49,6 +49,10 @@ public class EncryptConfig {
4949

5050
private String password;
5151

52+
private String sm2PrivateKey;
53+
54+
private String sm2PublicKey;
55+
5256
/**
5357
* 各个场景下使用的加密算法,不配置则使用默认算法
5458
*/

src/backend/commons/common-crypto/src/main/java/com/tencent/bk/job/common/crypto/config/CryptoAutoConfiguration.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424

2525
package com.tencent.bk.job.common.crypto.config;
2626

27+
import com.tencent.bk.job.common.crypto.ASymmetricCryptoService;
2728
import com.tencent.bk.job.common.crypto.CryptoConfigService;
2829
import com.tencent.bk.job.common.crypto.EncryptConfig;
2930
import com.tencent.bk.job.common.crypto.SymmetricCryptoService;
3031
import com.tencent.bk.job.common.crypto.scenario.CipherVariableCryptoService;
3132
import com.tencent.bk.job.common.crypto.scenario.DbPasswordCryptoService;
33+
import com.tencent.bk.job.common.crypto.scenario.SubmitAccountPasswordCryptoService;
3234
import com.tencent.bk.job.common.crypto.scenario.SensitiveParamCryptoService;
3335
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3436
import org.springframework.context.annotation.Bean;
@@ -62,4 +64,16 @@ DbPasswordCryptoService dbPasswordCryptoService(SymmetricCryptoService symmetric
6264
SensitiveParamCryptoService sensitiveParamCryptoService(SymmetricCryptoService symmetricCryptoService) {
6365
return new SensitiveParamCryptoService(symmetricCryptoService);
6466
}
67+
68+
@Bean
69+
ASymmetricCryptoService aSymmetricCryptoService(CryptoConfigService cryptoConfigService) {
70+
return new ASymmetricCryptoService(cryptoConfigService);
71+
}
72+
73+
@Bean
74+
SubmitAccountPasswordCryptoService submitAccountPasswordCryptoService(
75+
ASymmetricCryptoService aSymmetricCryptoService,
76+
CryptoConfigService cryptoConfigService) {
77+
return new SubmitAccountPasswordCryptoService(aSymmetricCryptoService, cryptoConfigService);
78+
}
6579
}

0 commit comments

Comments
 (0)