常用加密算法學習總結之數字簽名


數字簽名(Digital Signature),通俗來講是基於非對稱加密算法,用秘鑰對內容進行散列值簽名,在對內容與簽名一起發送。

更詳細的解說
更詳細的解說 - 中文

數字簽名的生成個驗證

簽名

⑴ 對數據進行散列值運算。
⑵ 簽名:使用簽名者的私鑰對數據的散列值進行加密。
⑶ 數字簽名數據:簽名與原始數據。

驗證
⑴ 接收數據:原始數據&數字簽名。
⑵ 使用公鑰進行解密得到散列值。
⑶ 將原始數據的散列值與解密后的散列值進行對比。

Go語言中使用RSA進行數字簽名

⑴ pem解碼:使用pem對私鑰進行解碼, 得到pem.Block結構體
⑵ 獲得私鑰:使用GO x509接口pem.Block據解析成私鑰結構體
⑶ 計算hash值:對明文進行散列值計算
⑷ 使用秘鑰對散列值簽名

package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
)

var (
	private = `-----BEGIN 私鑰-----
MIICXQIBAAKBgQDc73afIxqYOHg80puDIMYrqUAiTi8EiTVDEiO9YE3+VxRvN0sa
pe3zx1UdhgIn3iCPUzyI2vwNADId3LjuIjkdCcdB2fHrBTbcy6u0545HnY42F9aQ
7cAr168bHcqhQoKcna9i9nukO+w7So1J9C6Wr8J4e4923q7+T7z7bZeXywIDAQAB
AoGBAItX5KLdywoyo3MJCdgcNaCX8MEyOmlL+HHC4ROxx78gQN0cLJw0Bu33zHEA
ch+e8z4yKz3Nj6bLdtBqw6A9qXLBCfWfD/p9YKDZNFP/6+u9teUirOgiBSq7kXWy
mtBm0I3pz33EomCuSJzLj/Mj/fkKs+425jPFcZboJdZpCyBhAkEA8mtGUGYuAZwV
RKBDkf1bz5EyPBGV+9CyXa6pd6md61APY0j+qhb1w9ADfHKkAzfoilhpucznRhaz
kAheqMPAMwJBAOlQEx2Ytc8TxfFqhF8RPTODe2N0jBBvsvJ85k7vNiQ+hnmaAray
XS6pCbZdvmGHYKlz3MVGeis/UJKDdSzE0gkCQQCoZijkNPcEmz6S+5m00oFywXRa
EgVUdndRaMHEpIlVK7pkyBJQab60Fc42JxUUP0RExoI7VcHbCG4YQhgvuDvNAkBQ
CUolcwebe/sBcDrsqetGyqn/WjHaSZcnnDUdiu4VzOUwveaEafeRVCeiydHPfzNn
rflkK2MphtTLDhGaRAKRAkASKlhV8aTBzTty/V3XMQfFVIAdHCyEIGMdjDDSzPly
shZCn66IyIze8j5Q4ZLcRz6GPglHdrkBnyt4QFuGurpl
-----END 私鑰-----`

	public = `-----BEGIN 公鑰-----
MIGJAoGBANzvdp8jGpg4eDzSm4MgxiupQCJOLwSJNUMSI71gTf5XFG83Sxql7fPH
VR2GAifeII9TPIja/A0AMh3cuO4iOR0Jx0HZ8esFNtzLq7TnjkedjjYX1pDtwCvX
rxsdyqFCgpydr2L2e6Q77DtKjUn0Lpavwnh7j3berv5PvPttl5fLAgMBAAE=
-----END 公鑰-----`
)

func digitalSign(privateKey, plainText string) (signText []byte, err error) {
	var (
		pemBlock, _   = pem.Decode([]byte(privateKey))
		privateStream *rsa.PrivateKey
		plainHash     = sha256.Sum256([]byte(plainText))
	)

	if privateStream, err = x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err != nil {
		return
	}
	if signText, err = rsa.SignPKCS1v15(rand.Reader, privateStream, crypto.SHA256, plainHash[:]); err != nil {
		return
	}
	return
}

func digitalVerify(publicKeyByte, plainText string, signText []byte) (ok bool, err error) {
	var (
		pemBlock, _  = pem.Decode([]byte(publicKeyByte))
		publicStream *rsa.PublicKey
		plainHash    = sha256.Sum256([]byte(plainText))
	)

	if publicStream, err = x509.ParsePKCS1PublicKey(pemBlock.Bytes); err != nil {
		return
	}

	if err = rsa.VerifyPKCS1v15(publicStream, crypto.SHA256, plainHash[:], signText); err != nil {
		return
	}
	return true, nil
}

func main() {
	text, err := digitalSign(private, "張三李四王五趙柳")
	ok, err := digitalVerify(public, "張三李四王五趙柳", text)
	fmt.Println(ok)
	fmt.Println(err)
}

總結
在Go語言API中公鑰私鑰的注釋頭尾也需要加上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM