hutool国密sm2算法使用, 正确的秘钥生成签名及验签,签名为64字节

hutool工具类:

在糊涂提供的国密算法,需要通过椭圆曲线生成秘钥,且当前业内私钥长度为固定32字节,公用固定长度为64字节。在参考hutool官方文档中的国密算法的例子,发现生成的秘钥非常长,远大于32字节和64字节,生成的签名长度也不是64字节。

问题描述:

官方提供如下例子,用于演示签名和验签

String content = "我是Hanley.";
KeyPair pair = SecureUtil.generateKeyPair("SM2");
final SM2 sm2 = new SM2(pair.getPrivate(), pair.getPublic());
byte[] sign = sm2.sign(content.getBytes());
// true
boolean verify = sm2.verify(content.getBytes(), sign);

此例子可以跑通,但是有以下几个问题:

  1. 生成的公钥和私钥都非常长,远大于上文说的私钥长度为固定32字节,公钥长度为64字节
  2. 没有给出通过制定的公钥或者私钥来进行单独的验签和签名

官方提供如下例子,用于演示椭圆曲线生成秘钥

String privateKeyHex = "FAB8BBE670FAE338C9E9382B9FB6485225C11A3ECB84C938F10F20A93B6215F0";
String x = "9EF573019D9A03B16B0BE44FC8A5B4E8E098F56034C97B312282DD0B4810AFC3";
String y = "CC759673ED0FC9B9DC7E6FA38F0E2B121E02654BF37EA6B63FAF2A0D6013EADF";// 数据和ID此处使用16进制表示
String dataHex = "434477813974bf58f94bcf760833c2b40f77a5fc360485b0b9ed1bd9682edb45";
String idHex = "31323334353637383132333435363738";final SM2 sm2 = new SM2(privateKeyHex, x, y);
final String sign = sm2.signHex(data, id);
// true
boolean verify = sm2.verifyHex(data, sign)

这个例子完全跑不通,变量名都是错的
存在如下问题:

  1. 没有指出如何设置椭圆曲线及秘钥对生成
  2. 没有给出通过制定的公钥或者私钥来进行单独的验签和签名
  3. 生成的签名长度不为64字节
  4. 在提供的验证的链接里,这个例子验签不过。验证链接

解决方案:

hutool其实已经引用了国密库,并写好了推荐的椭圆曲线参数,代码如下:

推荐椭圆曲线参数默认sm2也是采用此参数生成。分析源码发现,真正对sm2算法操作的为类cn.hutool.crypto.asymmetric.SM2,此类默认配置如下
sm2默认配置此配置不满足业内要求,具体如下:

  1. 模式需要为C1C2C3
  2. 生成的签名为明文(具体转换类为org.bouncycastle.crypto.signers.PlainDSAEncoding

明白了其真正干活的类,则直接用sm2这个类

1.引入依赖

        <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.66</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.10</version></dependency>

2.创建秘钥对

    /*** 创建sm2测试* <i scr="https://i.goto327.top/CryptTools/SM2.aspx?tdsourcetag=s_pctim_aiomsg">秘钥验证</i>*/@Testpublic void createSm2KeyTest() {//需要加密的明文String text = "我是一段测试aaaa";//创建sm2 对象SM2 sm2 = SmUtil.sm2();//这里会自动生成对应的随机秘钥对 , 注意! 这里一定要强转,才能得到对应有效的秘钥信息byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());//这里公钥不压缩  公钥的第一个字节用于表示是否压缩  可以不要byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);//这里得到的 压缩后的公钥   ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(true);// byte[] publicKeyEc = BCUtil.encodeECPublicKey(sm2.getPublicKey());//打印当前的公私秘钥System.out.println("私钥: " + HexUtil.encodeHexStr(privateKey));System.out.println("公钥: " + HexUtil.encodeHexStr(publicKey));//得到明文对应的字节数组byte[] dateBytes = text.getBytes();System.out.println("数据: " + HexUtil.encodeHexStr(dateBytes));//这里需要手动设置,sm2 对象的默认值与我们期望的不一致sm2.setMode(SM2Engine.Mode.C1C2C3);sm2.setEncoding(new PlainDSAEncoding());//计算签名byte[] sign = sm2.sign(dateBytes, null);System.out.println("签名: " + HexUtil.encodeHexStr(sign));// 校验  验签boolean verify = sm2.verify(dateBytes, sign);System.out.println(verify);}

此方法会创建满足要求的公私钥对,且生成的签名也为64字节,用上面的验证链接,验证也为正常。生成如下打印信息

私钥: 1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e
公钥: 04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d7253763
数据: e68891e698afe4b880e6aeb5e6b58be8af9561616161
签名: 7f4434d553e20a63ae56b762b210608b1fa1117a2dd04f3abe9007a7545968161bd1e51c8686d11bee55b1c5ea571899db98417389bc89693f0b392eba4da1e4
true

注意!! 公钥生成为65个字节,其中第一个字节表示压缩用的,可以删除,即为64字节。在验证链接中,页面上输入的公钥X为公钥的前32字节,页面上输入的公钥Y为公钥的后32字节如果不知道怎么填可以把私钥输入,点击页面上的通过私钥生成公钥也是一样的。

3.通过指定的私钥进行签名

当实际开发中,我们是生成了一对公私钥就会保存起来,当需要签名的时候也只是用私钥对明文数据进行签名。具体代码如下:

    /*** 指定私钥签名测试* <i scr="https://i.goto327.top/CryptTools/SM2.aspx?tdsourcetag=s_pctim_aiomsg">秘钥验证</i>*/@Testpublic void signTest() {//指定的私钥String privateKeyHex = "1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e";//需要加密的明文,得到明文对应的字节数组byte[] dataBytes = "我是一段测试aaaa".getBytes();ECPrivateKeyParameters privateKeyParameters = BCUtil.toSm2Params(privateKeyHex);//创建sm2 对象SM2 sm2 = new SM2(privateKeyParameters, null);//这里需要手动设置,sm2 对象的默认值与我们期望的不一致 , 使用明文编码sm2.usePlainEncoding();sm2.setMode(SM2Engine.Mode.C1C2C3);byte[] sign = sm2.sign(dataBytes, null);System.out.println("数据: " + HexUtil.encodeHexStr(dataBytes));System.out.println("签名: " + HexUtil.encodeHexStr(sign));}

4.通过指定的公钥对数据进行验签

  /*** 指定私钥签名测试* <i scr="https://i.goto327.top/CryptTools/SM2.aspx?tdsourcetag=s_pctim_aiomsg">秘钥验证</i>*/@Testpublic void verifyTest() {//指定的公钥String publicKeyHex = "04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d7253763";//需要加密的明文,得到明文对应的字节数组byte[] dataBytes = "我是一段测试aaaa".getBytes();//签名值String signHex = "2881346e038d2ed706ccdd025f2b1dafa7377d5cf090134b98756fafe084dddbcdba0ab00b5348ed48025195af3f1dda29e819bb66aa9d4d088050ff148482a1";//这里需要根据公钥的长度进行加工if (publicKeyHex.length() == 130) {//这里需要去掉开始第一个字节 第一个字节表示标记publicKeyHex = publicKeyHex.substring(2);}String xhex = publicKeyHex.substring(0, 64);String yhex = publicKeyHex.substring(64, 128);ECPublicKeyParameters ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex);//创建sm2 对象SM2 sm2 = new SM2(null, ecPublicKeyParameters);//这里需要手动设置,sm2 对象的默认值与我们期望的不一致 , 使用明文编码sm2.usePlainEncoding();sm2.setMode(SM2Engine.Mode.C1C2C3);boolean verify = sm2.verify(dataBytes, HexUtil.decodeHex(signHex));System.out.println("数据: " + HexUtil.encodeHexStr(dataBytes));System.out.println("验签结果: " + verify);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/71322.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通信加密和解密,公钥,私钥,CA

监听模式&#xff1a;打开&#xff49;&#xff50;和端口&#xff1d;套接字 等待别人来连接 为众所周知的服务&#xff0d;&#xff0d;固定的端口&#xff1c;&#xff11;&#xff10;&#xff12;&#xff14; 客户端程序都是打开一个大于&#xff14;&#xff10;&#…

如何用Rdkit计算MACCS密钥以及每个指纹位点代表什么

1.MACCS密钥是什么 MACCS&#xff08;分子访问系统&#xff09;键是最常用的结构键之一&#xff0c;有时也被称为 MDL 密钥&#xff0c;MDL来源于开发它的公司的名称&#xff08;MDL 信息系统&#xff0c;现为 BIOVIA&#xff09;。 虽然有两组 MACCS 密钥&#xff08;一组包含…

5分钟让你知道什么是PKI 密钥

译者博客 原文出处 前言 Public Key Infrastructure&#xff08;PKI)&#xff0c;中文叫做公开密钥基础设施&#xff0c;也就是利用公开密钥机制建立起来的基础设施。但是如果这么解释起来&#xff0c;到底是个什么东西&#xff0c;大家想必是没办法理解的。 现在大家的很多重要…

公钥、密钥和数字证书

转自 我理解的数字证书-1-公钥&#xff0c;私钥和数字证书 英文原文地址&#xff1a; http://www.youdzone.com/signature.html 若下文有任何错误&#xff0c;请告知我&#xff0c;谢谢。79996286qq.com 主角介绍&#xff1a;Bob and Alice 提起RSA加密算法&#xff0c;公…

一文看懂公钥、私钥、数字签名、数字证书

好文章&#xff0c;记录下来&#xff01;源文地址&#xff1a;What is a Digital Signature? (youdzone.com) 1. 鲍勃有两把钥匙&#xff0c;一把是公钥&#xff0c;另一把是私钥。 2. 鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。 3. 苏珊要给鲍勃写一封保密…

密钥对,密钥,公钥,私钥的 区分!!!

密钥对&#xff0c;密钥&#xff0c;公钥&#xff0c;私钥的区分&#xff1a; 一、概念 1、密钥对&#xff1a;在非对称加密技术中&#xff0c;有两种密钥&#xff0c;分为公钥和私钥。 公钥是密钥对所有者持有&#xff0c;公布给他人的&#xff1b;私钥也是密钥对所有者持有…

数字签名是什么?公钥和私钥是什么

数字签名是什么&#xff1f;公钥和私钥是什么 数字签名 这里参考阮一峰的数字签名解释&#xff0c;详细 请看: 数字签名是什么&#xff1f; - 阮一峰的网络日志 1.鲍勃有两把钥匙&#xff0c;一把是公钥&#xff0c;另一把是私钥。 2.鲍勃把公钥送给他的朋友们----帕蒂、道格…

公钥,私钥和数字签名这样最好理解

一、公钥加密 假设一下&#xff0c;我找了两个数字&#xff0c;一个是1&#xff0c;一个是2。我喜欢2这个数字&#xff0c;就保留起来&#xff0c;不告诉你们(私钥&#xff09;&#xff0c;然后我告诉大家&#xff0c;1是我的公钥。 我有一个文件&#xff0c;不能让别人看&…

告别晦涩难懂的物理,《张朝阳的物理课》了解一下

马斯克的飞船和我国神舟十二号的速度和运行状态是怎样的&#xff1f;如何用能量守恒定律解释台球撞击问题&#xff1f;朝霞晚霞的颜色又是怎么回事&#xff1f;细究这些日常&#xff0c;大多数人心里充满大大的问号。可能在高中学过这些知识&#xff0c;但现在都还给了老师&…

张朝阳:走出焦虑,不再焦虑

在前不久的乌镇互联网大会上&#xff0c;张朝阳和丁磊坐在步步莲花咖啡馆外有一个长聊&#xff0c;其间&#xff0c;马云、周鸿祎和张平安也有加入&#xff0c;他们聊了大学的时光、金庸的江湖、永生的2029&#xff0c;也有互联网行业。跟正襟危坐的沙龙不同&#xff0c;大佬们…

张朝阳的物理课:他现在真的很快乐

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 没想到我这辈子还能听到麻省理工大学毕业的博士的课。张朝阳这快60岁了&#xff0c;还能把物理课程记得这么清楚&#xff0c;不愧是麻省理工的博士。 最近看到搜狐的张朝阳在讲顶尖的物理课&#…

Android Studio源码学习记录_01

一、HashMap<String, String> /* * HashMap:是基于哈希表的Map接口实现。 * 哈希表的作用是用来保证键的唯一性的。 * * HashMap<String,String> * 键&#xff1a;String * 值&#xff1a;String */ package cn.itcast_02;import java.util.HashMap; impor…

张朝阳不再狂妄,搜狐的艰难复苏路

来源&#xff5c;连线Insight 作者&#xff5c;王古锋 编辑&#xff5c;子夜 “我曾经什么都拥有&#xff0c;当时站在世界的中心&#xff0c;有名有钱很狂妄。现在已经没有在舞台中心的感觉了。现在我要做一个好的管理者&#xff0c;把一个企业做扎实。”近期&#xff0c;搜狐…

谁是下一个向海龙?

https://www.toutiao.com/a6693147614591844876/ 2019-05-21 00:31:07 5月17日&#xff0c;百度发布了2019Q1财报&#xff0c;百度自2005年上市以来出现首个季度亏损&#xff0c;这也让百度重臣向海龙的离职和百度前COO陆奇的离开一样&#xff0c;具有欲说还休的悲壮色彩。 19…

世界互联网大会前夜:丁磊马云雷军周鸿祎张朝阳等亮相,将会探讨什么?

关注网易智能&#xff0c;聚焦AI大事件&#xff0c;读懂下一个大时代&#xff01; 11月6日晚间&#xff0c;小桥流水&#xff0c;华灯初上&#xff0c;丁磊、马云、雷军、程维、张一鸣、张朝阳、周鸿祎等大佬纷纷亮相乌镇。在众多媒体的关注下&#xff0c;各位大佬悉数到场&…

张朝阳留不住的人

文|熔财经 作者|Alex Chiang &#xff08;封面图&#xff09; 张朝阳&#xff0c;再一次站上了风口浪尖。 “我每天只睡四个小时&#xff0c;并且已经坚持三年多了”&#xff0c;张朝阳在接受一次采访时如是说道&#xff0c;这番与时代多少有些格格不入的话语&#xff0c;在…

颠覆者-读周鸿祎新书

周鸿祎一直是我喜欢的偶像&#xff0c;他身上所体现出来的程序员改变世界、产品经理的执着与见解&#xff0c;还有对互联网的热爱和折腾一直给予我力量。之前读过一本老周的书《我的互联网方法论》&#xff0c;里面讲述了他对互联网的一些核心思想&#xff0c;还有常见的一些方…

破圈的《张朝阳的物理课》,开启“知识突围”的搜狐视频

在互联网耕耘二十多年的搜狐&#xff0c;正在焕发出新的活力。 从搜狐最近公布的2022年第三季度财报来看&#xff0c;营收1.85亿美元&#xff0c;其中在线游戏业务实现收入1.49亿美元&#xff0c;广告收入环比增长3%达到2600万美元。同时&#xff0c;净亏损好于此前预期。 对…

张朝阳的心境,搜狐的武器

乌镇互联网大会第六年&#xff0c;张朝阳连续几年参加&#xff0c;而今天又可以新的角度去写张朝阳&#xff0c;剖析搜狐。 心情&#xff1a;他乡遇故知 刚抵达乌镇放下行李&#xff0c;张朝阳就拿起手机做起直播&#xff0c;站在乌镇小桥上&#xff0c;向网友直播小桥流水。…

张朝阳夜跑33公里:直播聊物理 揭示“超级月亮”成因

雷递网 乐天 7月15日报道 7月13日晚&#xff0c;伴着本年度最大的“超级月亮”亮相夜空&#xff0c;搜狐创始人、董事局主席兼CEO张朝阳夜跑33KM&#xff0c;用脚步丈量北京二环&#xff0c;同时一边跑步一边聊物理&#xff0c;再次创新知识科普直播的新场景。本次夜跑活动持续…