8 Go 密码学(五)非对称加密之椭圆曲线算法

一、椭圆曲线概述

椭圆曲线密码学(Elliptic curve cryptography),简称ECC,其和RAS类似属于公开秘钥的加密算法体系。ECC被公认为在给定密钥长度下最安全的加密算法。近年来由于比特币以太币等区块链应用ECC加密算法,业界也普遍看好ECC。

我们说过现代密码学是基于数学难题构建的,如RSA基于大数分解,ECC则基于椭圆曲线的椭圆曲线上的离散对数问题。

椭圆曲线是代数几何中一类重要的曲线,至今已有 100 多年的研究历史。而应用于密码学中的椭圆曲线是基于有限域上的,通过引入无穷远点,将椭圆曲线上的所有点和无穷远点组成一个集合,并在该集合上定义一个运算,从而该集合和运算构成了群。在有限域上的椭圆曲线群有两种,分别基于GF(p)以及GF(2m),它们各自有不同的群元素和群运算,然而对于群上的 ECDLP 问题,都认为是一个指数级的困难问题。基于这个困难问题,构建了ECC算法,包括==公钥加密、私钥解密、数字签名、签名验证、DH交换==等。

二、Go中使用ECDSA数字签名及签名验证

ECDSA 算法是目前使用最为广泛的标准算法,它是以 ECDLP 困难问题为基础,采用ELGamal体制构建的一个签名算法,它包含一个签名算法和一个验证算法。ECDSA算法如下:

首先选择好系统参数,如有限域类型和表示方法,曲线参数a,b,以及一个曲线上的基点G以及G的阶n,要求n必须为一个大素数(相关的系统参数的选择可见文献[23])。

参数确定以后,ECDSA 算法分为如下 3 个模块分别执行不同的功能,即密钥产生模块、数字签名模块以及签名验证模块。另外介绍一个基于ECC的Diffie-Hellman交换型算法以及公钥加密算法。

密钥产生:
1.在区间[1,n−1]上随机产生一个整数d(当然d不能太小)。
2.计算标量乘法Q=dG。
3.公开Q为公钥,保留d为私钥。

数字签名:
1.使用安全散列函数H对需要签名的消息M进行杂凑计算e=H(M)。
2.随机生成一个区间[1,n−1]上的本地秘密随机数k,并计算kG=(x1,y1)。
3.计算r=x1 mod n。
4.计算s=k−1(e+dr)mod n。
5.则数据r||s即为ECDSA算法下对消息M的签名(其中||表示两个比特串的串接)。

签名验证:
1.使用与签名一样的散列算法H计算e=H(M)。
2.计算c=s−1 mod n。
3.计算u1=ec mod n,u2=rc mod n。
4.计算(x1,y1)=u1G+uQ2。
5.计算v=x1mod n。若v=r,则为一个合法签名,否则验证不通过。

DH交换:
1.A随机生成一个区间[1,n−1]上的本地秘密随机数k,计算并发送kG到B。
2.B随机生成一个区间[1,n−1]上的本地秘密随机数l,计算并发送lG到A。
3.最后A计算k(lG)同时B计算l(kG)作为双方的共享密钥。

公钥加密算法:
1.公钥加密:随机生成一个区间[1,n-1]上的本地秘密随机数k,并计算,对需要加密的消息M。计算的密文C=kG||kQ+M(其中+为XOR运算)。
2.私钥解密:M=(kQ+M)−d(kG)。
1.生成密钥对
import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "time"

    "crypto/x509"
    "encoding/pem"
    "errors"
    mathRand "math/rand"
    "os"
    "strings"
)

const (
    PRIVATEFILE = "src/cryptography/myECDSA/privateKey.pem"
    PUBLICFILE  = "src/cryptography/myECDSA/publicKey.pem"
)

//生成指定math/rand字节长度的随机字符串
func GetRandomString(length int) string {
    str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+?=-"
    bytes := []byte(str)
    result := []byte{}

    r := mathRand.New(mathRand.NewSource(time.Now().UnixNano()))
    for i := 0; i < length; i++ {
        result = append(result, bytes[r.Intn(len(bytes))])
    }
    return string(result)
}

//生成ECC算法的公钥和私钥文件
//根据随机字符串生成,randKey至少36位
func GenerateKey(randKey string) error {

    var err error
    var privateKey *ecdsa.PrivateKey
    var publicKey ecdsa.PublicKey
    var curve elliptic.Curve

    //一、生成私钥文件

    //根据随机字符串长度设置curve曲线
    length := len(randKey)
    //elliptic包实现了几条覆盖素数有限域的标准椭圆曲线,Curve代表一个短格式的Weierstrass椭圆曲线,其中a=-3
    if length < 224/8 {
        err = errors.New("私钥长度太短,至少为36位!")
        return err
    }

    if length >= 521/8+8 {
        //长度大于73字节,返回一个实现了P-512的曲线
        curve = elliptic.P521()
    } else if length >= 384/8+8 {
        //长度大于56字节,返回一个实现了P-384的曲线
        curve = elliptic.P384()
    } else if length >= 256/8+8 {
        //长度大于40字节,返回一个实现了P-256的曲线
        curve = elliptic.P256()
    } else if length &g
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值