sm2 js加密,java服务器端解密

有些敏感数据,为了保证数据的安全传输,在向浏览器发送的时刻就要被加密,例如密码,但是密码一般是不可逆的,服务器不需要解密它,直接存储即可。所以密码一般是使用md5或sha 哈希一下直接存到数据库了。但是有些是需要服务器重新解密的,比如手机号,身份证号等。客户端加密之后,需要服务器解密出来才可以。如果使用对称算法,那么对称密钥也会泄漏,所以可以使用非对称算法,rsa或sm2,而目前大多数系统都要求使用国密的sm2非对称算法。

前端的sm2加密操作,可以参考这个项目:https://gitee.com/wgslucky/SM2

服务器端解密操作:

复制代码
public static String decrypt(String cipherData, String privateKey) throws InvalidCipherTextException {
        byte[] cipherDataByte = Hex.decode(cipherData);
        // 刚才的私钥Hex,先还原私钥
        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters =
            new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        // 用私钥解密,这里的Model要与客户端的保持一致。
        SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C2C3);

        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;
    }

需要注意的是,这里面使用公钥,私钥参数都是十六进制的字段串,可以使用下面的方法生成一对十六进制的密钥对:

复制代码
    public static void createKey() throws NoSuchAlgorithmException {
        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();

        // 私钥,16进制格式,自己保存,格式如a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853
        BigInteger privatekey = ((ECPrivateKeyParameters)asymmetricCipherKeyPair.getPrivate()).getD();
        String privateKeyHex = privatekey.toString(16);
        System.out.println(privateKeyHex);
        System.out.println("------------------");
        // 公钥,16进制格式,发给前端,格式如04813d4d97ad31bd9d18d785f337f683233099d5abed09cb397152d50ac28cc0ba43711960e811d90453db5f5a9518d660858a8d0c57e359a8bf83427760ebcbba
        ECPoint ecPoint = ((ECPublicKeyParameters)asymmetricCipherKeyPair.getPublic()).getQ();
        String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
        System.out.println(publicKeyHex);
    }

这样就可以直接实现sm2 js加密,java服务器端解密了,不过这只是针对小数据而已,如果数据量比较大,建议采用对称算法 + sm2非对称算法联合的方法,使用对称算法加密数据,而使用sm2加密对称算法的密钥。因为sm2的公钥是公开的,只有私钥可以解密,所以是安全的。

相关推荐
峥嵘life5 小时前
Android16 311Y3 EAP-TLS 网络连接失败分析与修复总结
android·开发语言·人工智能·php
M-Robots echo5 小时前
轻量化裁剪方案解析:M-Robots 模块化构建,适配高低端各类机器人硬件平台
java·机器人·ros·开源社区·atomgit·m-robots
不可求~6 小时前
多模型路由怎么落地:把任务分流写进项目的最小实现
java·前端·数据库
mldong6 小时前
用 DDD 设计工作流引擎:聚合根与充血模型
java·架构
mqiqe7 小时前
AgentScope Java Harness:4. 双层记忆系统 让 Agent 拥有真正的“长期大脑“
java·开发语言
伍一517 小时前
03-文件管理模块-一个看似简单的模块藏着多少细节
java·ruoyi·若依
gugucoding8 小时前
46. 【Java】JUC并发工具:让并发更简单
java·开发语言
Nebula_g8 小时前
JavaSE基础语法:面向对象高级(代码中的成分)
java·开发语言·编程·javase·技术栈·高级语法
for_ever_love__8 小时前
python基础语法学习: 异常的传递性
开发语言·python·学习
AC赳赳老秦9 小时前
公开图片 OCR 数据提取:OpenClaw 合规采集公开信息图,识别文字与表格并转化为结构化数据
java·大数据·前端·数据库·python·php·openclaw