日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

golang中的数字签名

發布時間:2025/6/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang中的数字签名 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數字簽名

數字簽名的方法

簽名的生成和驗證

  • 簽名
    • 有原始數據對其進行哈希運算 -> 散列值
    • 使用非對稱加密的私鑰對散列值加密 -> 簽名
    • 將原始數據和簽名一并發送給對方
  • 驗證
    • 接收數據
      • 原始數據
      • 數字簽名
    • 數字簽名, 需要使用公鑰解密, 得到散列值
    • 對原始數據進行哈希運算得到新的散列值
  • 非對稱加密和數字簽名

    總結:

  • 數據通信
    • 公鑰加密, 私鑰解密
  • 數字簽名:
  • - 私鑰加密, 公鑰解密

    使用RSA進行數字簽名

  • 使用rsa生成密鑰對

  • 生成密鑰對
  • 序列化
  • 保存到磁盤文件
  • 使用私鑰進行數字簽名

  • 打開磁盤的私鑰文件

  • 將私鑰文件中的內容讀出

  • 使用pem對數據解碼, 得到了pem.Block結構體變量

  • x509將數據解析成私鑰結構體 -> 得到了私鑰

  • 創建一個哈希對象 -> md5/sha1

  • 給哈希對象添加數據

  • 計算哈希值

  • 使用rsa中的函數對散列值簽名

    func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) (s []byte, err error) 參數1: rand.Reader 參數2: 非對稱加密的私鑰 參數3: 使用的哈希算法crypto.sha1crypto.md5 參數4: 數據計算之后得到的散列值 返回值: - s: 得到的簽名數據 - err: 錯誤信息
  • 使用公鑰進行簽名認證

  • 打開公鑰文件, 將文件內容讀出 - []byte

  • 使用pem解碼 -> 得到pem.Block結構體變量

  • 使用x509對pem.Block中的Bytes變量中的數據進行解析 -> 得到一接口

  • 進行類型斷言 -> 得到了公鑰結構體

  • 對原始消息進行哈希運算(和簽名使用的哈希算法一致) -> 散列值

  • 創建哈希接口
  • 添加數據
  • 哈希運算
  • 簽名認證 - rsa中的函數

    func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (err error) 參數1: 公鑰 參數2: 哈希算法 -> 與簽名使用的哈希算法一致 參數3: 將原始數據進行哈希原始得到的散列值 參數4: 簽名的字符串 返回值: - nil -> 驗證成功- !=nil -> 失敗
  • 使用橢圓曲線進行數字簽名

    橢圓曲線在go中對應的包: import "crypto/elliptic"

    使用橢圓曲線在go中進行數字簽名: import "crypto/ecdsa"

    美國FIPS186-2標準, 推薦使用5個素域上的橢圓曲線, 這5個素數模分別是:

    P~192~ = 2^192^ - 2^64^ - 1

    P~224~ = 2^224^ - 2^96^ + 1

    P~256~ = 2^256^ - 2^224^ + 2^192^ - 2^96^ -1

    P~384~ = 2^384^ - 2^128^ - 2^96^ + 2^32^ -1

    P~512~ = 2^512^ - 1

  • 秘鑰對稱的生成, 并保存到磁盤

  • 使用ecdsa生成密鑰對

    func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error)
  • 將私鑰寫入磁盤

    • 使用x509進行序列化

      func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error)
    • 將得到的切片字符串放入pem.Block結構體中

      block := pem.Block{

      Type : "描述....",

      Bytes : MarshalECPrivateKey返回值中的切片字符串,

      }

    • 使用pem編碼

      pem.Encode();

  • 將公鑰寫入磁盤

    • 從私鑰中得到公鑰

    • 使用x509進行序列化

      func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
    • 將得到的切片字符串放入pem.Block結構體中

      block := pem.Block{

      Type : "描述....",

      Bytes : MarshalECPrivateKey返回值中的切片字符串,

      }

    • 使用pem編碼

      pem.Encode();

  • 使用私鑰進行數字簽名

  • 打開私鑰文件, 將內容讀出來 ->[]byte

  • 使用pem進行數據解碼 -> pem.Decode()

  • 使用x509, 對私鑰進行還原

    func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error)
  • 對原始數據進行哈希運算 -> 散列值

  • 進行數字簽名

    func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) - 得到的r和s不能直接使用, 因為這是指針應該將這兩塊內存中的數據進行序列化 -> []bytefunc (z *Int) MarshalText() (text []byte, err error)
  • 使用公鑰驗證數字簽名

  • 打開公鑰文件, 將里邊的內容讀出 -> []byte

  • pem解碼 -> pem.Decode()

  • 使用x509對公鑰還原

    func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)
  • 將接口 -> 公鑰

  • 對原始數據進行哈希運算 -> 得到散列值

  • 簽名的認證 - > ecdsa

    func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool - 參數1: 公鑰 - 參數2: 原始數據生成的散列值 - 參數3,4: 通過簽名得到的連個點func (z *Int) UnmarshalText(text []byte) error
  • 數字簽名無法解決的問題

    代碼

    RSA簽名和認證

    // RSA簽名 - 私鑰 func SignatureRSA(plainText []byte, fileName string) []byte{//1. 打開磁盤的私鑰文件file, err := os.Open(fileName)if err != nil {panic(err)}//2. 將私鑰文件中的內容讀出info, err := file.Stat()if err != nil {panic(err)}buf := make([]byte, info.Size())file.Read(buf)file.Close()//3. 使用pem對數據解碼, 得到了pem.Block結構體變量block, _ := pem.Decode(buf)//4. x509將數據解析成私鑰結構體 -> 得到了私鑰privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {panic(err)}//5. 創建一個哈希對象 -> md5/sha1 -> sha512// sha512.Sum512()myhash := sha512.New()//6. 給哈希對象添加數據myhash.Write(plainText)//7. 計算哈希值hashText := myhash.Sum(nil)//8. 使用rsa中的函數對散列值簽名sigText, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA512, hashText)if err != nil {panic(err)}return sigText } // RSA簽名驗證 func VerifyRSA(plainText, sigText []byte, pubFileName string) bool {//1. 打開公鑰文件, 將文件內容讀出 - []bytefile, err := os.Open(pubFileName)if err != nil {panic(err)}info, err := file.Stat()if err != nil {panic(err)}buf := make([]byte, info.Size())file.Read(buf)file.Close()//2. 使用pem解碼 -> 得到pem.Block結構體變量block, _ := pem.Decode(buf)//3. 使用x509對pem.Block中的Bytes變量中的數據進行解析 -> 得到一接口pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {panic(err)}//4. 進行類型斷言 -> 得到了公鑰結構體publicKey := pubInterface.(*rsa.PublicKey)//5. 對原始消息進行哈希運算(和簽名使用的哈希算法一致) -> 散列值hashText := sha512.Sum512(plainText)//6. 簽名認證 - rsa中的函數err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA512, hashText[:], sigText)if err == nil {return true}return false }func main() {src := []byte("在消息認證碼中,需要發送者和接收者之間共享密鑰,而這個密鑰不能被主動攻擊者Mallory獲取。如果這個密鑰落入Mallory手中,則Mallory也可以計算出MAC值,從而就能夠自由地進行篡改和偽裝攻擊,這樣一來消息認證碼就無法發揮作用了。")sigText := SignatureRSA(src, "private.pem")bl := VerifyRSA(src, sigText, "public.pem")fmt.Println(bl) }

    總結

    以上是生活随笔為你收集整理的golang中的数字签名的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。