Skip to content

Instantly share code, notes, and snippets.

@timest
Created April 2, 2018 14:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save timest/56b68d4ae77160abae00b4bb28faf7f4 to your computer and use it in GitHub Desktop.
Save timest/56b68d4ae77160abae00b4bb28faf7f4 to your computer and use it in GitHub Desktop.
用golang生成密钥和签名证书
package main
import (
"crypto/elliptic"
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"os"
"math/big"
"time"
"github.com/Sirupsen/logrus"
"crypto/sha256"
)
var log = logrus.New()
type ecdsaGen struct {
curve elliptic.Curve
}
func (e *ecdsaGen) KeyGen() (key *ecdsa.PrivateKey, err error) {
privKey, err := ecdsa.GenerateKey(e.curve, rand.Reader)
if err != nil {
return nil, err
}
return privKey, nil
}
func encode(privateKey *ecdsa.PrivateKey, publicKey *ecdsa.PublicKey) (string, string) {
x509Encoded, _ := x509.MarshalECPrivateKey(privateKey)
pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: x509Encoded})
x509EncodedPub, _ := x509.MarshalPKIXPublicKey(publicKey)
pemEncodedPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: x509EncodedPub})
// 将ec 密钥写入到 pem文件里
keypem, _ := os.OpenFile("ec-key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
pem.Encode(keypem, &pem.Block{Type: "EC PRIVATE KEY", Bytes: x509Encoded})
return string(pemEncoded), string(pemEncodedPub)
}
func decode(pemEncoded string, pemEncodedPub string) (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
block, _ := pem.Decode([]byte(pemEncoded))
x509Encoded := block.Bytes
privateKey, _ := x509.ParseECPrivateKey(x509Encoded)
blockPub, _ := pem.Decode([]byte(pemEncodedPub))
x509EncodedPub := blockPub.Bytes
genericPublicKey, _ := x509.ParsePKIXPublicKey(x509EncodedPub)
publicKey := genericPublicKey.(*ecdsa.PublicKey)
return privateKey, publicKey
}
func checkError(err error) {
if err != nil {
log.Panic(err)
}
}
// 根据ecdsa密钥生成特征标识码
func priKeyHash(priKey *ecdsa.PrivateKey) []byte {
hash := sha256.New()
hash.Write(elliptic.Marshal(priKey.Curve, priKey.PublicKey.X, priKey.PublicKey.Y))
return hash.Sum(nil)
}
func main() {
// 生成ecdsa
e := &ecdsaGen{curve: elliptic.P256()}
priKey, _ := e.KeyGen()
priKeyEncode, err := x509.MarshalECPrivateKey(priKey)
checkError(err)
// 保存到pem文件
f, err := os.Create("ec.pem")
checkError(err)
pem.Encode(f, &pem.Block{Type: "EC PRIVATE KEY", Bytes: priKeyEncode})
f.Close()
pubKey := priKey.Public()
// Encode public key
//raw, err := x509.MarshalPKIXPublicKey(pubKey)
//checkError(err)
//log.Info(raw)
// 自签
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
expiry := 365 * 24 * time.Hour
notBefore := time.Now().Add(-5 * time.Minute).UTC()
template := x509.Certificate{
SerialNumber: serialNumber,
NotBefore: notBefore,
NotAfter: notBefore.Add(expiry).UTC(),
BasicConstraintsValid: true,
IsCA: true,
KeyUsage: x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
Subject: pkix.Name{
Country: []string{"CN"},
Locality: []string{"zhongguancun"},
Province: []string{"Beijing"},
OrganizationalUnit: []string{"tect"},
Organization: []string{"paradise"},
StreetAddress: []string{"street", "address", "demo"},
PostalCode: []string{"310000"},
CommonName: "demo.example.com",
},
}
template.SubjectKeyId = priKeyHash(priKey)
x509certEncode, err := x509.CreateCertificate(rand.Reader, &template, &template, pubKey, priKey)
checkError(err)
crt, err := os.Create("cert.crt")
checkError(err)
pem.Encode(crt, &pem.Block{Type: "CERTIFICATE", Bytes: x509certEncode})
crt.Close()
// 使用bob的密钥进行证书签名
bobPriKey, _ := e.KeyGen()
bobPriKeyEncode, err := x509.MarshalECPrivateKey(bobPriKey)
checkError(err)
bobf, err := os.Create("bob.pem")
checkError(err)
pem.Encode(bobf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: bobPriKeyEncode})
bobf.Close()
bobPubKey := bobPriKey.Public()
bobSerialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
notBefore = time.Now().Add(-5 * time.Minute).UTC()
bobTemplate := x509.Certificate{
SerialNumber: bobSerialNumber,
NotBefore: notBefore,
NotAfter: notBefore.Add(expiry).UTC(),
BasicConstraintsValid: true,
IsCA: false,
KeyUsage: x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
Subject: pkix.Name{
Country: []string{"CN"},
Locality: []string{"Locality"},
Province: []string{"Beijing"},
OrganizationalUnit: []string{"tect"},
Organization: []string{"paradise"},
StreetAddress: []string{"street", "address", "demo"},
PostalCode: []string{"310000"},
CommonName: "demo.example.com",
},
}
bobTemplate.SubjectKeyId = priKeyHash(bobPriKey)
parent, err := x509.ParseCertificate(x509certEncode)
checkError(err)
bobCertEncode, err := x509.CreateCertificate(rand.Reader, &bobTemplate, parent, bobPubKey, priKey)
checkError(err)
bcrt, _ := os.Create("bob.crt")
pem.Encode(bcrt, &pem.Block{Type: "CERTIFICATE", Bytes: bobCertEncode})
bcrt.Close()
}
@lysShub
Copy link

lysShub commented Oct 24, 2021

请问,ECC的公钥加密私钥解密怎么写?官方好像没有实现

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment