118 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package starcrypto
 | ||
| 
 | ||
| import (
 | ||
| 	"crypto/ecdsa"
 | ||
| 	"crypto/elliptic"
 | ||
| 	"crypto/rand"
 | ||
| 	"crypto/x509"
 | ||
| 	"encoding/pem"
 | ||
| 	"errors"
 | ||
| 	"golang.org/x/crypto/ssh"
 | ||
| )
 | ||
| 
 | ||
| func GenerateEcdsaKey(pubkeyCurve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) {
 | ||
| 	// 随机挑选基点,生成私钥
 | ||
| 	priv, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader)
 | ||
| 	if err != nil {
 | ||
| 		return nil, nil, err
 | ||
| 	}
 | ||
| 	return priv, &priv.PublicKey, nil
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| func EncodeEcdsaPrivateKey(private *ecdsa.PrivateKey, secret string) ([]byte, error) {
 | ||
| 	b, err := x509.MarshalECPrivateKey(private)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 	if secret == "" {
 | ||
| 		return pem.EncodeToMemory(&pem.Block{
 | ||
| 			Bytes: b,
 | ||
| 			Type:  "EC PRIVATE KEY",
 | ||
| 		}), err
 | ||
| 	}
 | ||
| 	chiper := x509.PEMCipherAES256
 | ||
| 	blk, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", b, []byte(secret), chiper)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 	return pem.EncodeToMemory(blk), err
 | ||
| }
 | ||
| 
 | ||
| func EncodeEcdsaPublicKey(public *ecdsa.PublicKey) ([]byte, error) {
 | ||
| 	publicBytes, err := x509.MarshalPKIXPublicKey(public)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 	return pem.EncodeToMemory(&pem.Block{
 | ||
| 		Bytes: publicBytes,
 | ||
| 		Type:  "PUBLIC KEY",
 | ||
| 	}), nil
 | ||
| }
 | ||
| 
 | ||
| func DecodeEcdsaPrivateKey(private []byte, password string) (*ecdsa.PrivateKey, error) {
 | ||
| 	var prikey *ecdsa.PrivateKey
 | ||
| 	var err error
 | ||
| 	var bytes []byte
 | ||
| 	blk, _ := pem.Decode(private)
 | ||
| 	if blk == nil {
 | ||
| 		return nil, errors.New("private key error!")
 | ||
| 	}
 | ||
| 	if password != "" {
 | ||
| 		tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
 | ||
| 		if err != nil {
 | ||
| 			return nil, err
 | ||
| 		}
 | ||
| 		bytes = tmp
 | ||
| 	} else {
 | ||
| 		bytes = blk.Bytes
 | ||
| 	}
 | ||
| 	prikey, err = x509.ParseECPrivateKey(bytes)
 | ||
| 	if err != nil {
 | ||
| 		tmp, err := x509.ParsePKCS8PrivateKey(bytes)
 | ||
| 		if err != nil {
 | ||
| 			return nil, err
 | ||
| 		}
 | ||
| 		prikey = tmp.(*ecdsa.PrivateKey)
 | ||
| 	}
 | ||
| 	return prikey, err
 | ||
| }
 | ||
| 
 | ||
| func DecodeEcdsaPublicKey(pubStr []byte) (*ecdsa.PublicKey, error) {
 | ||
| 	blk, _ := pem.Decode(pubStr)
 | ||
| 	if blk == nil {
 | ||
| 		return nil, errors.New("public key error")
 | ||
| 	}
 | ||
| 	pub, err := x509.ParsePKIXPublicKey(blk.Bytes)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 	return pub.(*ecdsa.PublicKey), nil
 | ||
| }
 | ||
| 
 | ||
| func EncodeEcdsaSSHPublicKey(public *ecdsa.PublicKey) ([]byte, error) {
 | ||
| 	publicKey, err := ssh.NewPublicKey(public)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 	return ssh.MarshalAuthorizedKey(publicKey), nil
 | ||
| }
 | ||
| 
 | ||
| func GenerateEcdsaSSHKeyPair(pubkeyCurve elliptic.Curve, secret string) (string, string, error) {
 | ||
| 	pkey, pubkey, err := GenerateEcdsaKey(pubkeyCurve)
 | ||
| 	if err != nil {
 | ||
| 		return "", "", err
 | ||
| 	}
 | ||
| 
 | ||
| 	pub, err := EncodeEcdsaSSHPublicKey(pubkey)
 | ||
| 	if err != nil {
 | ||
| 		return "", "", err
 | ||
| 	}
 | ||
| 
 | ||
| 	priv, err := EncodeEcdsaPrivateKey(pkey, secret)
 | ||
| 	if err != nil {
 | ||
| 		return "", "", err
 | ||
| 	}
 | ||
| 	return string(priv), string(pub), nil
 | ||
| }
 |