golang的SHA1withRSA的實現

背景

有一個與第三方系統對接的需求,協議是比較簡單,但發現協議有個字段是簽名,而怎麼簽名並無細說,從提供的demo裏看是採用java的SHA1withRSA,然而百度了一翻沒有看到介紹,出動Google也沒有看到相關的信息,從而猜想應該是JAVA特有的封裝,應該是先進行一個SHA1的散列,再進行一次RSA的加密,後來從這裏 個人猜想應該是對的。java

解決思路

X509看了裏面的代碼,有看到SHA1withRSA的定義,但彷佛沒看到例子及使用。後來不停地找資料,發現這裏 講得比較細,也比較符合個人狀況,因而試用了一下居然能夠了,解決了我這幾天的煩惱啊。主要是如下這段:node

block, _ := pem.Decode([]byte(key))
    if block == nil {       // 失敗狀況
   }

    private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    if err != nil {
        ...
    }

    h := crypto.Hash.New(crypto.SHA1)
    h.Write(data)
    hashed := h.Sum(nil)

    // 進行rsa加密簽名
    signedData, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), crypto.SHA1, hashed)
    ...

關於證書

對方給的證書是windows下的p12,通常linux會採用pem的格式,不過這個openssl能夠搞定,用如下命令就能轉linux

openssl pkcs12 -out out.pem -in in.p12 -nodes -nocerts

若是是本身生成祕鑰,能夠直接採用golang

openssl genrsa -out rsa_private_key.pem 1024

個人封裝

若是哪位大神有更好的解決方案能夠告訴我一下!segmentfault

package common

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

type SHAwithRSA struct {
	privateKey *rsa.PrivateKey
}

func (this *SHAwithRSA) SetPriKey(pkey []byte) {
	block, _ := pem.Decode(pkey)
	if block == nil {
		fmt.Println("pem.Decode err")
		return
	}

	//private, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		fmt.Println("ParsePKCS8PrivateKey err", err)
		return
	}

	this.privateKey = private.(*rsa.PrivateKey)

	return
}

func (this *SHAwithRSA) Sign(data string) (string, error) {

	h := crypto.Hash.New(crypto.SHA1)
	h.Write([]byte(data))
	hashed := h.Sum(nil)

	signature, err := rsa.SignPKCS1v15(rand.Reader, this.privateKey,
		crypto.SHA1, hashed)
	if err != nil {
		fmt.Println("Error from signing: %s\n", err)
		return "", err
	}

	fmt.Printf("Signature: %x\n", signature)
	signRet := fmt.Sprintf("%x", signature)
	fmt.Printf("sigRet: %s\n", signRet)

	return signRet, nil
}

參考資料

相關文章
相關標籤/搜索