duanhongyi / gmssl

a python crypto for sm2/sm3/sm4
MIT License
474 stars 139 forks source link

java生成的公私钥与python的有点出入,Python用java的私钥签名后,验签失败 #67

Open sunyb3 opened 1 year ago

sunyb3 commented 1 year ago

java生成的公私钥与python的有点出入,Python用java的私钥签名后,验签失败 java生成的公私钥对: KeyPair keyPair = generateSm2KeyPair(); String pri = java.util.Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); String puk = java.util.Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());

pubKey:MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEtKnAlS64hZCIEpX42KY6VTgHoySczY8ELCHiat7wObuyWAiItnDP9HmPXZiLMzWmeCNlzmZsu/MpVjtLyBRd9Q== priKey:MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQ5HEtGmOW7XrQFYJmBMsu0o1tCkNYvaRhf04vzdYxUugCgYIKoEcz1UBgi2hRANCAAS0qcCVLriFkIgSlfjYpjpVOAejJJzNjwQsIeJq3vA5u7JYCIi2cM/0eY9dmIszNaZ4I2XOZmy78ylWO0vIFF31 (不知道对不对,被网上的教程弄晕了) python 代码:

@staticmethod
def sm2withsm3(sign_data: str):
    """
    此处签名需要公钥
    :param sign_data:
    :param private_key: 私钥
    :param public_key: 公钥
    :return:
    """

    crypt = CryptSM2(private_key=base64.b64decode(sk).decode(),
                     public_key=base64.b64decode(pk).decode())
    random_hex_str = func.random_hex(crypt.para_len)

    sign_str = crypt.sign_with_sm3(sign_data.encode('utf-8'), random_hex_str)
    b64 = base64.b64encode(bytes.fromhex(sign_str)).decode()
    return b64

@staticmethod
def sm2verify(verify_data: str, signature: str):
    """
    :param public_key:
    :param verify_data:
    :param signature:
    :return:
    """
    crypt = CryptSM2(private_key="", public_key=base64.b64decode(pk).decode())
    return crypt.verify_with_sm3(base64.b64decode(signature).hex(), verify_data.encode("utf-8"))
sunyb3 commented 1 year ago

java自己的可以加签验签 image

sunyb3 commented 1 year ago

image java这里去导入私钥的时候用的BC库的base64.decode,Python的实现方式是咋样的?

Davidcheng999817 commented 1 year ago

Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded(false)); String publicKeyHex = Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded(false));

2.1.2 与其他语言的密钥传输编码问题 Java的密钥一般直接使用 PrivateKey.getEncoded() 或者 PublicKey.getEncoded() 获得密钥,然后直接使用Base64或者Hex将密钥转成可见字符串,但是Sm2算法这样保存的密钥其他语言的工具大多数是解析不了的。

参考链接 https://blog.csdn.net/quhan97/article/details/124458753