最近看了一个项目的代码,用到了SM2,SM3,SM4,瞬间懵逼,一会用SM2,一会用SM3,一会又用SM4SM???

简单来说,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?相关推荐

  1. 国密SM1\ SM2\ SM3\ SM4\ SSF33算法和国际RSA算法的对应关系

    转载自https://blog.csdn.net/hcnetbee/article/details/53692579,部分内容和排版稍作修改. 国密算法由国家密码局发布,包含SM1\ SM2\ SM3 ...

  2. 国密算法SM1/SM2/SM3/SM4

    原创不易,转载请注明出处. 国密算法由国家密码局发布,今天大概介绍4中国密算法,分别是SM1,SM2,SM3,SM4.他们之间异同通过下表展示. 算法名称 算法分类 算法是否公开 明文最大长度(bit ...

  3. 爬虫逆向基础,认识 SM1/SM2/SM3/SM4/SM7/SM9/ZUC 国密算法

    文章目录 [01x00] 简介 [02x00]算法概述 [03x00]算法详解 [03x01]SM1 分组加密算法 [03x02]SM2 椭圆曲线公钥加密算法 [03x03]SM3 杂凑算法 [03x ...

  4. SM1 SM2 SM3 SM4加密算法

    2010 年开始,我国国家密码管理局就已经开始陆续发布了一系列国产加密算法,这其中就包括 SM1.SM2.SM3 .SM4.SM7.SM9.ZUC(祖冲之加密算法)等,SM 代表商密,即商业密码,是指 ...

  5. 国密算法(SM1,SM2,SM3,SM4)和国际算法对应关系

    加密领域主要有国际算法和国密算法两种体系.国密算法是国家密码局认定的国产密码算法.国际算法是由美国安全局发布的算法.由于国密算法安全性高等一系列原因.国内的银行和支付机构都推荐使用国密算法. 国密与国 ...

  6. php gmssl,支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱GmSSL

    GmSSL概述 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码 ...

  7. OpenSSL 1.1.1 新特性: 全面支持国密SM2/SM3/SM4加密算法

    OpenSSL项目最近6个月添加了许多新特性, 包括对中国SM2/SM3/SM4算法的支持: SM2椭圆曲线: https://github.com/openssl/openssl/pull/4793 ...

  8. 国密算法 SM2 SM3 SM4 及密钥生成

    国密算法 SM2 SM3 SM4 方式一:SM2密钥在线生成 SM2密钥在线生成工具 如果你没线下生成工具,可用下面2种线上生成方式之一: 1. sm2密钥在线生成(const.net.cn) 2.  ...

  9. 国密 sm2,sm3,sm4 算法纯 JavaScript 实现

    2014 年国务院办公厅就颁发了<国务院办公厅转发密码局等部门关于金融领域密码应用指导意见>,指出在我国涉及到金融领域信息安全的产品和系统要自主可控,在金融领域使用国产加密标准是机构走向合 ...

最新文章

  1. TypeMock是很不错的模拟测试框架
  2. linux 天堂测试软件,[Ubuntu] HTTP Live Streaming 安装测试
  3. 八个JS中你见过的类型。
  4. TK:绘制BoundaryEdges边界边用法实战
  5. python朴素贝叶斯_Python实现的朴素贝叶斯分类器示例
  6. Html.BeginForm() vs Ajax.BeginForm() in MVC3
  7. mysql周报内容范文_Mysql各种报表查询含实例,日报,周报,月报,时间差自动计算...
  8. 计算机科学家和心理学家合作,生物智能与人工智能之间的合作
  9. 利用VB2005制作颜色渐变的进度条
  10. java int转byte_JAVA中怎么将int数据转换为byte数据?
  11. 改变一个ppt所有的幻灯片的背景色和字体颜色
  12. 冒险岛 PHP,php基础知识
  13. 怎么可以优化网站的打开速度?
  14. 微信电子健康卡开放平台接口对接
  15. Mac删除已卸载软件残留启动台的图标
  16. android mysql 驱动_Java-使用com.mysql.jdbc.Driver的Android MySQL
  17. 【转】TOEFL写作27分完全攻略
  18. springcloud.3.服务注册与发现
  19. 如何通过接口获取商品详情
  20. ROC和AUC指标的理解

热门文章

  1. 专业的进销存财务软件卓越精算
  2. 设计数据库的画图软件
  3. ChatGPT是如何一本正经地胡说八道的?
  4. Go语言学习笔记十一--面向接口-接口的定义与实现
  5. 售价40万,年租金500的房子值得投资不?
  6. 几款好用的大数据报表工具
  7. python中import re_python之re模块
  8. 一. 安装工具 - Crow
  9. 流媒体中国(liumeiti.com)专访我公司总经理
  10. 健身管理系统 -捷径说懂数据会营销的健身房会员管理软件