密码技术应用--SM2文件签名验签

Posted Yuan_sr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了密码技术应用--SM2文件签名验签相关的知识,希望对你有一定的参考价值。

记录一下对一些稍大文件进行SM2签名验签的实现,这里只列出了核心代码,其他不涉及的代码或者有任何疑问可以查看我之前写的密码技术专题博客

/*
函数名:    sm2Sign
        sm2 签名算法实现对文件的签名
参 数:
        filePathIn ,     待签名文件
        priKey ,        签名私钥文件
返回值:
        签名后文件名
        错误信息
创建时间及创建者:
        2021-06-17    Yuan_sr
*/
func sm2Sign (filePathIn, priKey string) (string, error){

    //1.打开磁盘的私钥文件
    file, err := os.Open(priKey)
    if err != nil {
        return "", err
    }
    defer file.Close()
    //2.将私钥文件中的内容读出
    fileInfo, err := file.Stat()
    if err != nil {
        return "", err
    }
    buf := make([]byte, fileInfo.Size())
    _, err = file.Read(buf)
    if err != nil {
        return "", err
    }
    //3.将pem格式私钥文件解码并反序列化
    privateKeyFromPem, err := gmx509.ReadPrivateKeyFromPem(buf, nil)
    if err != nil {
        return "", err
    }
    //4.创建一个哈希对象
    hash := sm3.New()

    inFile, err := os.Open(filePathIn)
    if err != nil {
        return "", err
    }
    defer inFile.Close()

    for {
        n, err := inFile.Read(buf)
        if err == io.EOF{
            break
        }
        if err != nil && err != io.EOF {
            return "", err
        }
        _, err = hash.Write(buf[:n])
        if err != nil {
            return "", err
        }
    }
    hashed := hash.Sum(nil)
    //5.签名
    signText, err := privateKeyFromPem.Sign(rand.Reader, hashed, nil)
    if err != nil {
        return "", err
    }

    outFile, err := os.Create(signFileName)
    if err != nil {
        return "", err
    }
    defer outFile.Close()
    outFile.Write(signText)

    return signFileName, nil
}

/*
函数名:    sm2Verify
        sm2 验签算法实现对文件的验签
参 数:
        encFile ,         密文文件
        signFile ,        签名文件
        pubKey ,        验签公钥
返回值:
        验签结果
        错误信息
创建时间及创建者:
        2021-06-17    Yuan_sr
*/
func sm2Verify(encFile, signFile, pubKey string) (bool, error) {

    //1.打开磁盘公钥文件
    file, err := os.Open(pubKey)
    if err != nil {
        return false, err
    }
    defer file.Close()
    fileInfo, err := file.Stat()
    if err != nil {
        return false, err
    }
    buf := make([]byte, fileInfo.Size())
    _, err = file.Read(buf)
    if err != nil {
        return false, err
    }
    //2.将pem格式公钥解码并反序列化
    publicKeyFromPem, err := gmx509.ReadPublicKeyFromPem(buf)
    if err != nil {
        return false, err
    }
    //3.进行哈西运算
    hash := sm3.New()

    inFile, err := os.Open(dvOutPath + encFile)
    if err != nil {
        return false, err
    }
    defer inFile.Close()

    for {
        n, err := inFile.Read(buf)
        if err == io.EOF{
            break
        }
        if err != nil && err != io.EOF {
            return false, err
        }
        _, err = hash.Write(buf[:n])
        if err != nil {
            return false, err
        }
    }
    hashed := hash.Sum(nil)
    //4.读取接受到的签名值
    sr, err := os.Open(dvOutPath + signFile)
    if err != nil {
        return false, err
    }
    defer sr.Close()
    srInfo, err := sr.Stat()
    if err != nil {
        return false, err
    }
    srBuf := make([]byte, srInfo.Size())
    _, err = sr.Read(srBuf)
    if err != nil {
        return false, err
    }

    //5.签名认证
    verify := publicKeyFromPem.Verify(hashed, srBuf)
    return verify, nil
}

以上是关于密码技术应用--SM2文件签名验签的主要内容,如果未能解决你的问题,请参考以下文章

密码学系列 - 国密SM2为什么不支持恢复公钥

密码技术应用--RSA文件签名验签

STM32F103驱动RJMU401实现SM2加解密签名与验签

SM2 国密算法工具QT版,彻底搞懂国密算法的使用

国密算法 SM2 SM3 SM4分别用作什么

区块链与密码学第8-5讲:基于SM2签名算法的环签名