Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sm2算法的优化以及新规定的迭代 #3630

Open
CherryRum opened this issue Jun 25, 2024 · 19 comments
Open

sm2算法的优化以及新规定的迭代 #3630

CherryRum opened this issue Jun 25, 2024 · 19 comments
Assignees

Comments

@CherryRum
Copy link
Collaborator

参考文档

GMT 0009-2012.pdf
GMT 0009-2023.pdf

@CherryRum CherryRum self-assigned this Jun 25, 2024
@looly
Copy link
Member

looly commented Jun 26, 2024

@CherryRum 你要自己实现么,哈哈

@CherryRum
Copy link
Collaborator Author

看看有啥问题 哈哈,明确下文档

@cxhello
Copy link

cxhello commented Jul 3, 2024

    public KeyInfo generate() {
        KeyPair keyPair = SecureUtil.generateKeyPair("SM2");
        // 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.setPublicKeyStr(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        keyInfo.setPrivateKeyStr(Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        return keyInfo;
    }
image

最近在对接国密,想咨询下hutool生成的国密密钥对的私钥算法标识符是使用的1.2.840.10045.2.1ANSI X9.62 国际标准吗?

在使用openssl如下命令生成的国密密钥对的私钥算法标识符是使用的1.2.156.10197.1.301中国国家商用密码标准。因为也是第一次接触,客户要求使用国密,我理解这两种都是ECC(椭圆曲线密码学)的实现,请教下用哪一种更符合所谓国密的规范呢?

openssl ecparam -genkey -name SM2 -out "sm2PrivateKey.pem"

image

@looly
Copy link
Member

looly commented Jul 3, 2024

@cxhello 密钥格式的问题。

Hutool中使用密钥支持:

私钥:支持D值、PKCS#8、PKCS#1
公钥:支持Q值、X.509、PKCS#1

密钥标识符使用的是:1.2.156.10197.1.301

见:

image

@cxhello
Copy link

cxhello commented Jul 3, 2024

@looly 您说的密钥格式的问题,是指的我使用openssl命令不对是吗?

@looly
Copy link
Member

looly commented Jul 3, 2024

@cxhello 我意思是国密的Oid是固定的,只是密钥存储的格式不同。

如果在使用中有问题,可以附上测试的密钥,我这边回复。

@cxhello
Copy link

cxhello commented Jul 3, 2024

test.zip

证书解析网址:https://lapo.it/asn1js

image

压缩包里面有公私钥和证书,我使用证书解析网址解析出来看到OID使用的是1.2.840.10045.2.1,parameters是1.2.156.10197.1.301,导致我们在前端使用js解密有问题,所以想请教下。😂

@looly
Copy link
Member

looly commented Jul 3, 2024

@cxhello Java生成的密钥确实不是Asni格式,是pkcs8和x509。

现在Hutool只能保证js生成的密钥可以用,但是Java生成的密钥没法在js中使用。

@cxhello
Copy link

cxhello commented Jul 3, 2024

好的,我自己再研究下。

@CherryRum
Copy link
Collaborator Author

@cxhello
看下这个cxhello
你的意思是想直接在两方用ans.1编码的吗

您的问题是一个历史遗留问题
您解析证书时看到的OID 1.2.840.10045.2.1(是因为该证书使用了OpenSSL 1.x版本的实现。在OpenSSL 1.x版本中,SM2算法的公钥被错误地标识为标准的EC公钥(OID: 1.2.840.10045.2.1),而不是国密标准中定义的SM2算法的OID(1.2.156.10197.1.301sm2p256v1。这导致了与国密标准的不一致。

建议您使用OpenSSL 3.x版本。OpenSSL 3.x版本中,SM2公钥密码算法已经使用了正确的OID 1.2.156.10197.1.301(参见《GB/T 33560-2017 信息安全技术 密码应用标识规范》附录A)。虽然这一更改可能导致一些后向兼容性问题,但这是为了遵循最新的国密标准,并解决之前版本存在的标准落后于实践的问题。

#http://gmssl.org/docs/oid.html

@cxhello
Copy link

cxhello commented Jul 3, 2024

您解析证书时看到的OID 1.2.840.10045.2.1(是因为该证书使用了OpenSSL 1.x版本的实现。在OpenSSL 1.x版本中,SM2算法的公钥被错误地标识为标准的EC公钥(OID: 1.2.840.10045.2.1),而不是国密标准中定义的SM2算法的OID(1.2.156.10197.1.301)sm2p256v1。这导致了与国密标准的不一致。

@CherryRum 其实我想表达的是 我使用的hutool-5.7.22版本,生成的公私钥OID也是:1.2.840.10045.2.1,是需要更新版本吗?😂

@CherryRum
Copy link
Collaborator Author

那我建议您先升级版本吧,这个虽然不错,但是不符合现有的文档定义的曲线,虽然说这俩oid的椭圆曲线是一样的(没记错的话)

@cxhello
Copy link

cxhello commented Jul 3, 2024

@CherryRum 我们需要给客户演示的时候在他们的环境使用openss命令生成,所以如果客户的环境上使用openssl 1.x 其实没什么问题。我刚刚测试了,可以正常加解密了。

image

感谢大佬说的这个历史遗留问题。还有个问题想问下,hutool升级到5.8.29 OID就是1.2.156.10197.1.301了吗?

我是在我电脑上使用openssl生成公私钥发现这个问题的,我电脑上openssl版本是3.2.0。所以前端在使用私钥解密的时候报错了,前端用的应该也恰好是以前的库。😂

image

@looly
Copy link
Member

looly commented Jul 3, 2024

确实没注意,我想新版本要做下更新了。

@changhr2013
Copy link
Contributor

changhr2013 commented Jul 12, 2024

这其实是个算法的归类问题,取决于 SM2 是应该属于 EC 算法的一条曲线,还是应该与 EC 并列的算法。

我觉得业界一直是认为 SM2 就是一条特殊的 EC 曲线,所以一开始大家都是按照 EC 的标准去走的,包括 《GM/T 0015-2012 基于SM2密码算法的数字证书格式规范》 在附录中给出的示例,也是使用 1.2.840.10045.2.1 作为算法 Oid 的。

image

OpenSSL 团队在升级 3.0 时,也解释了他们最初这样做的原因,他们团队内部当时认为应该将 SM2 算法视为一种独立的算法,所以他们参考了《GM/T 0006-2012 密码应用标识规范》给出的 Oid 来标识 SM2 算法。

image

这造成了很大的混乱,我觉得既然 GM/T 0015 已经给出了明确的参考示例,那么正如 OpenSSL 开发人员在 Issue 中说的:『如果有一个标准规定应该以特定的方式进行编码,那么我们就不能以不同的方式进行编码』。


PS: 不过我觉得这个事情大概率还是 0015 制定者的锅,因为在 GM/T 0015 标准的附录表格中是这样描述的:

image

可以明确看到 algorithm 部分给的值是 1.2.156.10197.1.301parameters 部分标记的是:『当使用 SM2 密码算法时,为 SM2 密码算法曲线的 OID』。

但是到下面附录的示例又变成了上面贴图的那样,大家实现的时候即使有疑问,也肯定会优先去符合标准示例

这特么找谁说理去。


再提一嘴,目前所有的国密基础设施都是按照示例走的,所以在实际编码中,使用 1.2.840.10045.2.1 才是正解,会避免 N 多兼容性问题。

@cxhello
Copy link

cxhello commented Jul 12, 2024

@changhr2013

我公司 arm kylin v10 的服务器上 openssl 版本是 1.1.1f,生成的国密公私钥OID就是1.2.156.10197.1.301,可是坑了我一把。😂

@wolf-hunter404
Copy link

@changhr2013

我公司 arm kylin v10 的服务器上 openssl 版本是 1.1.1f,生成的国密公私钥OID就是1.2.156.10197.1.301,可是坑了我一把。😂

这个算是个bug,升级到openssl最新版本就能解决。
相关issue在这里,有过不少讨论
openssl/openssl#20973

@CherryRum
Copy link
Collaborator Author

@changhr2013
我公司 arm kylin v10 的服务器上 openssl 版本是 1.1.1f,生成的国密公私钥OID就是1.2.156.10197.1.301,可是坑了我一把。😂

这个算是个bug,升级到openssl最新版本就能解决。 相关issue在这里,有过不少讨论 openssl/openssl#20973

也不算是bug吧,上面我引用了很多,其中就有这个,只是标准太模糊了

@looly
Copy link
Member

looly commented Sep 8, 2024

新的参考:https://www.cnblogs.com/yang37/p/16636435.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants