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