本文已参与「新人创作礼」活动,一起开启掘金创作之路。
密钥生成
1、生成质数p
p越大,我们的算法就越安全,但是因为数字过大,所以使用big.Int类型。
//调用DSA文件夹中的PrimeCount函数(会有点慢),可以查看上一篇文章
p:=big.NewInt(DSA.PrimeCount(15270644627))
fmt.Println("质数p",p)
//结果
质数p:15270644639
2、p-1的素因子q
我们要计算或者写代码实现q是比较有难度的。 我们就可以使用工具(人和动物最大的区别就是人会使用工具) 网站:分解质因数工具
q:=big.NewInt(449136607)
fmt.Println("素因子q",q)
//结果
素因子q:449136607
3、生成参数h(1. h满足h<p-1,h^((p-1)/q) modp>1;)
我们需要生成一个随机数h 为了更具有个性化,我把hello使用sha256加密,将它密文前几位转换成10进制(使用工具),取前4位作为h
hash:=DSA.Sum256([]byte("hello"))
fmt.Printf("%x\n",hash)
h:=big.NewInt(1164)
4、生成参数g
g = h^((p-1)/q) mod p,h满足h < p - 1, h^((p-1)/q) mod p > 1; 在大数运算中,是不能使用符号的,得调math/big的运算包
// 减法,相当于p-1
g1:=p.Sub(p,big.NewInt(1))
//除法,相当于 g1/q=(p-1)/q
g2:=g1.Div(g1,q)
//幂运算 h^g2= h^((p-1)/q)
g3:=h.Exp(h,g2,nil)
//取余 g3%q=h^((p-1)/q) mod p
g:=g3.Mod(g3,q)
fmt.Println("g:",g)
5、私钥x
私钥x是随机数,只需要x<q
//私钥
//使用math/rand包
rand.Seed(time.Now().UnixNano())
x := big.NewInt(int64(rand.Intn(9999)) )// 生成0~9999的随机数
fmt.Println("私钥x",x)
6、公钥y
y:y=g^x mod p,( p, q, g, y )为公钥
//公钥
g的x次方
y1:= g.Exp(g,x,nil)
//然后取余
y:=y1.Mod(y1,p)
fmt.Println("公钥y",y)
p, q, g可由一组用户共享,但在实际应用中,使用公共模数可能会带来一定的威胁