package mycrypto

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"service/library/logger"
)

type SHAwithRSACrypto struct {
	privateKey *rsa.PrivateKey
	publicKey  *rsa.PublicKey
}

func NewSHAwithRSACryptoFromString(rsaPrivateKeyStr string) (crypto *SHAwithRSACrypto, err error) {
	crypto = &SHAwithRSACrypto{}

	rsaPriKey, err := base64.StdEncoding.DecodeString(rsaPrivateKeyStr)
	if err != nil {
		logger.Error("read rsa primary key failed!", err)
		return
	}

	private, err := x509.ParsePKCS8PrivateKey(rsaPriKey)
	if err != nil {
		logger.Error("ParsePKCS8PrivateKey err", err)
		return
	}

	crypto.privateKey = private.(*rsa.PrivateKey)
	crypto.publicKey = &crypto.privateKey.PublicKey

	return
}

func (p *SHAwithRSACrypto) Sign(data []byte) (string, error) {

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

	signature, err := rsa.SignPKCS1v15(rand.Reader, p.privateKey,
		crypto.SHA1, hashed)
	if err != nil {
		logger.Error("Error from signing: %s\n", err)
		return "", err
	}
	sign := base64.StdEncoding.EncodeToString(signature) //转换成base64返回
	return sign, nil
}

func (p *SHAwithRSACrypto) Verify(data []byte, sign string) error {

	signBytes, err := base64.StdEncoding.DecodeString(sign)
	if err != nil {
		logger.Error("read sign bytes failed!", err)
		return err
	}

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

	return rsa.VerifyPKCS1v15(p.publicKey, crypto.SHA1, hashed, signBytes)
}