鱼C论坛

 找回密码
 立即注册
查看: 667|回复: 8

[已解决]求助,怎么用Python生成sm2的密钥对

[复制链接]
发表于 2024-1-4 11:06:10 | 显示全部楼层 |阅读模式
25鱼币
求助,怎么生成
private_key = "2B4E468EB817B63B11DDC25A2A403D5EBA4FF50821700D7D1495F01E0A303A05"  # sm2的私钥
public_key = "04E8A2EA10BF81E9533C2CBF86CDA759371F6B557291D595727BFFF601F0A6AA8C65E85BA90980CA1D3668A7FF8B2E07ACC5F90445C6149803D883E632D92137BA"  # sm2的公钥
这种的sm2密钥对呀,私钥可以用func.random_hex(64)来随机生成,但是公钥不知道怎么用私钥计算,网上找了半天,都是看着好像可以执行,实际都是无法生成公钥的,像
# 使用私钥创建 SM2 密码对象
sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
# 生成公钥
public_key = sm2_crypt.export_public_key()  # 这里根本就没有export_public_key()方法

或者

from gmssl import sm2, func


def generate_sm2_key_pair():
    private_key = func.random_hex(64)
    print(private_key)
    sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
    public_key = sm2_crypt.get_pubkey()  # 这里也是没有get_pubkey()方法的

    return private_key, public_key


private_key, public_key = generate_sm2_key_pair()
print(private_key)
print(public_key)



最佳答案
2024-1-4 11:06:11
可以试试:

  1. from gmssl import sm2, func

  2. def generate_sm2_key_pair():
  3.     private_key = func.random_hex(64)
  4.     sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
  5.     public_key = sm2_crypt._kg(int(private_key, 16), sm2.default_ecc_table['g'])
  6.     public_key_str = '04' + ''.join(['{:02x}'.format(x) for x in public_key])

  7.     return private_key, public_key_str

  8. private_key, public_key = generate_sm2_key_pair()
  9. print("私钥:", private_key)
  10. print("公钥:", public_key)
复制代码

首先生成一个随机的64位十六进制私钥,然后通过椭圆曲线算法计算出相应的公钥。

_kg 方法是 CryptSM2 类的内部方法,用于根据私钥和椭圆曲线参数生成公钥。
sm2源码.png

最佳答案

查看完整内容

可以试试: 首先生成一个随机的64位十六进制私钥,然后通过椭圆曲线算法计算出相应的公钥。 _kg 方法是 CryptSM2 类的内部方法,用于根据私钥和椭圆曲线参数生成公钥。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-4 11:06:11 | 显示全部楼层    本楼为最佳答案   
可以试试:

  1. from gmssl import sm2, func

  2. def generate_sm2_key_pair():
  3.     private_key = func.random_hex(64)
  4.     sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
  5.     public_key = sm2_crypt._kg(int(private_key, 16), sm2.default_ecc_table['g'])
  6.     public_key_str = '04' + ''.join(['{:02x}'.format(x) for x in public_key])

  7.     return private_key, public_key_str

  8. private_key, public_key = generate_sm2_key_pair()
  9. print("私钥:", private_key)
  10. print("公钥:", public_key)
复制代码

首先生成一个随机的64位十六进制私钥,然后通过椭圆曲线算法计算出相应的公钥。

_kg 方法是 CryptSM2 类的内部方法,用于根据私钥和椭圆曲线参数生成公钥。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-4 11:06:51 | 显示全部楼层
要使用Python生成SM2的密钥对,可以使用第三方库gmssl中的sm2模块。下面是一个示例代码:

  1. from gmssl import sm2, func

  2. def generate_sm2_key_pair():
  3.     private_key = func.random_hex(64)
  4.     sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
  5.     public_key = sm2_crypt._get_public_key()

  6.     return private_key, public_key

  7. private_key, public_key = generate_sm2_key_pair()
  8. print("私钥: ", private_key)
  9. print("公钥: ", public_key)
复制代码


在这个示例中,我们首先使用`func.random_hex(64)`生成了一个随机的64位私钥。然后,我们创建了一个CryptSM2对象`sm2_crypt`,将私钥传递给它。最后,通过调用`_get_public_key()`方法来获取公钥。

请注意,这里用到的`_get_public_key()`方法是gmssl库中内部的方法,不是公开的API。因此,可能会存在一些风险,gmssl库的版本更新后也可能会发生变化。因此,建议在使用时仔细查阅gmssl的文档,确保代码的可靠性。

希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-1-4 11:10:48 | 显示全部楼层
FishC 发表于 2024-1-4 11:06
要使用Python生成SM2的密钥对,可以使用第三方库gmssl中的sm2模块。下面是一个示例代码:

没有_get_public_key()方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-4 11:10:59 | 显示全部楼层
life我知你心 发表于 2024-01-04 11:10
没有_get_public_key()方法


非常抱歉,我之前的回答有误。确实在gmssl库中,`_get_public_key()`方法并不存在。感谢您的指正。以下是一个修正后的示例代码:

  1. from gmssl import sm2, func

  2. def generate_sm2_key_pair():
  3.     private_key = func.random_hex(32)
  4.     sm2_crypt = sm2.CryptSM2(public_key='', private_key=private_key)
  5.     public_key = sm2_crypt._generate_public_key()

  6.     return private_key, public_key

  7. private_key, public_key = generate_sm2_key_pair()
  8. print("私钥: ", private_key)
  9. print("公钥: ", public_key)
复制代码


在这个示例中,我们使用了`func.random_hex(32)`生成了一个32字节(256位)的随机私钥。然后,我们创建了一个CryptSM2对象`sm2_crypt`并传入了私钥。最后,通过调用`_generate_public_key()`方法来计算公钥。

需要注意的是,`_generate_public_key()`方法同样是gmssl库中的内部方法,可能会存在风险和版本更新的问题。因此,在使用时请谨慎查阅gmssl的文档,并确保代码的可靠性。

希望这次能够解决您的问题!非常抱歉给您带来困扰!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-1-4 17:10:21 | 显示全部楼层
已经自己解决
1.生成随机数d,是一个256位的随机数,表示私钥
2.通过SM2椭圆曲线上的标量乘法运算,计算公钥P=d·G,其中G是椭圆曲线上的一个固定点,称为基点或生成点。
3.这样就得出了私钥和公钥,这时候的公钥需要在前面加上04表示未压缩
Snipaste_2024-01-04_17-10-01.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-4 17:11:24 | 显示全部楼层
life我知你心 发表于 2024-01-04 17:10
已经自己解决
1.生成随机数d,是一个256位的随机数, ...


非常抱歉之前的回答还是有误。下面是修正后的示例代码:

  1. import os
  2. from ecpy.curves import Curve
  3. from ecpy.keys import ECPublicKey, ECPrivateKey

  4. def generate_sm2_key_pair():
  5.     curve = Curve.get_curve('sm2p256v1')  # 使用SM2的p256曲线
  6.     d = os.urandom(32)  # 生成32字节(256位)的随机数作为私钥

  7.     # 计算公钥
  8.     Q = curve.generator * int.from_bytes(d, 'big')  # 标量乘法运算
  9.     public_key = '04' + Q.x.to_bytes(32, 'big').hex() + Q.y.to_bytes(32, 'big').hex()

  10.     return d.hex().upper(), public_key.upper()

  11. private_key, public_key = generate_sm2_key_pair()
  12. print("私钥: ", private_key)
  13. print("公钥: ", public_key)
复制代码


在这个示例中,我们使用了`ecpy`库来进行SM2的密钥对生成。首先,我们选择了SM2的p256曲线。然后,通过使用`os.urandom()`生成32字节的随机数作为私钥。接下来,我们使用标量乘法运算来计算公钥。最后,我们将公钥表示为未压缩格式,即在前面加上`04`。请注意,您需要先安装`ecpy`库,可以使用`pip install ecpy`命令安装。

希望这次能够解决您的问题!再次非常抱歉给您带来困扰!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-1-5 09:23:45 | 显示全部楼层

多谢了,这个问题昨天下午已经自己解决了,和你这个差不多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-5 10:10:47 | 显示全部楼层
life我知你心 发表于 2024-1-5 09:23
多谢了,这个问题昨天下午已经自己解决了,和你这个差不多

解决就好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 13:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表