經過Go語言封裝一個橢圓曲線算法(ecdsa),方便本身使用。簽名算法直接寫死sha256了,有須要自行修改便可。css
ecc_utils.gojava
package ecc import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/hex" "math/big" "strings" ) func GenKeyPair() (privateKey string, publicKey string, e error) { priKey, e := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if e != nil { return "", "", e } ecPrivateKey, e := x509.MarshalECPrivateKey(priKey) if e != nil { return "", "", e } privateKey = base64.StdEncoding.EncodeToString(ecPrivateKey) X := priKey.X Y := priKey.Y xStr, e := X.MarshalText() if e != nil { return "", "", e } yStr, e := Y.MarshalText() if e != nil { return "", "", e } public := string(xStr) + "+" + string(yStr) publicKey = base64.StdEncoding.EncodeToString([]byte(public)) return } func BuildPrivateKey(privateKeyStr string) (priKey *ecdsa.PrivateKey, e error) { bytes, e := base64.StdEncoding.DecodeString(privateKeyStr) if e != nil { return nil, e } priKey, e = x509.ParseECPrivateKey(bytes) if e != nil { return nil, e } return } func BuildPublicKey(publicKeyStr string) (pubKey *ecdsa.PublicKey, e error) { bytes, e := base64.StdEncoding.DecodeString(publicKeyStr) if e != nil { return nil, e } split := strings.Split(string(bytes), "+") xStr := split[0] yStr := split[1] x := new(big.Int) y := new(big.Int) e = x.UnmarshalText([]byte(xStr)) if e != nil { return nil, e } e = y.UnmarshalText([]byte(yStr)) if e != nil { return nil, e } pub := ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y} pubKey = &pub return } func Sign(content string, privateKeyStr string) (signature string, e error) { priKey, e := BuildPrivateKey(privateKeyStr) if e != nil { return "", e } r, s, e := ecdsa.Sign(rand.Reader, priKey, []byte(hash(content))) if e != nil { return "", e } rt, e := r.MarshalText() st, e := s.MarshalText() signStr := string(rt) + "+" + string(st) signature = hex.EncodeToString([]byte(signStr)) return } func VerifySign(content string, signature string, publicKeyStr string) bool { decodeSign, e := hex.DecodeString(signature) if e != nil { return false } split := strings.Split(string(decodeSign), "+") rStr := split[0] sStr := split[1] rr := new(big.Int) ss := new(big.Int) e = rr.UnmarshalText([]byte(rStr)) e = ss.UnmarshalText([]byte(sStr)) pubKey, e := BuildPublicKey(publicKeyStr) if e != nil { return false } return ecdsa.Verify(pubKey, []byte(hash(content)), rr, ss) } // Hash算法,這裏是sha256,能夠根據須要自定義 func hash(data string) string { sum := sha256.Sum256([]byte(data)) return base64.StdEncoding.EncodeToString(sum[:]) } 複製代碼
ecc_utils_test.go算法
package ecc import "testing" const pubKey = "MTEzODUyMzM5MzU4ODk1MzEzNzg3MzY2NzYwODUwMjE2MjQzNTE0OTc0NjkzMzM2NzA4OTYzNDY0MDk1MTUxMDkyMjY5MjM0NjE3NjMyKzc5NzY5NDM5NTI4NjcxMzc4OTQ3ODYyMzY0MjQ1ODg4ODA0MTEyMDgwOTM4MjgyNjI0MTY4NDUwNjE0NTg4MDc3MDk0MTUxNzk4NzM3" const priKey = "MHcCAQEEIBC7/AKbbIHyVF4XJQmvqwrJMX8c8dU2JP6NcReYDlJ1oAoGCCqGSM49AwEHoUQDQgAE+7Yj9jOgDCRccssUMp1NVJExBrJCv6H8LsYUqS8lfSCwW+cdXcnmNDHM5Z2K05bJywyDIWU3f+53z0HK0I4/0Q==" const content = "Happyjava not only java" const signature = "36393733373630313538383036323831323937313232353733313837333336373132363935303734303237373233373433363139373530313438383239303532303635383433333733313336362b35363137383339343939383534303631323730373630343438313135333633383339333535303836313830343737333331383935333532383537333730363035313839383939353330363939" func TestGenKeyPair(t *testing.T) { privateKey, publicKey, e := GenKeyPair() if e != nil { t.Error(e) return } t.Log("pubKey:", publicKey) t.Log("priKey:", privateKey) } func TestBuildPublicKey(t *testing.T) { publicKey, e := BuildPublicKey(pubKey) if e != nil { t.Error(e) return } t.Log("publicKey:", publicKey) } func TestBuildPrivateKey(t *testing.T) { privateKey, e := BuildPrivateKey(priKey) if e != nil { t.Error(e) return } t.Log("privateKey:", privateKey) } func TestSign(t *testing.T) { signature, e := Sign(content, priKey) if e != nil { t.Error(e) } else { t.Log("signature:", signature) } } func TestVerifySign(t *testing.T) { verify := VerifySign(content, signature, pubKey) t.Log("verify:", verify) } 複製代碼