一、概念
椭圆曲线密码学,一种建立公开密钥加密的算法,基于椭圆曲线数学。主要优势是在某些情况下他比其他的方法使用更小的密钥,提供相当的或更高等级的安全。椭圆曲线密码学的许多形式有稍微的不同,所有的都依赖与被广泛承认的解决椭圆椭圆曲线离散对数问题的困难性上。与传统的基于大质数因子分解困难性的加密方法不用,ECC通过椭圆曲线方程式的性质产生密钥。
ECC 164位的密钥产生的一个安全级相当于RSA 1024位密钥提供的保密强度,而且计算量较小,处理速度更快,,存储空间和传输带宽占用较少。目前,我国居民二代身份证正在使用256位的椭圆曲线密码。
数学公式
二、代码实现
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
)
/*
选择一个椭圆曲线(在elliptic包)
使用ecdsa包,创建私钥
使用x509进行编码
pem.Encode
*/
const EccPrivateKeyFile = "./EccPrivateKey.pem"
const EccPublicKeyFile = "./EccPublicKey.pem"
func generateEccKeypair() {
//选择一个椭圆曲线(在elliptic包)
//type Curve
//func P224() Curve
//func P256() Curve
//func P384() Curve
//func P521() Curve
curve := elliptic.P256()
//使用ecdsa包,创建私钥
//GenerateKey函数生成密钥对
//func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error)
privateKey , err := ecdsa.GenerateKey(curve,rand.Reader)
checheErr("generate key failed",err)
//使用x509进行编码
//MarshalECPrivateKey将ecdsa私钥序列化为ASN.1 DER编码。
//func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error)
derText1 , err := x509.MarshalECPrivateKey(privateKey)
checheErr("MarshalECPrivateKey",err)
//写入pem.Block中
block1 := pem.Block{
Type: "ECC PRIVATE KEY",
Headers: nil,
Bytes: derText1,
}
//pem.Encode
fileHander1 ,err := os.Create(EccPrivateKeyFile)
checheErr("os.Create fileHander failed",err)
defer fileHander1.Close()
err = pem.Encode(fileHander1,&block1)
checheErr("pem.Encode failed",err)
fmt.Println("==========================================")
//获取公钥
publicKey := privateKey.PublicKey
derText2 , err := x509.MarshalPKIXPublicKey(&publicKey)
checheErr("x509.MarshalPKIXPublicKey failed",err)
//写入pem.Block中
block2 := pem.Block{
Type: "ECC PRIVATE KEY",
Headers: nil,
Bytes: derText2,
}
//pem.Encode
fileHander2 ,err := os.Create(EccPublicKeyFile)
checheErr("os.Create fileHander failed",err)
defer fileHander2.Close()
err = pem.Encode(fileHander2,&block2)
checheErr("pem.Encode failed",err)
}
func main(){
generateEccKeypair()
}
func checheErr(message string, err error) {
if err != nil {
fmt.Println(message + "err:",err)
}
}