[go cryptography] - Digital Signature

Posted by validangina on Sun, 15 Dec 2019 16:28:31 +0100

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.

Topics: Go encoding Programming network