go區塊鏈培訓怎麼樣?深度講解橢圓曲線加密算法ECC和橢圓曲線數字簽名算法ECDSA

 8.1.1 ECC數字簽名(ECDSA)核心代碼app

下面經過一個案例驗證數字簽名,如例所示。code

例1-1 ECDSAcdn

1 package mainblog

2 import (ip

3 "crypto/ecdsa"ci

4 "crypto/elliptic"string

5 "crypto/rand"it

6 "crypto/sha256"io

7 "encoding/hex"class

8 "fmt"

9 "log"

10 "math/big"

11 )

12 func main() {

13 fmt.Println("生成簽名-------------------------------")

14 privKey, pubKey := NewKeyPair()

15 msg := sha256.Sum256([]byte("hello world"))

16 r, s, _ := ecdsa.Sign(rand.Reader, &privKey, msg[:])

17 strSigR := fmt.Sprintf("%x", r)

18 strSigS := fmt.Sprintf("%x", s)

19 fmt.Println("r、s的10進制分別爲:", r, s)

20 fmt.Println("r、s的16進制分別爲:", strSigR, strSigS)

21 signatureDer := MakeSignatureDerString(strSigR, strSigS)

22 fmt.Println("數字簽名DER格式爲:", signatureDer)

23 res := VerifySig(pubKey, msg[:], r, s)

24 fmt.Println("簽名驗證結果:", res)

25 res = VerifySignature(pubKey, msg[:], strSigR, strSigS)

26 fmt.Println("簽名驗證結果:", res)

27 }

28 func NewKeyPair() (ecdsa.PrivateKey, []byte) {

29 curve := elliptic.P256()

30 private, err := ecdsa.GenerateKey(curve, rand.Reader)

31 if err != nil {

32 log.Panic(err)

33 }

34 pubKey := append(private.X.Bytes(), private.Y.Bytes()...)

35 return *private, pubKey

36 }

37 func MakeSignatureDerString(r, s string) string {

38 lenSigR := len(r) / 2

39 lenSigS := len(s) / 2

40 lenSequence := lenSigR + lenSigS + 4

41 strLenSigR := DecimalToHex(int64(lenSigR))

42 strLenSigS := DecimalToHex(int64(lenSigS))

43 strLenSequence := DecimalToHex(int64(lenSequence))

44 derString := "30" + strLenSequence

45 derString = derString + "02" + strLenSigR + r

46 derString = derString + "02" + strLenSigS + s

47 derString = derString + "01"

48 return derString

49 }

50 func VerifySig(pubKey, message []byte, r, s *big.Int) bool {

51 curve := elliptic.P256()

52 keyLen := len(pubKey)

53 x := big.Int{}

54 y := big.Int{}

55 x.SetBytes(pubKey[:(keyLen / 2)])

56 y.SetBytes(pubKey[(keyLen / 2):])

57 rawPubKey := ecdsa.PublicKey{curve, &x, &y}

58 res := ecdsa.Verify(&rawPubKey, message, r, s)

59 return res

60 }

61 func VerifySignature(pubKey, message []byte, r, s string) bool {

62 curve := elliptic.P256()

63 keyLen := len(pubKey)

64 x := big.Int{}

65 y := big.Int{}

66 x.SetBytes(pubKey[:(keyLen / 2)])

67 y.SetBytes(pubKey[(keyLen / 2):])

68 rawPubKey := ecdsa.PublicKey{curve, &x, &y}

69 rint := big.Int{}

70 sint := big.Int{}

71 rByte, _ := hex.DecodeString(r)

72 sByte, _ := hex.DecodeString(s)

73 rint.SetBytes(rByte)

74 sint.SetBytes(sByte)

75 res := ecdsa.Verify(&rawPubKey, message, &rint, &sint)

76 return res

77 }

78 func DecimalToHex(n int64) string {

79 if n < 0 {

80 log.Println("Decimal to hexadecimal error: the argument must be greater than zero.")

81 return ""

82 }

83 if n == 0 {

84 return "0"

85 }

86 hex := map[int64]int64{10: 65, 11: 66, 12: 67, 13: 68, 14: 69, 15: 70}

87 s := ""

88 for q := n; q > 0; q = q / 16 {

89 m := q % 16

90 if m > 9 && m < 16 {

91 m = hex[m]

92 s = fmt.Sprintf("%v%v", string(m), s)

93 continue

94 }

95 s = fmt.Sprintf("%v%v", m, s)

96 }

97 return s

98 }

運行結果如圖所示。因爲數字簽名字段過長,這裏只截取了一部分。

圖8.1 運行結果

相關文章
相關標籤/搜索