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

20 篇文章 0 订阅

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

之前经常使用的加密方式就是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加密

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

链诸葛

真爱了。

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

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

打赏作者

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

抵扣说明:

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

余额充值