SM2 implementa el envío de mensajes cifrados desde el front-end y el descifrado de mensajes desde el back-end.

El autor original https://www.cnblogs.com/iroc1994/p/16399496.htmldesea agradecer al autor original
por el registro y el uso de este artículo. Al mismo tiempo, ha realizado ligeras modificaciones. La idea es correcta. El contenido no ha sido verificado. Si tiene alguna pregunta, no dude en libre de corregirlos. ¡Será verificado y modificado más adelante!
ambiente:

En el trabajo, los mensajes enviados por la página de inicio pueden incluir información del usuario. Para garantizar la seguridad de los datos, los datos solicitados deben cifrarse. El uso del cifrado asimétrico SM2 puede resolver eficazmente el problema de seguridad de los datos.

Cifrado de front-end, descifrado de back-end Dirección de descarga del código fuente de demostración

https://gitee.com/iroc-git/springboot-encryptreq.git

Pasos de implementación:

Paso 1: Introduzca las dependencias pom en el proyecto Maven. Tenga en cuenta que la versión del paquete jar dependiente debe ser superior a 1.6. También verifique si hay un paquete jar bcprov-jdk16.*. (normalmente lo habrá), que deba eliminarse ( Si no está preocupado, primero puede hacer una copia de seguridad; de lo contrario, se informarán conflictos y errores.

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.67</version>
</dependency>

Paso 2: generar claves públicas y privadas

HerramientasObtenerPK

package com.iroc.springboot.util;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
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;

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

//获取sm2公钥与私钥
public class GetPKs
{
    
    
    public static void main(String[] args)
    {
    
    
        try
        {
    
    
            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();

            //上面的代码都是直接用maven依赖中的包直接import就可以用了
            //还有一些更底层的写法,可以自己搜索一下,图方便的这个挺好的

            //私钥,16进制格式,自己保存
            BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
            String privateKeyHex = privatekey.toString(16);
            System.out.println("private Key :" + privateKeyHex);

            //公钥,16进制格式,发给前端
            ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
            String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
            System.out.println("Public Key :" + publicKeyHex);
        } catch (Exception e)
        {
    
    
            e.printStackTrace();
        }
    }

}

Después de la ejecución:


private Key :5e3dcfb19758d7829ebce1ee4276f8193951e0cb77040a319403fce5231cab0e
Public Key :045417fe9233682d37355d2f64db75fb6ff1146efb68cf409cdd64bb7e31a448047c337b0edd919501f678181a230d91e621029bc64faf7fca3631ac2c869673b9

Paso 3: cifrar los datos de la solicitud en la página de inicio

1.Introduzca crypto-js.js y sm2.js

Descargue estos dos archivos de github (https://github.com/Saberization/SM2)
y colóquelos en las ubicaciones correspondientes del proyecto
Insertar descripción de la imagen aquí. 2. Cifre el mensaje de solicitud.

//sm2公钥
var pubkeyHex = "045417fe9233682d37355d2f64db75fb6ff1146efb68cf409cdd64bb7e31a448047c337b0edd919501f678181a230d91e621029bc64faf7fca3631ac2c869673b9";
//对请求报文加密
jsonReqParams=sm2Encrypt(jsonReqParams, pubkeyHex, 0);

El código completo de la página de inicio login.html

<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <script src="../js/crypto-js.js"></script>
    <script src="../js/sm2.js"></script>
    <script src="../js/jquery-3.4.1.min.js"></script>
    <script>

        $(document).ready(function () {
    
    
            $("#submit").click(function () {
    
    
                var username = $("#username").val();
                var password = $("#password").val();
                var jsonReqParams = {
    
    

                };
                jsonReqParams.username=username;
                jsonReqParams.password=password;
                jsonReqParams=JSON.stringify(jsonReqParams);
                //sm2公钥
                var pubkeyHex = "045417fe9233682d37355d2f64db75fb6ff1146efb68cf409cdd64bb7e31a448047c337b0edd919501f678181a230d91e621029bc64faf7fca3631ac2c869673b9";
                //对请求报文加密
                jsonReqParams=sm2Encrypt(jsonReqParams, pubkeyHex, 0);
                //发送请求到后端
                $.ajax({
    
    
                    type: 'POST', //方法类型
                    dataType: 'json', //预期服务器返回的数据类型
                    url: '/login', //请求地址
                    data: {
    
     'jsonReqParams': jsonReqParams },
                    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
                    success: function (data) {
    
    
                        if(data.code == "1001"){
    
    
                            $("#result").html("登录成功");
                        }else if(data.code== "1002"){
    
    
                            $("#result").html("登录失败");
                        }else{
    
    
                            $("#result").html("出现异常,请联系管理员");
                        }
                    },
                    error: function () {
    
    
                        $("#result").html("出现异常,请联系管理员");
                    },
                });
            });
        });

    </script>
</head>

<body>

    用户名:<input type="text" id="username" /><br />
    密码:<input type="password" id="password" /><br />
    <button id="submit">登录</button><br />
    <span id="result"></span>

</body>

Paso 4: el backend recibe el mensaje de solicitud del frontend y lo descifra

1.Introduzca la clase de herramienta de descifrado DecryptUtil.java en el backend

package com.iroc.springboot.util;

import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;

//解密前端页面的请求报文
public class DecryptUtil
{
    
    
    public static String decrypt(String cipherData) throws Exception{
    
    
        byte[] cipherDataByte = Hex.decode(cipherData);

        //sm2私钥
        String privateKey = "5e3dcfb19758d7829ebce1ee4276f8193951e0cb77040a319403fce5231cab0e";
        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        X9ECParameters sm2ECParameters1 = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters1 = new ECDomainParameters(sm2ECParameters1.getCurve(), sm2ECParameters1.getG(), sm2ECParameters1.getN());
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters1);

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

        //processBlock得到Base64格式,记得解码
        byte[] arrayOfBytes = Base64.decodeBase64(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));

        //得到明文:SM2 Encryption Test
        String data = new String(arrayOfBytes);
        return data;
    }
}

2. Descifre el mensaje solicitado por el front-end.

package com.iroc.springboot.controller;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.iroc.springboot.util.DecryptUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class LoginController
{
    
    

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @ResponseBody
    public String login(@RequestParam(value = "jsonReqParams") String jsonReqParams){
    
    
        JsonObject result = new JsonObject();
        //设数据库中username为zhangsan,password为123456
        try
        {
    
    
            //解密前端请求的报文
            jsonReqParams = DecryptUtil.decrypt(jsonReqParams);
            JsonObject jsonObject = new JsonParser().parse(jsonReqParams).getAsJsonObject();
            String username = jsonObject.get("username").getAsString();
            String password = jsonObject.get("password").getAsString();
            if("zhangsan".equals(username)&&"123456".equals(password)){
    
    
                result.addProperty("code","1001");
                result.addProperty("desc","登录成功");
            }else {
    
    
                result.addProperty("code","1002");
                result.addProperty("desc","账号或密码有误");
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
            result.addProperty("code","1003");
            result.addProperty("desc","出现异常,请联系管理员");
        }

        return result.toString();
    }

}

Artículo de referencia

  1. https://blog.csdn.net/python_small_pan/article/details/120064529

  2. https://github.com/Saberization/SM2

  3. https://blog.51cto.com/boytnt/2503384

Supongo que te gusta

Origin blog.csdn.net/m0_46364149/article/details/125885586
Recomendado
Clasificación