SM? SM1? SM2? SM3? SM4?
最近看了一个项目的代码,用到了SM2,SM3,SM4
,瞬间懵逼,一会用SM2
,一会用SM3
,一会又用SM4
,SM
???
简单来说,SM2,SM3,SM4
是国家密码局认定的国产密码算法,当然除了这几个算法,还有SM1,SM7,SM9,祖冲之密码算法
等。
本文重点是SM
算法的Java
实现,并不是研究这几种算法的原理以及和其他算法的比较等。
这里简单介绍下这几种SM算法,先有个大概的印象:
SM1
它是一种对称加密算法
中的分组加密算法,分组长度、秘钥长度都是128位,和国际上通用的 AES, DES
一样,SM1 算法目前还没公开,只能集成在芯片中。
SM2
和国际上通过的RSA
一样,是一种非对称加密算法
,使用公钥加密,私钥解密,在安全性和运算速度方面要优于RSA算法。
SM3
可以用来生成信息摘要,如MD5,生成的信息摘要长度为256位。
SM4
是一种对称加密算法
,可用于替代DES/AES
等国际算法, SM4算法与AES算法具有相同的密钥长度和分组长度,都是128位。
当然这些算法的源码可以在商用密码检测中心
中下载,我已经下载好了,公众号回复【SM】即可下载。
了解了SM2, SM3, SM4
这些算法之后,在我们的系统中就可以应用这些算法来对传输的报文进行加解密;一个简单的流程图如下所示:
SM2
下面将来重点介绍SM2算法
SM2
算法是国家密码管理局发布的椭圆曲线公钥密码算法,推荐使用素数域256位椭圆曲线
。
椭圆曲线方程:曲线参数为:如果你数学够屌,文档给你准备好了,公众号回复【SM】即可下载。
SM2 java实现
既然SM2算法那么厉害,接下来我们就使用Java来实现下吧。
首先在项目中引入对应的jar包:
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.60</version>
</dependency>
首先第一步,是要创建 SM2 的椭圆曲线参数,用到的类为 「SM2P256V1Curve」,它是代表国密SM2推荐参数定义的椭圆曲线,源码如下:可以看到和上面所提供的推荐参数是一样的。
由于「SM2P256V1Curve」没有实现Gx 和 Gy,即基点G的x,y坐标,我们需要自行创建,参数为推荐的参数即可,然后使用x,y 坐标创建基点G,代码如下:第一步创建 SM2 的椭圆曲线参数的代码如下:第二步,由于SM2算法基于 ECC,所以需要根据曲线参数来生成 ECC密钥对,代码如下:第三步,通过 ECC 密钥对获取SM2公钥和私钥,代码如下:
第四步,获取到公钥之后,就可以使用公钥对报文进行加密了,代码如下:第五步,加密之后,需要使用私钥来进行解密,代码如下:第六步,现在来测试一下吧。运行结果如下:
到这里使用Java来实现SM2加解密算法已经结束了,是不是很简单,你学废了吗?
完成代码如下:
生成SM2公私钥:
private static Map<String, ECKeyParameters> getSm2PrivateKeyOrPublicKey() {// P256V1Curve 代表国密SM2推荐参数定义的椭圆曲线:SM2P256V1Curve sm2P256V1Curve = new SM2P256V1Curve();BigInteger sm2N = sm2P256V1Curve.getOrder();BigInteger sm2H = sm2P256V1Curve.getCofactor();// 由于 gx,gy 没有提供,需要自己创建默认参数BigInteger sm2Gx = new BigInteger("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16);BigInteger sm2Gy = new BigInteger("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16);// 根据 gx, gy 坐标创建一个 G点,即为椭圆的基点ECPoint sm2Gpoint = sm2P256V1Curve.createPoint(sm2Gx, sm2Gy);//设置椭圆曲线参数ECDomainParameters ecDomainParameters = new ECDomainParameters(sm2P256V1Curve, sm2Gpoint, sm2N, sm2H);// 生成ECC密钥对ECKeyGenerationParameters keyGenerationParameters = new ECKeyGenerationParameters(ecDomainParameters, new SecureRandom());ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();keyPairGenerator.init(keyGenerationParameters);// ECC密钥对AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();// 通过 ECC 密钥对获取SM2公钥和私钥// 私钥ECPrivateKeyParameters sm2PrivateKey = (ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate();String x = ByteUtils.toHexString(sm2PrivateKey.getParameters().getG().getAffineXCoord().getEncoded());String y = ByteUtils.toHexString(sm2PrivateKey.getParameters().getG().getAffineYCoord().getEncoded());System.out.println("生成的SM2私钥为:" + x + "-" + y);// 公钥ECPublicKeyParameters sm2PublicKey = (ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic();String x1 = ByteUtils.toHexString(sm2PublicKey.getQ().getAffineYCoord().getEncoded());String y1 = ByteUtils.toHexString(sm2PublicKey.getQ().getAffineXCoord().getEncoded());System.out.println("生成的SM2公钥为:" + x1 + "-" + y1);Map<String, ECKeyParameters> map = new HashMap<>(2);map.put("private", sm2PrivateKey);map.put("public", sm2PublicKey);return map;
}
加密:
/*** 公钥加密** @param sm2PublicKey SM2 公钥* @param pack 加密的报文* @return 加密后的保温* @throws Exception e*/
private static String sm2Encrypt(ECPublicKeyParameters sm2PublicKey, String pack) throws Exception {SM2Engine sm2PublicEngine = new SM2Engine();ParametersWithRandom withRandom = new ParametersWithRandom(sm2PublicKey, new SecureRandom());sm2PublicEngine.init(true, withRandom);byte[] encryResult = sm2PublicEngine.processBlock(pack.getBytes(StandardCharsets.UTF_8), 0, pack.getBytes(StandardCharsets.UTF_8).length);String encryResultStr = Base64.getEncoder().encodeToString(encryResult);System.out.println("加密后的报文为:" + encryResultStr);return encryResultStr;
}
解密:
/*** SM2 私钥解密** @param sm2PrivateKey SM2 私钥* @param pack 解密报文* @throws Exception e*/
private static void sm2Decrypt(ECPrivateKeyParameters sm2PrivateKey, String pack) throws Exception {SM2Engine sm2PrivateEngine = new SM2Engine();sm2PrivateEngine.init(false, sm2PrivateKey);byte[] decodePackByte = Base64.getDecoder().decode(pack);byte[] decryptResult = sm2PrivateEngine.processBlock(decodePackByte, 0, decodePackByte.length);String decryptResultStr = new String(decryptResult, StandardCharsets.UTF_8);System.out.println("解密后的报文为:" + decryptResultStr);
}
测试:
static {Security.addProvider(new BouncyCastleProvider());
}public static void main(String[] args) throws Exception {Map<String, ECKeyParameters> sm2Key = getSm2PrivateKeyOrPublicKey();String pack = "公众号搜索【Java技术编程】, 公众号搜索【Java技术编程】, 公众号搜索【Java技术编程】";System.out.println("原始报文为:" + pack);// 对报文进行加密String encryResult = sm2Encrypt((ECPublicKeyParameters) sm2Key.get("public"), pack);// 对报文进行解密sm2Decrypt((ECPrivateKeyParameters) sm2Key.get("private"), encryResult);
}
SM3 Java 实现
下一篇,敬请期待。
SM4 Java 实现
下下一篇,敬请期待。
SM? SM1? SM2? SM3? SM4?相关推荐
- 国密SM1\ SM2\ SM3\ SM4\ SSF33算法和国际RSA算法的对应关系
转载自https://blog.csdn.net/hcnetbee/article/details/53692579,部分内容和排版稍作修改. 国密算法由国家密码局发布,包含SM1\ SM2\ SM3 ...
- 国密算法SM1/SM2/SM3/SM4
原创不易,转载请注明出处. 国密算法由国家密码局发布,今天大概介绍4中国密算法,分别是SM1,SM2,SM3,SM4.他们之间异同通过下表展示. 算法名称 算法分类 算法是否公开 明文最大长度(bit ...
- 爬虫逆向基础,认识 SM1/SM2/SM3/SM4/SM7/SM9/ZUC 国密算法
文章目录 [01x00] 简介 [02x00]算法概述 [03x00]算法详解 [03x01]SM1 分组加密算法 [03x02]SM2 椭圆曲线公钥加密算法 [03x03]SM3 杂凑算法 [03x ...
- SM1 SM2 SM3 SM4加密算法
2010 年开始,我国国家密码管理局就已经开始陆续发布了一系列国产加密算法,这其中就包括 SM1.SM2.SM3 .SM4.SM7.SM9.ZUC(祖冲之加密算法)等,SM 代表商密,即商业密码,是指 ...
- 国密算法(SM1,SM2,SM3,SM4)和国际算法对应关系
加密领域主要有国际算法和国密算法两种体系.国密算法是国家密码局认定的国产密码算法.国际算法是由美国安全局发布的算法.由于国密算法安全性高等一系列原因.国内的银行和支付机构都推荐使用国密算法. 国密与国 ...
- php gmssl,支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱GmSSL
GmSSL概述 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码 ...
- OpenSSL 1.1.1 新特性: 全面支持国密SM2/SM3/SM4加密算法
OpenSSL项目最近6个月添加了许多新特性, 包括对中国SM2/SM3/SM4算法的支持: SM2椭圆曲线: https://github.com/openssl/openssl/pull/4793 ...
- 国密算法 SM2 SM3 SM4 及密钥生成
国密算法 SM2 SM3 SM4 方式一:SM2密钥在线生成 SM2密钥在线生成工具 如果你没线下生成工具,可用下面2种线上生成方式之一: 1. sm2密钥在线生成(const.net.cn) 2. ...
- 国密 sm2,sm3,sm4 算法纯 JavaScript 实现
2014 年国务院办公厅就颁发了<国务院办公厅转发密码局等部门关于金融领域密码应用指导意见>,指出在我国涉及到金融领域信息安全的产品和系统要自主可控,在金融领域使用国产加密标准是机构走向合 ...
最新文章
- TypeMock是很不错的模拟测试框架
- linux 天堂测试软件,[Ubuntu] HTTP Live Streaming 安装测试
- 八个JS中你见过的类型。
- TK:绘制BoundaryEdges边界边用法实战
- python朴素贝叶斯_Python实现的朴素贝叶斯分类器示例
- Html.BeginForm() vs Ajax.BeginForm() in MVC3
- mysql周报内容范文_Mysql各种报表查询含实例,日报,周报,月报,时间差自动计算...
- 计算机科学家和心理学家合作,生物智能与人工智能之间的合作
- 利用VB2005制作颜色渐变的进度条
- java int转byte_JAVA中怎么将int数据转换为byte数据?
- 改变一个ppt所有的幻灯片的背景色和字体颜色
- 冒险岛 PHP,php基础知识
- 怎么可以优化网站的打开速度?
- 微信电子健康卡开放平台接口对接
- Mac删除已卸载软件残留启动台的图标
- android mysql 驱动_Java-使用com.mysql.jdbc.Driver的Android MySQL
- 【转】TOEFL写作27分完全攻略
- springcloud.3.服务注册与发现
- 如何通过接口获取商品详情
- ROC和AUC指标的理解