美文网首页
公私钥生成

公私钥生成

作者: 一个摸鱼AI喵 | 来源:发表于2021-10-17 09:30 被阅读0次

一、rsa模块

# -*- coding: utf-8 -*-
import rsa

(pubkey, privkey) = rsa.newkeys(1024)
# 生成公钥
pub = pubkey.save_pkcs1()

pubfile = open('public.pem', 'wb')
pubfile.write(pub)
pubfile.close()

# 生成私钥
pri = privkey.save_pkcs1()
prifile = open('private.pem', 'wb')
prifile.write(pri)
prifile.close()

二、Crypto模块

from Crypto import Random
from Crypto.PublicKey import RSA
def private_public():
 """
 获得公钥与私钥
 param  :无
 return  : 私钥与公钥
 """
 # 生成私钥
 random_generator = Random.new().read
 rsa = RSA.generate(3072, random_generator)
 private_key = rsa.exportKey()  # bytes类型

 # 生成公钥
 public_key = rsa.publickey().exportKey()  #bytes类型
 return private_key.decode('utf-8'), public_key.decode('utf-8')

三、Win64OpenSSL

步骤一:在windows操作系统上安装Win64OpenSSL软件; 步骤二:打开Win64OpenSSL软件,首先生成私钥,命令为:ecparam -genkey -name SM2 -out priv.key;

步骤三:再通过生成的私钥生成公钥,命令为:ec -in priv.key -pubout -out pub.key。

验证SM2生成的公私钥 步骤一:首先创建一个file.txt文件(示例放在公私钥同级目录下);

步骤二:打开Win64OpenSSL软件,首先根据私钥生成签名,命令为:dgst -sign priv.key -sha1 -out sha1_sm2_file.sign file.txt

步骤三:再根据公钥去验证生成的签名,如果公钥和私钥相互匹配,那么生成SM2公私钥成功,命令为:dgst -verify pub.key -sha1 -signature sha1_sm2_file.sign file.txt

OpenSSL> ecparam -genkey -name SM2 -out priv.key
ecparam: Can't open "priv.key" for writing, Permission denied
error in ecparam
OpenSSL> ecparam -genkey -name SM2 -out d:/priv.key
OpenSSL> ec -in d:/priv.key -pubout -out d:/pub.key
read EC key
writing EC key
OpenSSL> dgst -sign d:/priv.key -sha1 -out d:/sha1_sm2_file.sign d:/file.txt
d:/file.txt: No such file or directory
error in dgst
OpenSSL> dgst -sign d:/priv.key -sha1 -out d:/sha1_sm2_file.sign d:/file.txt
OpenSSL> dgst -verify d:/pub.key -sha1 -signature d:/sha1_sm2_file.sign d:/file.txt
Verified OK

文件地址需要修改.上述直接放在d盘中,最后为.key 或者.pem

四、gmssl

Download (GmSSL-master.zip), uncompress it and go to the source code folder. On Linux and OS X, run the following commands:

$ ./config
$ make
$ sudo make install

安装后,输入gmssl version,报错:

gmssl: error ``while` `loading shared libraries: libssl.so.1.1: cannot ``open` `shared object ``file``: No such ``file` `or directory

添加两条软连接:

ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1

生成私钥

$ gmssl sm2 -genkey -out skey.pem

生成公钥

$ gmssl sm2 -pubout -in skey.pem -out vkey.pem

参考(https://github.com/guanzhi/GmSSL)

五、 支付宝开放平台开发助手

image-20210812191252255.png

六、自定义代码

上面生成的公私钥都没法给gmss sm2使用,可以进行加密解密,但是结果是错的

from random import SystemRandom

class CurveFp:
    def __init__(self, A, B, P, N, Gx, Gy, name):
        self.A = A
        self.B = B
        self.P = P
        self.N = N
        self.Gx = Gx
        self.Gy = Gy
        self.name = name

sm2p256v1 = CurveFp(
    name="sm2p256v1",
    A=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC,
    B=0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93,
    P=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF,
    N=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123,
    Gx=0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7,
    Gy=0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
)

def multiply(a, n, N, A, P):
    return fromJacobian(jacobianMultiply(toJacobian(a), n, N, A, P), P)

def add(a, b, A, P):
    return fromJacobian(jacobianAdd(toJacobian(a), toJacobian(b), A, P), P)

def inv(a, n):
    if a == 0:
        return 0
    lm, hm = 1, 0
    low, high = a % n, n
    while low > 1:
        r = high//low
        nm, new = hm-lm*r, high-low*r
        lm, low, hm, high = nm, new, lm, low
    return lm % n

def toJacobian(Xp_Yp):
    Xp, Yp = Xp_Yp
    return (Xp, Yp, 1)

def fromJacobian(Xp_Yp_Zp, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    z = inv(Zp, P)
    return ((Xp * z**2) % P, (Yp * z**3) % P)

def jacobianDouble(Xp_Yp_Zp, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    if not Yp:
        return (0, 0, 0)
    ysq = (Yp ** 2) % P
    S = (4 * Xp * ysq) % P
    M = (3 * Xp ** 2 + A * Zp ** 4) % P
    nx = (M**2 - 2 * S) % P
    ny = (M * (S - nx) - 8 * ysq ** 2) % P
    nz = (2 * Yp * Zp) % P
    return (nx, ny, nz)

def jacobianAdd(Xp_Yp_Zp, Xq_Yq_Zq, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    Xq, Yq, Zq = Xq_Yq_Zq
    if not Yp:
        return (Xq, Yq, Zq)
    if not Yq:
        return (Xp, Yp, Zp)
    U1 = (Xp * Zq ** 2) % P
    U2 = (Xq * Zp ** 2) % P
    S1 = (Yp * Zq ** 3) % P
    S2 = (Yq * Zp ** 3) % P
    if U1 == U2:
        if S1 != S2:
            return (0, 0, 1)
        return jacobianDouble((Xp, Yp, Zp), A, P)
    H = U2 - U1
    R = S2 - S1
    H2 = (H * H) % P
    H3 = (H * H2) % P
    U1H2 = (U1 * H2) % P
    nx = (R ** 2 - H3 - 2 * U1H2) % P
    ny = (R * (U1H2 - nx) - S1 * H3) % P
    nz = (H * Zp * Zq) % P
    return (nx, ny, nz)

def jacobianMultiply(Xp_Yp_Zp, n, N, A, P):
    Xp, Yp, Zp = Xp_Yp_Zp
    if Yp == 0 or n == 0:
        return (0, 0, 1)
    if n == 1:
        return (Xp, Yp, Zp)
    if n < 0 or n >= N:
        return jacobianMultiply((Xp, Yp, Zp), n % N, N, A, P)
    if (n % 2) == 0:
        return jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P)
    if (n % 2) == 1:
        return jacobianAdd(jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P), (Xp, Yp, Zp), A, P)

class PrivateKey:
    def __init__(self, curve=sm2p256v1, secret=None):
        self.curve = curve
        self.secret = secret or SystemRandom().randrange(1, curve.N)

    def publicKey(self):
        curve = self.curve
        xPublicKey, yPublicKey = multiply((curve.Gx, curve.Gy), self.secret, A=curve.A, P=curve.P, N=curve.N)
        return PublicKey(xPublicKey, yPublicKey, curve)

    def toString(self):
        return "{}".format(str(hex(self.secret))[2:].zfill(64))

class PublicKey:
    def __init__(self, x, y, curve):
        self.x = x
        self.y = y
        self.curve = curve

    def toString(self, compressed=True):
        return {
            True:  str(hex(self.x))[2:],
            False: "{}{}".format(str(hex(self.x))[2:].zfill(64), str(hex(self.y))[2:].zfill(64))
        }.get(compressed)

if __name__ == "__main__":
    priKey = PrivateKey()
    pubKey = priKey.publicKey()
    print(priKey.toString())
    print(pubKey.toString(compressed = False))

七、base64转16进制

由于提供的公私钥为base64格式,故要进行转码.

import base64

# base64解码
def base64_decode(base64_data):
    temp = base64.b64decode(base64_data).hex()
    return temp

data = "qgEeAGBFRQAAZEIAAFhCAAAAAAAAE0LFEAVqAAAHZhbn9rs="
tem = base64_decode(data)
print(tem)

四、其他格式互转

# 16进制转bytes
byte_arr = bytes.fromhex("1f2f3f4f")
# bytes转16进制
byte_arr.hex()
# bytes转base64,输入输出都是bytes
import base64
base64.b64encode(byte_arr)
# base64转bytes
base64.b64decode(base64_byte_arr)
# 字符串转bytes
"xxxxx".encode("UTF-8")
bytes(data,encoding='utf-8')
# bytes转字符串
str(data,encoding='utf-8')
data.decode('utf-8')

八、字符串与base64互转

字符串与base64不能直接转,需要先转到bytes

def strToBase64(s):
    '''
    将字符串转换为base64字符串
    :param s:
    :return:
    '''
    strEncode = base64.b64encode(s.encode('utf8'))  # 转为base64, base64也是bytes
    return strEncode.decode("utf")

def base64ToStr(s):
    '''
    将base64字符串转换为字符串
    :param s:
    :return:
    '''
    strDecode = base64.b64decode(bytes(s, encoding="utf8"))

相关文章

网友评论

      本文标题:公私钥生成

      本文链接:https://www.haomeiwen.com/subject/orlonltx.html