1. Generate a key pair and write it to a disk file

1. Use ECDSA to generate a key pair

2. Write the private key to the disk

  • Deserialization using X509
  • Place the resulting sliced string into the pem.Block structure
  • Using pem encoding

3. Write the public key to the disk

  • Get the public key from the private key
  • Use X509 for serialization
  • Place the resulting slice string into the pem.Block structure
  • Using pem encoding

2. Use the private key for digital signature

1. Open the private key file and read it

2. Use the PEM to decode data

3. Use X509 to restore data

4. Hash the original data

Func Sign(rand IO.Reader, priv *PrivateKey, Hash []byte) (r, s *big.Int, err Error) 6. The return value is a pointer, so you need to sequence the address to the data in memory

3. Use the public key to verify the digital signature

1. Open the public key file and read data

2. Use the PEM to decode

3. Restore public key data using X509 func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)

4. Because the interface type returned in the previous step is an interface type, you need to perform type assertion to convert the interface type to a public key

5. Hash the original data

6. Attestation

4. Go in application

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"encoding/pem"
	"os"
	"crypto/sha256"
	"math/big"
)

func GenerateEcdsaKey (a) {
	//1. Use ecDSA to generate a key pair
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	iferr ! =nil {
		panic(err)
	}
	//2. Write the private key to the disk
	//* Use x509 to deserialize
	ecPrivateKey, err := x509.MarshalECPrivateKey(privateKey)
	iferr ! =nil {
		panic(err)
	}
	//* Place the resulting sliced string in the pem.Block structure
	block := pem.Block{
		Type:    "ecdsa private key",
		Headers: nil,
		Bytes:   ecPrivateKey,
	}
	//* Use pem encoding
	file, err := os.Create("ecPrivate.pem")
	iferr ! =nil {
		panic(err)
	}
	defer file.Close()
	err = pem.Encode(file, &block)
	iferr ! =nil {
		panic(err)
	}
	//3. Write the public key to the disk
	//* Get the public key from the private key
	publicKey := privateKey.PublicKey
	//* Use x509 for serialization
	ecPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	iferr ! =nil {
		panic(err)
	}
	//* Place the resulting slice string into the pem.Block structure
	block = pem.Block{
		Type:    "ecdsa public key",
		Headers: nil,
		Bytes:   ecPublicKey,
	}
	//* Use pem encoding
	file, err = os.Create("ecPublic.pem")
	iferr ! =nil {
		panic(err)
	}
	defer file.Close()
	pem.Encode(file, &block)
}

/ / signature
func SignECDSA (plainText []byte, priFileName string) (rText, sText []byte) {
	//1. Open the private key file and read the contents
	file, err := os.Open(priFileName)
	iferr ! =nil {
		panic(err)
	}
	defer file.Close()
	fileInfo, err := file.Stat()
	iferr ! =nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	iferr ! =nil {
		panic(err)
	}
	//2. Use pem to decode data
	block, _ := pem.Decode(buf)
	//3. Use X509 to restore data
	privateKey, err := x509.ParseECPrivateKey(block.Bytes)
	iferr ! =nil {
		panic(err)
	}
	//4. Hash the original data
	hashText := sha256.Sum256(plainText)
	//5. Create a digital signature
	var r, s *big.Int // Notice here
	r, s, err = ecdsa.Sign(rand.Reader, privateKey, hashText[:])
	iferr ! =nil {
		panic(err)
	}
	//6. The return value is a pointer, so we need to sequence the address to the data in memory
	rText, err = r.MarshalText()
	iferr ! =nil {
		panic(err)
	}
	sText, err = s.MarshalText()
	iferr ! =nil {
		panic(err)
	}
	return rText,sText
}

/ / attestation
func VerifyECDSA (plainText, rText, sText []byte, pubFileName string) bool {
	//1. Open the public key file and read data
	file, err := os.Open(pubFileName)
	iferr ! =nil {
		panic(err)
	}
	defer file.Close()
	fileInfo, err := file.Stat()
	iferr ! =nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	iferr ! =nil {
		panic(err)
	}
	//2. Decode using pem
	block, _ := pem.Decode(buf)
	//3. Use X509 to restore public key data
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	iferr ! =nil {
		panic(err)
	}
	//4. Since the interface type returned in the previous step is an interface type, type assertion is required to convert the interface type to a public key
	publicKey := pubInterface.(*ecdsa.PublicKey)
	//5. Hash the original data
	hashText := sha256.Sum256(plainText)
	/ / 6. Attestation
	var r, s big.Int
	r.UnmarshalText(rText)
	s.UnmarshalText(sText)
	res := ecdsa.Verify(publicKey, hashText[:], &r, &s)
	return res
}
Copy the code