内容简介:数字签名就是只有消息的发送者才能产生的别人无法伪造的一段数字串,这段数字串是对信息真实性的有效证明。非对称加密中,
介绍
数字签名就是只有消息的发送者才能产生的别人无法伪造的一段数字串,这段数字串是对信息真实性的有效证明。
- 发送者:生成签名
- 接受者:验证签名
非对称密码机制
非对称加密中, 公钥用于加密,私钥用于解密
。数字签名中相反, 私钥生成签名,公钥验证签名
。
数字签名方法
直接对消息签名
对消息的散列值签名
先用单向散列函数求出消息的散列值,然后再将散列值进行加密。
数字签名算法
RSA
案例一
package main import ( "crypto/rsa" "crypto/rand" "fmt" "crypto/md5" "encoding/base64" "crypto" ) //用公钥加密,私钥解密 //用私钥签名,公钥验证 //公钥是公开的,任何人可以使用公钥,私钥非公开(保存好) //一,编程实现,公钥加密,私钥解密的过程 func crypt() { //创建私钥 priv, _ := rsa.GenerateKey(rand.Reader, 1024) fmt.Println("输出系统自动产生的私钥", priv) //创建公钥 pub := priv.PublicKey //准备加密的明文 org := []byte("hello kongyixueyuan") //公钥加密 cipherTxt, _ := rsa.EncryptOAEP(md5.New(), rand.Reader, &pub, org, nil) //打印密文 fmt.Println("密文为:", cipherTxt) fmt.Println("密文为:", base64.StdEncoding.EncodeToString(cipherTxt)) //用私钥解密 plaintext, _ := rsa.DecryptOAEP(md5.New(), rand.Reader, priv, cipherTxt, nil) //打印解密后的结果 fmt.Println("明文为:", string(plaintext)) } //二,编程实现,私钥签名,公钥验证的过程 func sign() { //创建私钥 priv, _ := rsa.GenerateKey(rand.Reader, 1024) //创建公钥 pub := &priv.PublicKey plaintxt := []byte("zhaoyingkui") //实现hash散列 h := md5.New() h.Write(plaintxt) hashed := h.Sum(nil) //通过RSA实现数字签名 //数组签名的作用为验证是否被篡改,A->B,当B收到数据时,验证是否由A传递的消息 opts := rsa.PSSOptions{rsa.PSSSaltLengthAuto, crypto.MD5} sig, _ := rsa.SignPSS(rand.Reader, priv, crypto.MD5, hashed, &opts) fmt.Println("签名的结果为", sig) //通过公钥实现验证签名 err := rsa.VerifyPSS(pub, crypto.MD5, hashed, sig, &opts) if err == nil { fmt.Println("验证成功") } } func main() { //crypt() sign() }
案例二
server.go
package main import ( "net" "fmt" "encoding/pem" "crypto/x509" "crypto/rsa" "crypto/md5" "crypto" ) //接收网络传送过来的数据 //公钥验签 var publicKey = []byte(` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyOnQ8Dbm1/UIkmSfeMKd K1LRJGX7T18vjZ7P4w3f/Jft/LKCwkxyC2H7x03An+EdHP7dreRhNytzbQaseIgH EYjFapaCEz+JpMNm+qY4ZpApzvPvqm/tut4T1J0HG33iiBqnyMJRZg8LjUXV2tEw fnHm5yCX36kOkN/YCW7ZbeO6aqw7gMyvJDiLGIYgCy2Daqe1MH1RP91djrt6tWcf qVmUR+HxvJFkvUZZHqFUUZyJefNcY7JQDLSz5F22VB7ZLd9sSX38My353pNy4D19 yeo5/54Z5AbSeRUMYJSFFbxwJzfewyVq2nV7EUJEj7lk0NmksB+S6w1a+a8cWydJ /QIDAQAB -----END PUBLIC KEY----- `) func Recive() []byte { netListen, _ := net.Listen("tcp", "127.0.0.1:1234") defer netListen.Close() //监听端口,并接收数据 for { conn, _ := netListen.Accept() //设置接收数据的内存缓存 data := make([]byte, 2048) for { n, _ := conn.Read(data) //返回接收的数据 return data[:n] } } } func main() { //fmt.Println(Recive()) //获得接收到的数据 data := Recive() //拆分数据 plaintxt := data[:11] fmt.Println("接收的名文为", string(plaintxt)) //获得接收到的数据中的数字签名的结果 sig := data[11:] //通过公钥做验证 block, _ := pem.Decode(publicKey) pubInterface, _ := x509.ParsePKIXPublicKey(block.Bytes) pub := pubInterface.(*rsa.PublicKey) //验证发送方是否为zhaoyingkui h := md5.New() h.Write([]byte(plaintxt)) hashed := h.Sum(nil) e := rsa.VerifyPSS(pub, crypto.MD5, hashed, sig, nil) if e == nil { fmt.Println("接受数据成功,数据确实是",string(plaintxt)) } }
client.go
package main import ( "crypto/md5" "encoding/pem" "crypto/x509" "crypto/rsa" "crypto" "crypto/rand" "net" "fmt" ) //发送消息,需要对数据进行签名 //私钥做签名 var privateKey = []byte(` -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAyOnQ8Dbm1/UIkmSfeMKdK1LRJGX7T18vjZ7P4w3f/Jft/LKC wkxyC2H7x03An+EdHP7dreRhNytzbQaseIgHEYjFapaCEz+JpMNm+qY4ZpApzvPv qm/tut4T1J0HG33iiBqnyMJRZg8LjUXV2tEwfnHm5yCX36kOkN/YCW7ZbeO6aqw7 gMyvJDiLGIYgCy2Daqe1MH1RP91djrt6tWcfqVmUR+HxvJFkvUZZHqFUUZyJefNc Y7JQDLSz5F22VB7ZLd9sSX38My353pNy4D19yeo5/54Z5AbSeRUMYJSFFbxwJzfe wyVq2nV7EUJEj7lk0NmksB+S6w1a+a8cWydJ/QIDAQABAoIBAAQo+z+OE3eTRksp tDee5/w2qcf0KKD7GpP3HtzXs7SaPL5Hv/df99iOfdUhogRtd9na2SI5oV2wE6LF SZrxThwp1dSgKy9U2HfF6AL2oCJXh9YWLPc9fBGreYOkgLosAB3LV4ALrf3L//Q7 5vKx9CwaFarhfOOPr5KGYAXJ+syQqi3CjQrPGTLsoyYPB5oc5CA45eHIctoS90M3 cCRb5pu8vlbmeMUh9G9GMdjD3zuefndOBnwcpErLf2xPuM/Qav9LI7bP25UaZe1u zuTm93AjAtjS9zTvyqbVx/xq7C+LA4EaEeBzxNuUPHAGEhuf4kQGOPl48XKM3aNk lc/UoUECgYEA5vTg6lJKkyHvA5JJvOLSRqrGd220TvO0EPmdp3PUGSFWdldC1ev1 M42f8tbzBBeQJlIMBTeGi5Sa8QRVVZXWYmjKkcpDreZJCKz4dVPyeg93MRUhDA7J 8+2GSypKO+MpTty3WY7y0K0Lyk7381to7QTfqXzMc1d/Q/W2rqdrITECgYEA3rL3 4EzaxisRG9yaxu1ndGFcaTX9JUm+RTDPd5wecfE2mrSqfWwcXjsJ/BOqim1pwPQe 1/7e6PwyPqqd9It+E5f3zLwN5fvHISSjawU+sCLgpPY4YQvybf2cLsfyQrIQw1Ig 4Mo+DTBp4EAGYLszn/8yk7A6PIkev/+W22s1oo0CgYEArYriGpC9QrOj4t4glFMn yDv4p7MCYrUS4BKA2VvaywtW6dOGADKubA+GWbYUo0WFZpYOPDlN20JN7r7f1FC1 6Axv8n62vkwlIuS+SYNL11YZrQMAcwwFykn3uDFN2JRH7N9C0oPshssQ6fLOs8lD HZ6k5blF84GSuqE+pRxeDnECgYAagUJvN7ZyD34hysfBFVBS0aOmAf73CSfUJFMM 8U/OT98n2ojQFKXrsSsnDVAm2Y7UoDlri7IMGLgCLVxPVqrSuiuL+nXNAYJZt3qb qiwj2oLSH1vmcP2RibWk+7chqP/Fv2iaWHe6KiDvx676pE0opb7nRPopakh2oXz1 8I+ZoQKBgDR/aXBDXcDzHC4dM3dYzkSf0bn8LXyANkEjHovSH/QSs4m+d2BkGlSy yB3kgNSnEa9vNoffQcRvRlQbS58zTF8Z4iGjnoCHS6Q2yJBFm9L+EaRJlF6tOERk ngLn8mAtV/IGigWBpZCVeEIHH1nG1DLatF2VDCQifQXZ5oRcZZr6 -----END RSA PRIVATE KEY----- `) func SignData(msg string) []byte { //准备签名的数据 plaintxt:=[]byte(msg) h:=md5.New() h.Write(plaintxt) hashed:=h.Sum(nil) fmt.Println(hashed) //将字节数组转换成私钥类型 block,_:=pem.Decode(privateKey) priv,_:=x509.ParsePKCS1PrivateKey(block.Bytes) //签名 opts:=&rsa.PSSOptions{rsa.PSSSaltLengthAuto,crypto.MD5} sig,_:=rsa.SignPSS(rand.Reader,priv,crypto.MD5,hashed,opts) //返回签名结果 return sig } //通过TCP将数据和签名结果发送给接收端 func Send(data []byte) { conn,_:=net.ResolveTCPAddr("tcp4","127.0.0.1:1234") n,_:=net.DialTCP("tcp",nil,conn) //将数据通过tcp协议发送给接收方 n.Write(data) fmt.Println("发送结束") } func main() { //获得签名的结果 var dt = "hello world" sg:=SignData(dt) //dt是准发送出去的数据 var data = make([]byte,len(dt)+len(sg)) copy(data[0:11],[]byte(dt)) copy(data[11:],sg) //data数组其实有两部分组成,发出去的数据+签名结果 Send(data) }
DSA
ECDSA
一种利用椭圆曲线密码来实现的数字签名算法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 写给开发人员的实用密码学:数字签名
- [原]数字签名
- 数字签名与HTTPS详解
- 对称加密,非对称加密,数字签名,数字证书,SSL握手
- 详解国密 SM2 的数字签名
- 非对称加密 Rsa 数字签名 Go 实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。