关于SM2软件加密与硬件加密的问题

ops/2024/10/19 9:31:29/

        SM2国密算法在中国的密码学领域中使用得非常广泛,它是一种基于椭圆曲线公钥密码的算法。日常开发工作中,涉及到SM2算法的加密和解密时,如果一方使用软件实现,而另一方使用硬件实现,可能会遇到一些联调过程中的问题。在SM2的加密和解密过程中,涉及到对ASN.1格式的编码和解码。

当软件加密和硬件加密进行联调时,可能会遇到以下问题:

        1.编码/解码不一致:软件和硬件可能采用不同的ASN.1编码规则或者库来处理ASN.1格式的数据。这可能导致加密后的数据在软件端和硬件端之间无法正确解析。

        2.数据填充和对齐问题:ASN.1编码的数据可能需要特定的填充或对齐方式。软件和硬件在这方面的处理方式如果不一致,也可能导致问题。

为了解决这些问题,可以采取以下措施:

        1.明确接口定义:确保软件和硬件之间的接口定义清晰、一致,并遵循相关的标准和规范。如果可能的话,尽量使软件和硬件使用相同的ASN.1库,以确保编码和解码的一致性。

        2.与硬件厂商沟通:如果问题确实出在硬件端,及时与硬件厂商沟通,寻求技术支持和解决方案。

案例:软件加密(主流开源库bouncycastle)和硬件加密接口对接,运行过程中偶现解密失败问题。接口上送的sm2加密值为硬件加密机加密后的asn1字节数组,应用程序需要将asn1转换原始数据进行解密,偶现错误发生在转换过程中。

        ASN.1(Abstract Syntax Notation One)是一种接口定义语言,用于描述数据结构,被广泛用于密码学标准中。在SM2加密算法中,asn1的数据格式是这样的:

/*** 加密数据的ASN.1 数据结构如下:* CipherData ::= SEQUENCE {* xcoordinate INTEGER,(32)* ycoordinate INTEGER,(32)* hash OCTET STRING,(32)* cigherText OCTET STRING (对应明文字节长度)* }* <p>* C1C3C2格式对应:* c1 = xcoordinate + ycoordinate* c3 = hash;* c2 = cigherText;* <p>* 格式解析如下:* 30 + totalLen  + xTag + xlen + x  + yTag + ylen +y + c3Tag + c3len + c3 + c2Tag + c2len + c2;*/

将asn1字节写入文件,使用asn1工具打开可以看到完整结构:

 asn1字节解析:

0x30:sequence

0x79:总长度totalLen

0x02:x类型标签xTag

0x20:x的长度xlen

0x00~0x92:x的内容

依此类推。。。

 

x分量: 包含标记+长度+内容,0x02表示整数

 y分量:包含标记+长度+内容

 摘要:包含标记+长度+内容,0x04表示String

 密文:包含标记+长度+内容

应用程序中处理asn1数据转原始数据:

        <!--引入开源库 -->        <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency>
    //此方法将asn1格式数据转换为原始数据进行解密 private static byte[] changeAsn1ToC1C3C2(byte[] asn1) {try {ASN1InputStream aIn = new ASN1InputStream(asn1);ASN1Sequence seq = (ASN1Sequence) aIn.readObject();BigInteger x = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();BigInteger y = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();byte[] c3 = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();byte[] c2 = ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets();ECPoint c1Point = GMNamedCurves.getByName("sm2p256v1").getCurve().createPoint(x, y);byte[] c1 = c1Point.getEncoded(false);return ArrayUtil.addAll(c1, c3, c2);} catch (Exception ex) {return null;}}

错误发生位置:

ASN1Sequence seq = (ASN1Sequence) aIn.readObject();

debug进入方法,如果出现无法debug情况,将bouncycastle库下载到本地调试。

bouncycastle库最终异常的位置:ASN1Integer#isMalformed

方案一:屏蔽bc关于大整数的校验,设置系统参数org.bouncycastle.asn1.allow_unsafe_integer为true

    private static byte[] changeAsn1ToC1C3C2(byte[] asn1) {try {//x,y分量补位问题导致的规范性校验不通过,该配置绕过校验逻辑System.setProperty("org.bouncycastle.asn1.allow_unsafe_integer", "true");ASN1InputStream aIn = new ASN1InputStream(asn1);ASN1Sequence seq = (ASN1Sequence) aIn.readObject();BigInteger x = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();BigInteger y = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();byte[] c3 = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();byte[] c2 = ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets();ECPoint c1Point = GMNamedCurves.getByName("sm2p256v1").getCurve().createPoint(x, y);byte[] c1 = c1Point.getEncoded(false);return ArrayUtil.addAll(c1, c3, c2);} catch (Exception ex) {return null;}}

方案二:厂商提供asn1转原始数据方法替换bc库(推荐)

方案三:自行解析

asn1格式解析如下(16进制表示):x、y、c3、c2为内容
30 + totalLen  + xTag + xlen + x  + yTag + ylen +y + c3Tag + c3len + c3 + c2Tag + c2len + c2;

原始数据格式(c1c3c2模式):

04+x+y+c3+c2

 参考:

网联回执报文签名验证和敏感信息解密报错:failed to construct sequence from byte[]: corrupted stream detected [国密SM2]-CSDN博客

https://blog.51cto.com/u_16099268/8806443

关于SM2算法 ASN.1编码 踩过的坑 - 加密_sm2私钥asn.1序列化-CSDN博客

asn.1ber编解码系统与设计asn.1编码规则详解(全面最经典) - 豆丁网


http://www.ppmy.cn/ops/15725.html

相关文章

数据库安全如何保障?YashanDB有妙招(上篇)

数据库作为信息系统的核心&#xff0c;不仅承载着海量的关键数据&#xff0c;还负责向各类用户提供高效、可靠的信息服务&#xff0c;数据库的安全性显得尤为关键&#xff0c;已成为信息安全体系的重中之重。 什么是数据库安全&#xff1f; 数据库安全是数据安全的一个子集&…

大学生在线考试|基于SprinBoot+vue的在线试题库系统系统(源码+数据库+文档)

大学生在线考试目录 基于SprinBootvue的在线试题库系统系统 一、前言 二、系统设计 三、系统功能设计 试卷管理 试题管理 考试管理 错题本 考试记录 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#…

洛谷P1234题解

题目描述 小 A 最近有了一个口头禅 “呵呵”&#xff0c;于是他给出了一个矩形&#xff0c;让你求出里面有几个 “hehe”&#xff08;方向无所谓&#xff09;。 输入格式 第一行两个数 n,m&#xff0c;表示这个矩形的大小。 接下来 n 行&#xff0c;每行 m 个字符&#xff…

cdp集群Hbase组件HRegionServer服务停止原因以及排查

前言&#xff1a;重启集群后某一节点HRegionServer服务停止&#xff0c;重启前所有服务均正常 去查看日志&#xff1a; 日志报错 ERROR HRegionServer Master rejected startup because clock is out of sync org.apache.hadoop.hbase.ClockOutOfSyncException: org.apache.h…

R-tree相关整理

R-tree 是一种用于空间索引的树形数据结构&#xff0c;常用于地理信息系统 (GIS) 和空间数据库中以高效地处理空间查询。R-tree 的基本思想是将空间对象&#xff08;如点、线、多边形等&#xff09;用最小边界矩形 (MBR) 来表示&#xff0c;并在树中按空间位置对这些 MBR 进行层…

未来五十年,智能科技将如何改变传统行业格局?

未来五十年内&#xff0c;随着人工智能&#xff08;AI&#xff09;和智能科技的不断发展&#xff0c;许多行业将面临被取代的风险。虽然这种趋势可能会带来一些担忧&#xff0c;但也将为人类社会带来巨大的变革。下面将详细探讨哪些行业可能会在未来被智能科技所取代。 ▶ 制造…

利用word2vec包将中文转变为词向量

代码展示&#xff1a; import jieba import re import json import logging import sys import gensim.models as word2vec from gensim.models.word2vec import LineSentence, loggerpattern u[\\s\\d,.<>/?:;\\"[\\]{}()\\|~!\t"#$%^&*\\-_a-zA-Z&…

Python打怪升级(4)

在计算机领域常常有说"合法"和"非法"指的是:是否合理&#xff0c;是否有效&#xff0c;并不是指触犯了法律。 random.randint(begin,end) 详细讲解一下这个random是指模板&#xff0c;也就是别人写好的代码直接来用&#xff0c;在Python当中&#xff0c;…