1 橢圓曲線密碼學(xué)
- 橢圓曲線密碼學(xué)(Elliptic Curve Cryptography,縮寫(xiě)ECC)祝懂,是基于橢圓曲線數(shù)學(xué)理論實(shí)現(xiàn)的一種非對(duì)稱(chēng)加密算法铭若。橢圓曲線在密碼學(xué)中的使用是在1985年有Neal Koblitz和Victor Miller分別提出來(lái)的吓懈。
-
標(biāo)準(zhǔn)的橢圓曲線
- 橢圓曲線加密
- 考慮K=kG,其中K嘴办、G為橢圓曲線Ep(a,b)上的點(diǎn)季率,n為G的階(n G = O∞ ),k為小于n的整數(shù)躲庄。則給定k和G查剖,根據(jù)加法法則,計(jì)算K很容易但反過(guò)來(lái)噪窘,給定K和G笋庄,求k就非常困難。因?yàn)閷?shí)際使用中的ECC原則上把p取得相當(dāng)大倔监,n也相當(dāng)大直砂,要把n個(gè)解點(diǎn)逐一算出來(lái)列成上表是不可能的。這就是橢圓曲線加密算法的數(shù)學(xué)依據(jù) 浩习。
2 應(yīng)用場(chǎng)景
- 比特幣使用橢圓曲線算法生產(chǎn)公鑰和私鑰静暂,選擇的是secp256k1曲線。與RSA(Ron Rivest瘦锹,Adi Shamir籍嘹,Len Adleman三位天才的名字)一樣,ECC(橢圓曲線加密算法)也屬于公開(kāi)秘鑰算法弯院。
- 橢圓曲線數(shù)字簽名算法辱士,因其高安全性,目前已廣發(fā)應(yīng)用在比特幣听绳、以太坊颂碘、超級(jí)賬本等區(qū)塊鏈項(xiàng)目中。
3 ECC與RSA算法的優(yōu)勢(shì)對(duì)?
與經(jīng)典的RSA、DSA等公鑰密碼體制相?头岔,橢圓密碼體制有以下優(yōu)點(diǎn):
- 安全性能更?(ECC可以使?更短的密鑰):
160位ECC加密算法的安全強(qiáng)度相當(dāng)于1024位RSA加密塔拳;
210位ECC加密算法的安全強(qiáng)度相當(dāng)于2048位RSA加密。 - 處理速度快:計(jì)算量?峡竣,處理速度快 在私鑰的處理速度上(解密和簽名)靠抑,ECC遠(yuǎn) ?RSA、DSA快得多适掰。
- 存儲(chǔ)空間占??: ECC的密鑰尺?和系統(tǒng)參數(shù)與RSA颂碧、DSA相?要?得多, 所以占?的存儲(chǔ)空間?得多类浪。
- 帶寬要求低使得ECC具有?泛的應(yīng)?前景载城。ECC的這些特點(diǎn)使它必將取代RSA,成為通?的公鑰加密算法费就。
4 數(shù)字簽名與驗(yàn)證過(guò)程
- 只有轉(zhuǎn)賬人才能生成一段防偽造的字符串诉瓦。通過(guò)驗(yàn)證該字符串,一方面證明改交易是轉(zhuǎn)出方本人發(fā)起的力细,另一方面證明交易信息在傳輸過(guò)程中沒(méi)有被更改睬澡。
- 數(shù)字簽名由:數(shù)字摘要和非對(duì)稱(chēng)加密技術(shù)組成。數(shù)字摘要把交易信息hash成固定長(zhǎng)度的字符串眠蚂;再用私鑰對(duì)hash后的交易信息進(jìn)行加密成數(shù)字簽名猴贰。
-
交易中,需要將完整的交易信息和數(shù)字簽名一起廣播給礦工河狐。礦工節(jié)點(diǎn)用轉(zhuǎn)賬人公鑰對(duì)簽名驗(yàn)證米绕,驗(yàn)證成功說(shuō)明改交易確實(shí)是轉(zhuǎn)賬人發(fā)起;曠工節(jié)點(diǎn)將交易信息進(jìn)行hash后與簽名的交易信息摘要進(jìn)行比對(duì)馋艺,如果一致則說(shuō)明交易信息在傳輸過(guò)程中沒(méi)有被篡改栅干。
5 代碼驗(yàn)證
- ?成私鑰和公鑰,?成的私鑰為結(jié)構(gòu)體ecdsa.PrivateKey的指針
func NewKeyPair() (ecdsa.PrivateKey, []byte) {
// 生產(chǎn)secp256橢圓曲線
curve := elliptic.P256()
// 產(chǎn)生一個(gè)結(jié)構(gòu)體指針捐祠,結(jié)構(gòu)體類(lèi)型ecdsa.PrivateKey
private, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
log.Panic(err)
}
fmt.Println("私鑰:%x\n", private)
fmt.Println("私鑰X:%x\n", private.X.Bytes())
fmt.Println("私鑰Y:%x\n", private.Y.Bytes())
fmt.Println("私鑰D:%x\n", private.D.Bytes())
// x坐標(biāo)與y坐標(biāo)拼接在一起生成公鑰
publicKey := append(private.X.Bytes(), private.Y.Bytes()...)
fmt.Println("公鑰:%x\n", publicKey)
return *private, publicKey
}
- ?成簽名的DER格式
func MakeSignatureDerString(r, s string) string {
// 獲取R和S的?度
lenSigR := len(r) / 2
lenSigS := len(s) / 2
// 計(jì)算DER序列的總?度
lenSequence := lenSigR + lenSigS + 4
// 將10進(jìn)制?度轉(zhuǎn)16進(jìn)制字符串
strLenSigR := DecimalToHex(int64(lenSigR))
strLenSigS := DecimalToHex(int64(lenSigS))
strLenSequence := DecimalToHex(int64(lenSequence))
// 拼湊DER編碼
derString := "30" + strLenSequence
derString = derString + "02" + strLenSigR + r
derString = derString + "02" + strLenSigS + s
derString = derString + "01"
return derString
}
- 生成簽名
privateKey, publicKey := NewKeyPair()
msg := sha256.Sum256([]byte("ecc數(shù)組簽名"))
r, s, _ := ecdsa.Sign(rand.Reader, &privateKey, msg[:])
strSigR := fmt.Sprintf("%x", r) // r.MarshalText()
strSigS := fmt.Sprintf("%x", s) // s.MarshalText()
fmt.Printf("r碱鳞、s的10進(jìn)制:%#v, %#v\n", r, s)
fmt.Println("r踱蛀、s的16進(jìn)制:", strSigR, strSigS)
//r和s拼接在?起窿给,形成數(shù)字簽名的der格式
signatureDer := MakeSignatureDerString(strSigR, strSigS)
//打印數(shù)字簽名的16進(jìn)制顯示
fmt.Println("數(shù)字簽名DER格式為:", signatureDer)
- 驗(yàn)證簽名
func VerifySig(pubKey, message []byte, r, s *big.Int) bool {
curve := elliptic.P256()
//公鑰的?度
keyLen := len(pubKey)
//前?半為x軸坐標(biāo),后?半為y軸坐標(biāo)
x := big.Int{}
y := big.Int{}
x.SetBytes(pubKey[:(keyLen / 2)])
y.SetBytes(pubKey[(keyLen / 2):])
rawPubKey := ecdsa.PublicKey{curve, &x, &y}
//根據(jù)交易哈希率拒、公鑰崩泡、數(shù)字簽名驗(yàn)證成功:
// ecdsa.Verify func Verify(pub *PublicKey, hash[] byte, r * big.Int, s * big.Int) bool
res := ecdsa.Verify(&rawPubKey, message, r, s)
return res
}