cert.go 6.88 KB
Newer Older
wangp's avatar
wangp committed
1 2 3 4 5 6
package utils

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
wangp's avatar
wangp committed
7
	"crypto/sha1"
wangp's avatar
wangp committed
8 9
	"crypto/x509"
	"encoding/base64"
wangp's avatar
wangp committed
10
	"encoding/hex"
wangp's avatar
wangp committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
)

//func test() {
//	str := "from A to B 500RMB"
//	base64Sig, _ := RSASign([]byte(str), "../cert/OP00000003_private_key.pem")
//	fmt.Println("签名后的信息:", base64Sig)
//
//	err := RSAVerify([]byte(str), base64Sig, "../cert/OP00000003_cert.cert")
//	if err == nil {
//		fmt.Println("验证成功!")
//	} else {
//		fmt.Println("验证失败!")
//	}
//}

// 私钥签名过程
func RSASign(data []byte, filename string) (string, error) {
	// 1、选择hash算法,对需要签名的数据进行hash运算
	myhash := crypto.SHA256
	hashInstance := myhash.New()
	hashInstance.Write(data)
	hashed := hashInstance.Sum(nil)
	// 2、读取私钥文件,解析出私钥对象
	privateKey, err := ReadParsePrivaterKey(filename)
	if err != nil {
		return "", err
	}
	// 3、RSA数字签名(参数是随机数、私钥对象、哈希类型、签名文件的哈希串),生成base64编码的签名字符串
	bytes, err := rsa.SignPKCS1v15(rand.Reader, privateKey, myhash, hashed)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(bytes), nil
}

// 公钥验证签名过程
func RSAVerify(data []byte, base64Sig, filename string) error {
	// 1、对base64编码的签名内容进行解码,返回签名字节
	bytes, err := base64.StdEncoding.DecodeString(base64Sig)
	if err != nil {
		return err
	}
	// 2、选择hash算法,对需要签名的数据进行hash运算
	myhash := crypto.SHA256
	hashInstance := myhash.New()
	hashInstance.Write(data)
	hashed := hashInstance.Sum(nil)
	// 3、读取公钥文件,解析出公钥对象
	publicKey, err := ReadParsePublicKey(filename)
	if err != nil {
		return err
	}
	// 4、RSA验证数字签名(参数是公钥对象、哈希类型、签名文件的哈希串、签名后的字节)
	return rsa.VerifyPKCS1v15(publicKey, myhash, hashed, bytes)
}

// 读取公钥文件,解析出公钥对象
func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) {
	// 1、读取公钥文件,获取公钥字节
	publicKeyBytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	// 2、解码公钥字节,生成加密块对象
	block, _ := pem.Decode(publicKeyBytes)
	if block == nil {
		return nil, errors.New("公钥信息错误!")
	}
	// 3、解析DER编码的公钥,生成公钥接口
wangp's avatar
wangp committed
84 85 86
	//publicKeyInterface2, err := asn1.Marshal(block.Bytes)
	//fmt.Println(publicKeyInterface2)

wangp's avatar
wangp committed
87
	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
wangp's avatar
wangp committed
88
	//publicKeyInterface, err := x509.ParseCertificate(block.Bytes)
wangp's avatar
wangp committed
89
	if err != nil {
wangp's avatar
wangp committed
90
		fmt.Println(8888888888)
wangp's avatar
wangp committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
		return nil, err
	}
	// 4、公钥接口转型成公钥对象
	publicKey := publicKeyInterface.(*rsa.PublicKey)

	return publicKey, nil
}

// 读取私钥文件,解析出私钥对象
func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) {
	// 1、读取私钥文件,获取私钥字节
	privateKeyBytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	// 2、对私钥文件进行编码,生成加密块对象
	block, _ := pem.Decode(privateKeyBytes)
	fmt.Println(block.Type)
	if block == nil {
		return nil, errors.New("私钥信息错误!")
	}
	// 3、解析DER编码的私钥,生成私钥对象
	//privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	//if err != nil {
	//	return nil, err
	//}
	prkI, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	privateKey := prkI.(*rsa.PrivateKey)

	return privateKey, nil
wangp's avatar
wangp committed
124 125
}

wangp's avatar
wangp committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
//(3)签名:采用sha1算法进行签名并输出为hex格式(私钥PKCS8格式)
func RsaSignWithSha1Hex(data string, prvKey string) (string, error) {
	//keyByts, err := hex.DecodeString(prvKey)
	keyByts := []byte(prvKey)
	//if err != nil {
	//	fmt.Println("DecodeString err", err)
	//	return "", err
	//}
	privateKey, err := x509.ParsePKCS8PrivateKey(keyByts)
	if err != nil {
		fmt.Println("ParsePKCS8PrivateKey err", err)
		return "", err
	}
	h := sha1.New()
	h.Write([]byte([]byte(data)))
	hash := h.Sum(nil)
	signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA1, hash[:])
	if err != nil {
		fmt.Printf("Error from signing: %s\n", err)
		return "", err
	}
	out := hex.EncodeToString(signature)
	return out, nil
}

//(4)验签:对采用sha1算法进行签名后转base64格式的数据进行验签
func RsaVerySignWithSha1Base64(originalData, signData, pubKey string) error{
	sign, err := base64.StdEncoding.DecodeString(signData)
	if err != nil {
		return err
	}
	//public, _ := base64.StdEncoding.DecodeString(pubKey)
	public := []byte(pubKey)
	pub, err := x509.ParsePKIXPublicKey(public)
	if err != nil {
		return err
	}
	hash := sha1.New()
	hash.Write([]byte(originalData))
	return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA1, hash.Sum(nil), sign)
}

//func VerifySignCert(signData, sign, signType, aliPayPublicKeyPath string) (err error) {
//	var (
//		h         hash.Hash
//		hashs     crypto.Hash
//		block     *pem.Block
//		pubKey    *x509.Certificate
//		publicKey *rsa.PublicKey
//		ok        bool
//		bytes     []byte
//	)
//	if bytes, err = ioutil.ReadFile(aliPayPublicKeyPath); err != nil {
//		return fmt.Errorf("支付宝公钥文件读取失败: %w", err)
//	}
//	signBytes, _ := base64.StdEncoding.DecodeString(sign)
//	if block, _ = pem.Decode(bytes); block == nil {
//		return errors.New("支付宝公钥Decode错误")
//	}
//	if pubKey, err = x509.ParseCertificate(block.Bytes); err != nil {
//		return fmt.Errorf("x509.ParseCertificate:%w", err)
//	}
//	if publicKey, ok = pubKey.PublicKey.(*rsa.PublicKey); !ok {
//		return errors.New("支付宝公钥转换错误")
//	}
//	switch signType {
//	case "RSA":
//		hashs = crypto.SHA1
//	case "RSA2":
//		hashs = crypto.SHA256
//	default:
//		hashs = crypto.SHA256
//	}
//	h = hashs.New()
//	h.Write([]byte(signData))
//	return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
//}

//func VerifyDerCert(der_cert []byte, der_signing_cert []byte) (bool, error) {
func VerifyDerCert(der_cert []byte, filename string) (bool, error) {
	// 1、读取私钥文件,获取私钥字节
	der_signing_cert, err := ioutil.ReadFile(filename)
	if err != nil {
		return false, err
	}

	roots := x509.NewCertPool()
	opts := x509.VerifyOptions{
		Roots: roots,
	}

	// Verify key
	policy_cert, err := x509.ParseCertificate(der_signing_cert)
	if err != nil {
		return false, errors.New("Signing ParseCertificate fails")
	}
	roots.AddCert(policy_cert)
	fmt.Printf("Root cert: %x\n", der_signing_cert)

	// Verify key
	cert, err := x509.ParseCertificate(der_cert)
	if err != nil {
		return false, errors.New("Cert ParseCertificate fails")
	}

	roots.AddCert(policy_cert)
	opts.Roots = roots
	chains, err := cert.Verify(opts)
	if err != nil {
		return false, errors.New("Verify fails")
	}
	if chains != nil {
		return true, nil
	} else {
		return false, nil
	}
wangp's avatar
wangp committed
242

wangp's avatar
wangp committed
243
}