国密算法纯软件实现(java+javascript )

国密算法简介

国密算法是我国自主研发创新的一套数据加密处理系列算法。从SM1-SM4分别实现了对称、非对称、摘要等算法功能。

国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为 128 位。

  • SM1
    对称加密。算法 不公开 ,加密强度与AES相当。调用该算法时,需要通过加密芯片的接口进行调用。目前在软件开发过程中使用较少。
  • SM2
    非对称加密。该算法已公开。算法基于ECC,签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。软件开发过程中应用广泛。
  • SM3
    消息摘要。该算法已公开,校验结果为256位。算法的安全性要高于 MD5 算法和 SHA-1 算法。在报文签名方面应用广泛。
  • SM4
    无线局域网标准的分组数据算法。软件开发领域应用较少。

国密改造

国密改造是相对国际算法来说的。

密码算法是保障信息安全的核心技术,尤其是最关键的银行业核心领域长期以来都是沿用 3DES、SHA-1、RSA 等国际通用的密码算法体系及相关标准。
2010年底,国家密码管理局公布了我国自主研制的“椭圆曲线公钥密码算法”(SM2算法)。为保障重要经济系统密码应用安全,国家密码管理局于2011年发布了《关于做好公钥密码算法升级工作的通知》,要求“自2011年3月1日起,在建和拟建公钥密码基础设施电子认证系统和密钥管理系统应使用国密算法。自2011年7月1日起,投入运行并使用公钥密码的信息系统,应使用SM2算法。”

银行内部大多有成熟厂商提供的硬件加密机完成国密(及国际)算法的加解密过程。加密机作为专业设备,加解密效率高,稳定可靠。
但随着银行向产业生态的拓展,经常遭遇硬件加解密不方便的场景。

java 纯软件实现国密算法

java 开源社区的 bouncycastle 提供了大量的哈希算法和加密算法;hutoolhutool-crypto 模块对加解密方法做了很好的封装,使用起来非常的方便。
本文借助这两个开源库完成相关功能。

引入开源库

如果是使用 maven 管理的项目,引入方式如下:

<dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>${bcprov.version}</version>
    </dependency>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-crypto</artifactId>
        <version>${hutool.version}</version>
    </dependency>
</dependencies>

版本号选择最新即可,如:

<properties>
    <bcprov.version>1.68</bcprov.version>
    <hutool.version>5.6.3</hutool.version>
</properties>

如果不是使用 maven 管理的项目,请自行完成依赖引入。

SM2 加解密

引入上述的 jar 包后, SM2 加密已经变得非常容易。

/**
 * 创建 SM2 公私钥对
 */
private static void createSM2Key() {
    SM2 sm2 = new SM2();
    System.out.println("公钥:" + sm2.getPublicKeyBase64());
    System.out.println("私钥:" + sm2.getPrivateKeyBase64());
}

/**
 * SM2 公钥加密
 *
 * @param publicKey
 * @param plainText
 */

public static String sm2Encrypt(String publicKey, String plainText) {
    System.out.println("SM2 公钥加密");
    System.out.println("明文:" + plainText);
    SM2 sm2 = new SM2(null, publicKey);
    String ciphertext = sm2.encryptBase64(plainText, KeyType.PublicKey);
    System.out.println("密文:" + ciphertext);
    return ciphertext;
}

/**
 * SM2 私钥解密
 *
 * @param privateKey
 * @param ciphertext
 */
public static String sm2Decrypt(String privateKey, String ciphertext) {
    System.out.println("SM2 私钥解密");
    System.out.println("密文:" + ciphertext);
    SM2 sm2 = new SM2(privateKey, null);
    String plainText = sm2.decryptStr(ciphertext, KeyType.PrivateKey);
    System.out.println("明文:" + plainText);
    return plainText;
}

PS: 示例中的公私钥及密文均使用 base64 进行编码。如果有其他编码需求,调用其他方法即可。

SM3 计算摘要

SM3 的使用更加简单。

private static final byte[] SM3_SALT = "AABBCC112233".getBytes();
// SM3 取摘要
SM3 sm3 = new SM3(SM3_SALT);
System.out.println(sm3.digestHex(plainText));

PS:摘要算法的盐值可根据需要自行替换。SM3 亦可计算文件摘要,调用同类其他方法即可。

javascript + java 纯软件实现 SM2 加解密

非对称加解密实际应用场景中最常见的就是用户口令加密。
用户在前端页面(h5+js)输入口令,使用 js 完成口令加密,通过 ajax 请求上送密文至服务端,服务端解密校验后完成用户认证。
具体过程为:

  1. js 使用公钥通过 SM2 算法对口令加密,上送密文至服务端;
  2. 服务端使用私钥通过 SM2 算法对密文解密;
  3. 服务端使用 SM3 算法(或其他不可逆算法)计算摘要与数据库中存储密码进行比对。(原因是数据库不允许存储用户明文密码,一般使用非可逆算法加密后存储)

此时即要求前端加密算法的实现与后端解密算法的实现一致。
在 javascript 中继续使用开源库完成实现 SM2 算法加密,本次使用 crypto-js.js.

引入 js 加密库

根据前端项目的依赖管理方式,自行引入即可。js 源文件可从下文参考链接获取,包含crypto-js.jssm2.js

完成加密

调用 sm2.js 中预置的方法即可完成加密

sm2Encrypt('明文', '公钥', 1);

注意:

  1. 此处为与上一章节 java 实现保持一致,公钥使用 base64 编码。
    在 sm2.js 中完成 base64 编码转换为 Hex 编码。
// base64转Hex,若秘钥是hex格式则无需进行转换
var pubkeyHex = "04"+CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(publickey));

如果使用 Hex 编码秘钥,

var pubkeyHex = publickey;

生成 Hex 编码的java 代码为:

/**
 * 创建 SM2 公私钥对
 */
private static void createSM2KeyForJs() {
    SM2 sm2 = new SM2();
    System.out.println("公钥:" + sm2.getPublicKeyBase64());
    System.out.println("公钥 Hex(用于前端加密):" + Hex.toHexString(sm2.getQ(false)));
    System.out.println("私钥:" + sm2.getPrivateKeyBase64());
}
  1. 此处生成的密文为 Hex 编码。
    如果想要获取 base64 格式的密文,可使用 sm2.js 中的实现。
// 可通过此方法生成 base64 格式的密文,
var encryptDataBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(encryptDataHex));

java 代码进行解密时密文编码为 base64 和 Hex 都支持(解密前判断了编码类型,分别进行解码)。

参考链接

java 代码参考链接 https://github.com/hou-xx/encryption-and-decryptionSmDemo.javaSmDemoForJs.java
前端代码(h5+js)参考链接 https://github.com/hou-xx/SM2-front

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 国密算法:国家密码局认定的国产密码算法,即商用密码。 非对称密码(公钥算法):SM2,SM9 对称密码(分组密码,...
    得奕阅读 2,802评论 0 1
  • 国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。 SM1...
    袋熊饲养员阅读 10,913评论 0 0
  • 国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。SM1 ...
    Li_MAX阅读 27,535评论 2 13
  • IOS应用安全-加解密算法简述 导读客户端经常遇到需要对数据进行加密的情况,那应该如何加密,选用什么样的加密算法,...
    萝卜_7fad阅读 611评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,503评论 28 53