等保要求,密码必须使用SM2加密传输

本文介绍了如何遵循等保要求,通过SM2加密算法来增强密码在网络传输中的安全性。首先,详细展示了SM2加密的流程,包括公私钥的生成。接着,阐述了前端使用JS库进行加密,每次加密生成的密文不同,确保安全性。最后,给出了后台使用Java进行解密的步骤,并提供了所需依赖。这种方法有效防止了MD5等传统加密方式的安全隐患。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据等保要求,用户密码在登录、创建、修改等操作过程中,密码传输到后台必须加密,以免密码存在在网络传输中泄露的风险。

之前经常使用的加密方式就是MD5,但是现在MD5加密已经不安全,存在破解的可能性,根据等保要求,密码必须使用SM2加密传输。

使用SM2加密的流程如下:

1.生成公私钥,公钥用来加密,私钥用来解密。

        /**
		 * 生成公私钥
		 * @return
		 * @throws Exception
		 */
		public static String[] key() throws Exception{
			String[] key = new String[2];
			X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
			ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
			ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
			keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
			AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

			//私钥
			BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
			String privateKey = privatekey.toString(16);
			key[0] = privateKey;
			//公钥
			ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
			String publicKey = Hex.toHexString(ecPoint.getEncoded(false));
			key[1] = publicKey;
			return key;
		}

2.前端加密,前端加密使用到了两个js文件,crypto-js.js、sm2.js。

使用SM2加密,每次生成的加密串都不一样。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SM2加密</title>
<script src="./js/jquery-2.1.1.js"></script>
<script src="./js/crypto-js.js"></script>
<script src="./js/sm2.js"></script>
<script type="text/javascript">
	//公钥,用来加密
	var pubkeyHex = "041620e22b3389db4ec89233a2cba7f7efed06cea1990e82fe5c27f85d41f1b44802f05b125391663bc9809a2e5bc86444139d1cb15c4939189e6386e6a865a3b5";
	//加密,每次加密得到的加密串都不一样
	function encrypt() {
		var cipher = sm2Encrypt($('#password').val(), pubkeyHex, 0);
		console.log(cipher)
	}
</script>
</head>
<body>
	<input id="password" name="password" type="password" placeholder="请输入密码" />
	<button type="button" id="btn_submit" onclick="encrypt()">
		<span>加密</span>
	</button>
</body>
</html>

3.后台解密,解密需要用到私钥。

需要用的jar包依赖:

        <!-- SM2加密 -->
		<dependency>
		  <groupId>org.bouncycastle</groupId>
		  <artifactId>bcprov-jdk15on</artifactId>
		  <version>1.65</version>
		</dependency>

解密:

package SM2;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Base64;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

public class SM2Utils {
		//私钥,用来解密
		public static String privateKey = "9c3e9ba372448da70b387529acb6f271eb7c25e2e3cca315678c770dcf3b9739";
		
		/**
		 * 解密,如果内容并非使用SM2加密或者加密内容被篡改或者内容是普通内容,解密会异常
		 * @param cipherData
		 * @return
		 */
		public static String decrypt(String cipherData) {
			String clear = "";
			X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
			ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
			byte[] cipherDataByte = Hex.decode(cipherData);

			BigInteger privateKeyD = new BigInteger(privateKey, 16);
			ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

			//用私钥解密
			SM2Engine sm2Engine = new SM2Engine();
			sm2Engine.init(false, privateKeyParameters);

			byte[] arrayOfBytes;
			try {
				arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
				//得到明文
				clear = new String(arrayOfBytes);
			} catch (InvalidCipherTextException e) {
				e.printStackTrace();
			}
			return clear;
		}
		
		/**
		 * 生成公私钥
		 * @return
		 * @throws Exception
		 */
		public static String[] key() throws Exception{
			String[] key = new String[2];
			X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
			ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
			ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
			keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
			AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

			//私钥
			BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
			String privateKey = privatekey.toString(16);
			key[0] = privateKey;
			//公钥
			ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
			String publicKey = Hex.toHexString(ecPoint.getEncoded(false));
			key[1] = publicKey;
			return key;
		}
		
		public static void main(String[] args) {
			//前端加密生成的加密串
			String cipher = "0416ba9b498bad82492503cc60a1b5da67c63e9512c4d54a6a3a567f4a050cf7be3c773503bd048c9050ae7bf3657813a778acd2655c30a45de810e634458ed973142807165d7ecb29ac1c35e4a3f79989c0c3b1b31b188211bd14bf11113bf55898602aa68074c280";
			String clear = SM2Utils.decrypt(cipher);
			System.out.println(clear);
		}
}

所有需要用的前端js文件和后台jar包,以及所有源码,都在这里:SM2加密

### Spring Boot 中实现 SM4 和 SM2 加密传输 #### 后端配置与依赖引入 为了在Spring Boot项目中集成国密标准中的SM4对称加密SM2非对称加密,首先需要添加必要的Maven依赖项。对于SM2加密,可以使用Bouncy Castle库来处理非对称加密需求。 ```xml <dependencies> <!-- BouncyCastle Provider --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> <!-- For additional support with Chinese Cryptography Standard (GM/T) --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency> <!-- Optional: If you need to use a specific library that supports SM4 directly --> <dependency> <groupId>com.github.wujiuye.sm4</groupId> <artifactId>sm4-utils</artifactId> <version>1.0.0</version> </dependency> </dependencies> ``` 上述代码片段展示了如何向`pom.xml`文件中加入支持国密算法所需的第三方库[^2]。 #### 配置安全提供者 为了让JVM识别并加载这些新的加解密服务提供商,在应用程序启动时需注册Bouncy Castle作为默认的安全提供者: ```java import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import java.security.Security; public class Application { static { Security.addProvider(new BouncyCastleProvider()); } public static void main(String[] args){ SpringApplication.run(Application.class, args); } } ``` 这段初始化逻辑确保了后续所有的加密操作都能调用到BC提供的具体实现类上。 #### 使用SM2进行非对称加密/解密 下面是一个简单的例子展示怎样利用SM2完成消息的加密过程以及接收方如何对其进行解码恢复原文本内容: ```java // 假设已经获取到了对方发来的公钥信息(Base64编码) String pubKey = "..."; // 创建Cipher实例指定采用ECIES模式下的SM2算法,并设置为加密工作状态 Cipher cipher = Cipher.getInstance("SM2", "BC"); cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("EC").generatePublic( new X509EncodedKeySpec(Base64.getDecoder().decode(pubKey)))); byte[] encryptedData = cipher.doFinal(plainText.getBytes()); System.out.println("Encrypted Data:" + Base64.getEncoder().encodeToString(encryptedData)); ``` 同样的方式也可以用来执行对应的解密流程,只需要改变传入给`init()`方法的第一个参数值为`DECRYPT_MODE`即可[^4]。 #### 应用SM4对称加密技术保护敏感字段 当涉及到较短的数据单元比如用户的登录密码或者其他个人身份验证资料时,则更适合选用效率更高的分组加密方案——即这里的SM4算法来进行防护措施的设计实施。这里给出一段关于创建随机秘钥并向客户端返回其用于临时会话期间通信保密机制建立的基础框架示意代码: ```java import com.github.wujiuye.utils.SM4Utils; ... // Generate random key for this session String secretKey = RandomStringUtils.randomAlphanumeric(32); try{ // Encrypt data using generated key String ciphertext = SM4Utils.encryptEcbPkcs7(secretKey, originalMessage); }catch(Exception e){ throw new RuntimeException(e.getMessage(),e); } return ResponseEntity.ok(ciphertext); ``` 以上就是有关于如何借助开源工具包的帮助快速搭建起一套基于国密系列协议栈之上的Web Service API接口层面上的信息安全保障体系结构的大致思路概述[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

链诸葛

真爱了。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值