introduce
Digital signature is a digital string that can not be forged by others only by the sender of the message. This digital string is an effective proof of the authenticity of the information.
- Sender: generate signature
- Recipient: verify signature
Asymmetric cryptography
In asymmetric encryption, the public key is used for encryption and the private key is used for decryption. In digital signature, on the contrary, private key generates signature and public key verifies signature.
Digital signature method
Sign message directly
Hash value signature for message
First, the hash value of the message is calculated by the one-way hash function, and then the hash value is encrypted.
Digital signature algorithm
RSA
Case 1
package main import ( "crypto/rsa" "crypto/rand" "fmt" "crypto/md5" "encoding/base64" "crypto" ) //Encrypt with public key and decrypt with private key //Sign with private key and verify with public key //Public key is public, anyone can use public key, private key is not public (save well) //I. programming, public key encryption and private key decryption func crypt() { //Create a private key priv, _ := rsa.GenerateKey(rand.Reader, 1024) fmt.Println("Output the private key automatically generated by the system", priv) //Create public key pub := priv.PublicKey //Prepare encrypted clear text org := []byte("hello kongyixueyuan") //Public key encryption cipherTxt, _ := rsa.EncryptOAEP(md5.New(), rand.Reader, &pub, org, nil) //Print ciphertext fmt.Println("The ciphertext is:", cipherTxt) fmt.Println("The ciphertext is:", base64.StdEncoding.EncodeToString(cipherTxt)) //Decrypt with private key plaintext, _ := rsa.DecryptOAEP(md5.New(), rand.Reader, priv, cipherTxt, nil) //Print decrypted results fmt.Println("Plaintext is:", string(plaintext)) } //2. Programming implementation, private key signature and public key verification func sign() { //Create a private key priv, _ := rsa.GenerateKey(rand.Reader, 1024) //Create public key pub := &priv.PublicKey plaintxt := []byte("zhaoyingkui") //Implement hash hash h := md5.New() h.Write(plaintxt) hashed := h.Sum(nil) //Digital signature via RSA //The function of array signature is to verify whether it has been tampered with. A - > B. when B receives data, it verifies whether the message passed by a is verified opts := rsa.PSSOptions{rsa.PSSSaltLengthAuto, crypto.MD5} sig, _ := rsa.SignPSS(rand.Reader, priv, crypto.MD5, hashed, &opts) fmt.Println("The result of signing is", sig) //Verify signature by public key err := rsa.VerifyPSS(pub, crypto.MD5, hashed, sig, &opts) if err == nil { fmt.Println("Verify success") } } func main() { //crypt() sign() }
Case two
server.go
package main import ( "net" "fmt" "encoding/pem" "crypto/x509" "crypto/rsa" "crypto/md5" "crypto" ) //Receive data from the network //Public key verification 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() //Listen to the port and receive data for { conn, _ := netListen.Accept() //Set the memory cache for receiving data data := make([]byte, 2048) for { n, _ := conn.Read(data) //Return received data return data[:n] } } } func main() { //fmt.Println(Recive()) //Get received data data := Recive() //Split data plaintxt := data[:11] fmt.Println("Name text received is", string(plaintxt)) //Get the result of the digital signature in the received data sig := data[11:] //Verify with public key block, _ := pem.Decode(publicKey) pubInterface, _ := x509.ParsePKIXPublicKey(block.Bytes) pub := pubInterface.(*rsa.PublicKey) //Verify that the sender is 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("Accept data successfully, data is indeed",string(plaintxt)) } }
client.go
package main import ( "crypto/md5" "encoding/pem" "crypto/x509" "crypto/rsa" "crypto" "crypto/rand" "net" "fmt" ) //To send a message, you need to sign the data //Private key for signature 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 { //Prepare signed data plaintxt:=[]byte(msg) h:=md5.New() h.Write(plaintxt) hashed:=h.Sum(nil) fmt.Println(hashed) //Convert byte array to private key type block,_:=pem.Decode(privateKey) priv,_:=x509.ParsePKCS1PrivateKey(block.Bytes) //autograph opts:=&rsa.PSSOptions{rsa.PSSSaltLengthAuto,crypto.MD5} sig,_:=rsa.SignPSS(rand.Reader,priv,crypto.MD5,hashed,opts) //Return signature result return sig } //Send data and signature results to the receiver through TCP func Send(data []byte) { conn,_:=net.ResolveTCPAddr("tcp4","127.0.0.1:1234") n,_:=net.DialTCP("tcp",nil,conn) //Send data to receiver through tcp protocol n.Write(data) fmt.Println("End of sending") } func main() { //Get signed results var dt = "hello world" sg:=SignData(dt) //dt is the data to be sent var data = make([]byte,len(dt)+len(sg)) copy(data[0:11],[]byte(dt)) copy(data[11:],sg) //The data array actually consists of two parts: data sent + signature result Send(data) }
DSA
ECDSA
A digital signature algorithm based on elliptic curve cryptography.