初始化项目
This commit is contained in:
99
trunk/goutil/securityUtil/aes.go
Normal file
99
trunk/goutil/securityUtil/aes.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidBlockSize indicates hash blocksize <= 0.
|
||||
ErrInvalidBlockSize = errors.New("invalid blocksize")
|
||||
|
||||
// ErrInvalidPKCS7Data indicates bad input to PKCS7 pad or unpad.
|
||||
ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)")
|
||||
|
||||
// ErrInvalidPKCS7Padding indicates PKCS7 unpad fails to bad input.
|
||||
ErrInvalidPKCS7Padding = errors.New("invalid padding on input")
|
||||
)
|
||||
|
||||
// pkcs7Pad right-pads the given byte slice with 1 to n bytes, where
|
||||
// n is the block size. The size of the result is x times n, where x
|
||||
// is at least 1.
|
||||
func pkcs7Pad(b []byte, blocksize int) ([]byte, error) {
|
||||
if b == nil || len(b) == 0 {
|
||||
return nil, ErrInvalidPKCS7Data
|
||||
}
|
||||
if blocksize <= 0 {
|
||||
return nil, ErrInvalidBlockSize
|
||||
}
|
||||
n := blocksize - (len(b) % blocksize)
|
||||
pb := make([]byte, len(b)+n)
|
||||
copy(pb, b)
|
||||
copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
||||
// pkcs7Unpad validates and unpads data from the given bytes slice.
|
||||
// The returned value will be 1 to n bytes smaller depending on the
|
||||
// amount of padding, where n is the block size.
|
||||
func pkcs7Unpad(b []byte, blocksize int) ([]byte, error) {
|
||||
if b == nil || len(b) == 0 {
|
||||
return nil, ErrInvalidPKCS7Data
|
||||
}
|
||||
if blocksize <= 0 {
|
||||
return nil, ErrInvalidBlockSize
|
||||
}
|
||||
if len(b)%blocksize != 0 {
|
||||
return nil, ErrInvalidPKCS7Padding
|
||||
}
|
||||
|
||||
c := b[len(b)-1]
|
||||
n := int(c)
|
||||
if n == 0 || n > len(b) {
|
||||
return nil, ErrInvalidPKCS7Padding
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
if b[len(b)-n+i] != c {
|
||||
return nil, ErrInvalidPKCS7Padding
|
||||
}
|
||||
}
|
||||
|
||||
return b[:len(b)-n], nil
|
||||
}
|
||||
|
||||
func AESEncrypt_CBC_Pkcs7(src []byte, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
src, err = pkcs7Pad(src, block.BlockSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockmode := cipher.NewCBCEncrypter(block, key)
|
||||
blockmode.CryptBlocks(src, src)
|
||||
|
||||
return src, nil
|
||||
}
|
||||
|
||||
func AESDecrypt_CBC_Pkcs7(src []byte, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockmode := cipher.NewCBCDecrypter(block, key)
|
||||
blockmode.CryptBlocks(src, src)
|
||||
src, err = pkcs7Unpad(src, block.BlockSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return src, nil
|
||||
}
|
||||
95
trunk/goutil/securityUtil/aes_test.go
Normal file
95
trunk/goutil/securityUtil/aes_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
|
||||
// const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
// const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
)
|
||||
|
||||
var coder = base64.NewEncoding(base64Table)
|
||||
|
||||
// 对字符串进行Base64编码
|
||||
func Base64Encode(src string) string {
|
||||
if src == "" {
|
||||
return src
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString([]byte(src))
|
||||
}
|
||||
|
||||
// 对字符串进行Base64解码
|
||||
func Base64Encode2(src []byte) []byte {
|
||||
if len(src) == 0 {
|
||||
return src
|
||||
}
|
||||
|
||||
return []byte(base64.StdEncoding.EncodeToString(src))
|
||||
}
|
||||
|
||||
// 对字符数组进行Base64编码
|
||||
func Base64Decode(src string) (string, error) {
|
||||
if src == "" {
|
||||
return src, nil
|
||||
}
|
||||
|
||||
bytes, err := coder.DecodeString(src)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
// 对字符数组进行Base64解码
|
||||
func Base64Decode2(src []byte) ([]byte, error) {
|
||||
if len(src) == 0 {
|
||||
return src, nil
|
||||
}
|
||||
|
||||
return coder.DecodeString(string(src))
|
||||
}
|
||||
|
||||
func TestEncryptAndDecrypt(t *testing.T) {
|
||||
x := []byte("6d15fbbf-4913-40f5-afd1-c02effc2373a")
|
||||
key := []byte("WB6aEKK5LoGpetJv")
|
||||
x1, _ := AESEncrypt_CBC_Pkcs7(x, key)
|
||||
x1_base64 := Base64Encode2(x1)
|
||||
x1_base64_str := string(x1_base64)
|
||||
fmt.Printf("Base64 of encrypted data:%s\n", x1_base64_str)
|
||||
|
||||
// x1_base64_str = "OoV781MTCRIEKBaWDn4NDuS3Iq1stwnORQA30Ip/eewTEzaNDQl/TgVQU09Bm7pcIP6GxGfzO7vKhRITgKCghpTi9/D+oz/GdKn8KjF/gmE="
|
||||
x2_init_str, _ := Base64Decode(x1_base64_str)
|
||||
x2_init := []byte(x2_init_str)
|
||||
fmt.Printf("x2_init:%d\n", len(x2_init))
|
||||
|
||||
x2, _ := AESDecrypt_CBC_Pkcs7(x2_init, key)
|
||||
fmt.Printf("Decrypted data:%s\n", string(x2))
|
||||
if string(x) != string(x2) {
|
||||
t.Errorf("Expected %s, but got %s", string(x), string(x2))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
key := []byte("WB6aEKK5LoGpetJv")
|
||||
x2_init_str, _ := Base64Decode("Oit72+aWraykW7i0e/q+zZ77w5yEU/5KuNpRYoJaxpw93i6zWKiFB8c6/PIedZxz")
|
||||
x2_init := []byte(x2_init_str)
|
||||
x2, _ := AESDecrypt_CBC_Pkcs7(x2_init, key)
|
||||
fmt.Printf("Decrypted data:%s\n", string(x2))
|
||||
|
||||
x2_init_str, _ = Base64Decode("r0KHpfSmQ8jmx/FR4IJPOGBLTYF9lDRWbo9P8lIwekjkkU8BOO0QvfypgHZRIJWS")
|
||||
x2_init = []byte(x2_init_str)
|
||||
x2, _ = AESDecrypt_CBC_Pkcs7(x2_init, key)
|
||||
fmt.Printf("Decrypted data:%s\n", string(x2))
|
||||
|
||||
x2_init_str, _ = Base64Decode("ev2P8zTEnebpBm43Dd8YlA==")
|
||||
x2_init = []byte(x2_init_str)
|
||||
x2, _ = AESDecrypt_CBC_Pkcs7(x2_init, key)
|
||||
fmt.Printf("Decrypted data:%s\n", string(x2))
|
||||
}
|
||||
11
trunk/goutil/securityUtil/doc.go
Normal file
11
trunk/goutil/securityUtil/doc.go
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
这个包包含安全方面的util对象和方法,例如md5,sha1,rsa等。
|
||||
使用时需要先import "goutil.security"。
|
||||
|
||||
当前这里面包括有2个对象md5和sha1,在使用时,可以参照如下方式
|
||||
s := "hello world"
|
||||
result := Md5String(s, true)
|
||||
*/
|
||||
package securityUtil
|
||||
|
||||
//此文档是专为写包注释而添加的,无实际意义。因此其它文件也不用再添加包注释了
|
||||
63
trunk/goutil/securityUtil/hmac.go
Normal file
63
trunk/goutil/securityUtil/hmac.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
// Hmac-SHA1编码
|
||||
// source:编码原数据
|
||||
// key:编码密钥
|
||||
// 返回值:编码结果
|
||||
func HmacSha1(source, key string) (result []byte, err error) {
|
||||
mac := hmac.New(sha1.New, []byte(key))
|
||||
if _, err = mac.Write([]byte(source)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return mac.Sum(nil), nil
|
||||
}
|
||||
|
||||
// Hmac-SHA1 Base64编码
|
||||
// source:编码原数据
|
||||
// key:编码密钥
|
||||
// 返回值:编码结果
|
||||
func Base64HmacSha1(source, key string) (result string, err error) {
|
||||
mac := hmac.New(sha1.New, []byte(key))
|
||||
if _, err = mac.Write([]byte(source)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
bytes := mac.Sum(nil)
|
||||
result = base64.StdEncoding.EncodeToString(bytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Hmac-SHA256编码
|
||||
// source:编码原数据
|
||||
// key:编码密钥
|
||||
// 返回值:编码结果
|
||||
func HmacSha256(source, key string) (result []byte, err error) {
|
||||
mac := hmac.New(sha256.New, []byte(key))
|
||||
if _, err = mac.Write([]byte(source)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return mac.Sum(nil), nil
|
||||
}
|
||||
|
||||
// Hmac-SHA512编码
|
||||
// source:编码原数据
|
||||
// key:编码密钥
|
||||
// 返回值:编码结果
|
||||
func HmacSha512(source, key string) (result []byte, err error) {
|
||||
mac := hmac.New(sha512.New, []byte(key))
|
||||
if _, err = mac.Write([]byte(source)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return mac.Sum(nil), nil
|
||||
}
|
||||
38
trunk/goutil/securityUtil/hmac_test.go
Normal file
38
trunk/goutil/securityUtil/hmac_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHmacSha1(t *testing.T) {
|
||||
source := "oauthConsumerKey=1Nocz0wk0Hi8oGgSosogC4K4k&oauthToken=TOKEN_%2B8vQAR1eoD3ujiGstjzdyakEgbkyvWhfzF1fChQJ46EH07n%2FQvrazkMqy%2BhuprqU&oauthSignatureMethod=HMAC-SHA1&oauthTimestamp=1508486834&oauthNonce=5409983431934290948&oauthVersion=1.0&"
|
||||
key := "f724054cbBF8710D2c3a2500Ec65Fa9F&"
|
||||
sign := "+2zYxghf5BOqAXp/o9yax4TI56c="
|
||||
|
||||
buf, err := HmacSha1(source, key)
|
||||
if err != nil {
|
||||
t.Fatalf("Hmac-SHA1编码错误:%v", err)
|
||||
}
|
||||
|
||||
base64Result := base64.StdEncoding.EncodeToString(buf)
|
||||
if base64Result != sign {
|
||||
t.Fatalf("Hmac-SHA1编码结果不一致")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHmacSha256(t *testing.T) {
|
||||
source := "oauthConsumerKey=1Nocz0wk0Hi8oGgSosogC4K4k&oauthToken=TOKEN_%2B8vQAR1eoD3ujiGstjzdyakEgbkyvWhfzF1fChQJ46EH07n%2FQvrazkMqy%2BhuprqU&oauthSignatureMethod=HMAC-SHA1&oauthTimestamp=1508486834&oauthNonce=5409983431934290948&oauthVersion=1.0&"
|
||||
key := "f724054cbBF8710D2c3a2500Ec65Fa9F&"
|
||||
sign := "6GsbOxY0ldpTqGIdIATUuJceMgCGSwcylODhXxPHZLE="
|
||||
|
||||
buf, err := HmacSha256(source, key)
|
||||
if err != nil {
|
||||
t.Fatalf("Hmac-SHA256编码错误:%v", err)
|
||||
}
|
||||
|
||||
base64Result := base64.StdEncoding.EncodeToString(buf)
|
||||
if base64Result != sign {
|
||||
t.Fatalf("Hmac-SHA256编码结果不一致")
|
||||
}
|
||||
}
|
||||
38
trunk/goutil/securityUtil/md5.go
Normal file
38
trunk/goutil/securityUtil/md5.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 对字符串进行MD5加密,并且可以选择返回大、小写
|
||||
// s:输入字符串
|
||||
// ifUpper:输出是否大写
|
||||
// 返回值:md5加密后的字符串
|
||||
func Md5String(s string, ifUpper bool) string {
|
||||
if len(s) == 0 {
|
||||
panic(errors.New("input string can't be empty"))
|
||||
}
|
||||
|
||||
return Md5Bytes([]byte(s), ifUpper)
|
||||
}
|
||||
|
||||
// 对字符数组进行MD5加密,并且可以选择返回大、小写
|
||||
// b:输入字符数组
|
||||
// ifUpper:输出是否大写
|
||||
// 返回值:md5加密后的字符串
|
||||
func Md5Bytes(b []byte, ifUpper bool) string {
|
||||
if len(b) == 0 {
|
||||
panic(errors.New("input []byte can't be empty"))
|
||||
}
|
||||
|
||||
md5Instance := md5.New()
|
||||
md5Instance.Write(b)
|
||||
result := md5Instance.Sum([]byte(""))
|
||||
if ifUpper {
|
||||
return fmt.Sprintf("%X", result)
|
||||
} else {
|
||||
return fmt.Sprintf("%x", result)
|
||||
}
|
||||
}
|
||||
40
trunk/goutil/securityUtil/md5_test.go
Normal file
40
trunk/goutil/securityUtil/md5_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
ExpectedUpperString = "5EB63BBBE01EEED093CB22BB8F5ACDC3"
|
||||
ExpectedLowerString = "5eb63bbbe01eeed093cb22bb8f5acdc3"
|
||||
)
|
||||
|
||||
func TestMd5String(t *testing.T) {
|
||||
s := fmt.Sprintf("&GroupId=%s&ClusterId=%s&IP=%s&ServiceName=%s&ServiceId=%s&Timestamp=%d&GroupSecret=%s",
|
||||
"DSN", "DSN_AREA1", "10.255.0.226", "gs1", "4fa2b870-f8eb-4a47-a4bb-becf14f3b628", 1649212351304327500, "88F5BC56-96D3-4021-A358-BBDAFFBF772A")
|
||||
//s := "hello world"
|
||||
result := Md5String(s, true)
|
||||
if result != ExpectedUpperString {
|
||||
t.Errorf("Md5String(\"hello world\") failed.Got %s, expected %s", result, ExpectedUpperString)
|
||||
}
|
||||
|
||||
result = Md5String(s, false)
|
||||
if result != ExpectedLowerString {
|
||||
t.Errorf("Md5String(\"hello world\") failed.Got %s, expected %s", result, ExpectedLowerString)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMd5Bytes(t *testing.T) {
|
||||
s := "hello world"
|
||||
b := []byte(s)
|
||||
result := Md5Bytes(b, true)
|
||||
if result != ExpectedUpperString {
|
||||
t.Errorf("Md5String(\"hello world\") failed.Got %s, expected %s", result, ExpectedUpperString)
|
||||
}
|
||||
|
||||
result = Md5Bytes(b, false)
|
||||
if result != ExpectedLowerString {
|
||||
t.Errorf("Md5String(\"hello world\") failed.Got %s, expected %s", result, ExpectedLowerString)
|
||||
}
|
||||
}
|
||||
251
trunk/goutil/securityUtil/rsa.go
Normal file
251
trunk/goutil/securityUtil/rsa.go
Normal file
@@ -0,0 +1,251 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RsaSha256验证签名
|
||||
// publicKey:公钥
|
||||
// source:原字符串
|
||||
// targetSign:用以验证的目标签名(会进行Base64解码)
|
||||
// 返回值:返回nil为成功
|
||||
func VerifyRsaWithSha256(publicKey, source, targetSign string) error {
|
||||
//未加标记的PEM密钥加上公钥标记
|
||||
if !strings.HasPrefix(publicKey, "-") {
|
||||
publicKey = fmt.Sprintf(`-----BEGIN PUBLIC KEY-----
|
||||
%s
|
||||
-----END PUBLIC KEY-----`, publicKey)
|
||||
}
|
||||
|
||||
//base64解码目标签名
|
||||
signBuf, err := base64.StdEncoding.DecodeString(targetSign)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//解码公钥
|
||||
block, _ := pem.Decode([]byte(publicKey))
|
||||
if block == nil {
|
||||
return fmt.Errorf("RSA.VerifyRsaWithSha256,Block is nil,public key error!")
|
||||
}
|
||||
|
||||
//转化为公钥对象
|
||||
pubObj, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pub := pubObj.(*rsa.PublicKey)
|
||||
|
||||
//验证签名
|
||||
err = rsa.VerifyPKCS1v15(pub, crypto.SHA256, Sha256Bytes([]byte(source)), signBuf)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// RsaSha1验证签名
|
||||
// publicKey:公钥
|
||||
// source:原字符串
|
||||
// targetSign:用以验证的目标签名(会进行Base64解码)
|
||||
// 返回值:返回nil为成功
|
||||
func VerifyRsaWithSha1(publicKey, source, targetSign string) error {
|
||||
//未加标记的PEM密钥加上公钥标记
|
||||
if !strings.HasPrefix(publicKey, "-") {
|
||||
publicKey = fmt.Sprintf(`-----BEGIN PUBLIC KEY-----
|
||||
%s
|
||||
-----END PUBLIC KEY-----`, publicKey)
|
||||
}
|
||||
|
||||
//base64解码目标签名
|
||||
signBuf, err := base64.StdEncoding.DecodeString(targetSign)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//解码公钥
|
||||
block, _ := pem.Decode([]byte(publicKey))
|
||||
if block == nil {
|
||||
return fmt.Errorf("RSA.VerifyRsaWithSha1,Block is nil,public key error!")
|
||||
}
|
||||
|
||||
//转化为公钥对象
|
||||
pubObj, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pub := pubObj.(*rsa.PublicKey)
|
||||
|
||||
//验证签名
|
||||
err = rsa.VerifyPKCS1v15(pub, crypto.SHA1, Sha1StringToBytes(source), signBuf)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// 对字符数组进行SHA1加密
|
||||
// b:输入字符数组
|
||||
// 返回值:sha1加密后的原数据
|
||||
func Sha1StringToBytes(b string) []byte {
|
||||
if len(b) == 0 {
|
||||
panic(errors.New("input []byte can't be empty"))
|
||||
}
|
||||
|
||||
sha1Instance := sha1.New()
|
||||
sha1Instance.Write([]byte(b))
|
||||
result := sha1Instance.Sum(nil)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func packageData(originalData []byte, packageSize int) (r [][]byte) {
|
||||
var src = make([]byte, len(originalData))
|
||||
copy(src, originalData)
|
||||
|
||||
r = make([][]byte, 0)
|
||||
if len(src) <= packageSize {
|
||||
return append(r, src)
|
||||
}
|
||||
for len(src) > 0 {
|
||||
var p = src[:packageSize]
|
||||
r = append(r, p)
|
||||
src = src[packageSize:]
|
||||
if len(src) <= packageSize {
|
||||
r = append(r, src)
|
||||
break
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// RSAEncrypt 数据加密
|
||||
// plaintext:待加密的数据
|
||||
// key:公钥
|
||||
// 返回值:
|
||||
// []byte:加密后的数据
|
||||
// error:错误信息
|
||||
func RSAEncrypt(plaintext, key []byte) ([]byte, error) {
|
||||
var err error
|
||||
var block *pem.Block
|
||||
block, _ = pem.Decode(key)
|
||||
if block == nil {
|
||||
return nil, errors.New("public key error")
|
||||
}
|
||||
|
||||
var pubInterface interface{}
|
||||
pubInterface, err = x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pub = pubInterface.(*rsa.PublicKey)
|
||||
|
||||
var data = packageData(plaintext, pub.N.BitLen()/8-11)
|
||||
var cipherData []byte = make([]byte, 0, 0)
|
||||
|
||||
for _, d := range data {
|
||||
var c, e = rsa.EncryptPKCS1v15(rand.Reader, pub, d)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
cipherData = append(cipherData, c...)
|
||||
}
|
||||
|
||||
return cipherData, nil
|
||||
}
|
||||
|
||||
// RSADecrypt 数据解密
|
||||
// plaintext:待解密的数据
|
||||
// key:私钥
|
||||
// 返回值:
|
||||
// []byte:解密后的数据
|
||||
// error:错误信息
|
||||
func RSADecrypt(ciphertext, key []byte) ([]byte, error) {
|
||||
var err error
|
||||
var block *pem.Block
|
||||
block, _ = pem.Decode(key)
|
||||
if block == nil {
|
||||
return nil, errors.New("private key error")
|
||||
}
|
||||
|
||||
var pri *rsa.PrivateKey
|
||||
pri, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data = packageData(ciphertext, pri.PublicKey.N.BitLen()/8)
|
||||
var plainData []byte = make([]byte, 0, 0)
|
||||
|
||||
for _, d := range data {
|
||||
var p, e = rsa.DecryptPKCS1v15(rand.Reader, pri, d)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
plainData = append(plainData, p...)
|
||||
}
|
||||
return plainData, nil
|
||||
}
|
||||
|
||||
// 基于RSA PKCS1V15进行签名
|
||||
// src:待签名的原始字符串
|
||||
// key:签名用的私钥
|
||||
// hash:签名配置
|
||||
// 返回值:
|
||||
// []byte:得到的签名字节流
|
||||
// error:错误信息
|
||||
func SignPKCS1v15(src, key []byte, hash crypto.Hash) ([]byte, error) {
|
||||
var h = hash.New()
|
||||
h.Write(src)
|
||||
var hashed = h.Sum(nil)
|
||||
|
||||
var err error
|
||||
var block *pem.Block
|
||||
block, _ = pem.Decode(key)
|
||||
if block == nil {
|
||||
return nil, errors.New("private key error")
|
||||
}
|
||||
|
||||
var pri *rsa.PrivateKey
|
||||
pri, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rsa.SignPKCS1v15(rand.Reader, pri, hash, hashed)
|
||||
}
|
||||
|
||||
// 验证RSA PKCS1V15进行签名
|
||||
// src:待签名的原始字符串
|
||||
// sig:签名字节流
|
||||
// key:签名用的私钥
|
||||
// hash:签名配置
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func VerifyPKCS1v15(src, sig, key []byte, hash crypto.Hash) error {
|
||||
var h = hash.New()
|
||||
h.Write(src)
|
||||
var hashed = h.Sum(nil)
|
||||
|
||||
var err error
|
||||
var block *pem.Block
|
||||
block, _ = pem.Decode(key)
|
||||
if block == nil {
|
||||
return errors.New("public key error")
|
||||
}
|
||||
|
||||
var pubInterface interface{}
|
||||
pubInterface, err = x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var pub = pubInterface.(*rsa.PublicKey)
|
||||
|
||||
return rsa.VerifyPKCS1v15(pub, hash, hashed, sig)
|
||||
}
|
||||
27
trunk/goutil/securityUtil/rsa_test.go
Normal file
27
trunk/goutil/securityUtil/rsa_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVerifyRsaWithSha1(t *testing.T) {
|
||||
publicKey := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmreYIkPwVovKR8rLHWlFVw7YDfm9uQOJKL89Smt6ypXGVdrAKKl0wNYc3/jecAoPi2ylChfa2iRu5gunJyNmpWZzlCNRIau55fxGW0XEu553IiprOZcaw5OuYGlf60ga8QT6qToP0/dpiL/ZbmNUO9kUhosIjEu22uFgR+5cYyQIDAQAB"
|
||||
source := "notifyId=GC201710201145455410100040000&partnerOrder=601_2055_1508471145_42087&productName=元宝&productDesc=1000元宝&price=5000&count=1&attach=601_2055_1508471145_42087"
|
||||
sign := "JdzsJlVOgJ6gXTCJjWAXisyFeS0ztvB5m6WOgx9XqqdfxthLVC0gvxXdoqT1SnzzkaznebtbgvVrIeAFlyEBiVpShH76yZ9KO781wiBdJMY/BUwKkHlnMWjtFZx7pjqj6xBMoZ3HFl9j5loFYuYLMg+MDUCpvXV+Kg/wAqkkOnY="
|
||||
|
||||
err := VerifyRsaWithSha1(publicKey, source, sign)
|
||||
if err != nil {
|
||||
t.Fatalf("VerifyRsaWithSha1验证错误:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyRsaWithSha256(t *testing.T) {
|
||||
publicKey := "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJm8eeTR8mPWuPdCFo5boenHe+Yj8zC82ohIuTeMu+4QJuRK/MI+wtJlYheKtE0s4lXzL0rw/KQzMB+KO9F/WM0CAwEAAQ=="
|
||||
source := "accessMode=0&amount=6.00&bankId=HuaWei¬ifyTime=1500370048019&orderId=H20170718172707521578B0C13&orderTime=2017-07-18 17:27:07&payType=0&productName=元宝&requestId=606_2001_1500370020_19213&result=0&spending=0.00&tradeTime=2017-07-18 17:27:07&userName=900086000021763400"
|
||||
sign := "d9PDjSwgItg8eTTAYbP2OHD5t+F8wgrgjMOCXHXI7pe3qCe7sixraHmLrOQfFoAvxi4e2eYxZocN4QRoqD3/zw=="
|
||||
|
||||
err := VerifyRsaWithSha256(publicKey, source, sign)
|
||||
if err != nil {
|
||||
t.Fatalf("VerifyRsaWithSha256验证错误:%v", err)
|
||||
}
|
||||
}
|
||||
38
trunk/goutil/securityUtil/sha1.go
Normal file
38
trunk/goutil/securityUtil/sha1.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 对字符串进行SHA1加密,并且可以选择返回大、小写
|
||||
// s:输入字符串
|
||||
// ifUpper:输出是否大写
|
||||
// 返回值:md5加密后的字符串
|
||||
func Sha1String(s string, ifUpper bool) string {
|
||||
if len(s) == 0 {
|
||||
panic(errors.New("input string can't be empty"))
|
||||
}
|
||||
|
||||
return Sha1Bytes([]byte(s), ifUpper)
|
||||
}
|
||||
|
||||
// 对字符数组进行SHA1加密,并且可以选择返回大、小写
|
||||
// b:输入字符数组
|
||||
// ifUpper:输出是否大写
|
||||
// 返回值:md5加密后的字符串
|
||||
func Sha1Bytes(b []byte, ifUpper bool) string {
|
||||
if len(b) == 0 {
|
||||
panic(errors.New("input []byte can't be empty"))
|
||||
}
|
||||
|
||||
sha1Instance := sha1.New()
|
||||
sha1Instance.Write(b)
|
||||
result := sha1Instance.Sum([]byte(""))
|
||||
if ifUpper {
|
||||
return fmt.Sprintf("%X", result)
|
||||
} else {
|
||||
return fmt.Sprintf("%x", result)
|
||||
}
|
||||
}
|
||||
32
trunk/goutil/securityUtil/sha1_test.go
Normal file
32
trunk/goutil/securityUtil/sha1_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha1String(t *testing.T) {
|
||||
s := "hello world"
|
||||
result := Sha1String(s, true)
|
||||
if result != "2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED" {
|
||||
t.Errorf("Sha1String(\"hello world\") failed.Got %s, expected %s", result, "2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED")
|
||||
}
|
||||
|
||||
result = Sha1String(s, false)
|
||||
if result != "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" {
|
||||
t.Errorf("Sha1String(\"hello world\") failed.Got %s, expected %s", result, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSha1Bytes(t *testing.T) {
|
||||
s := "hello world"
|
||||
b := []byte(s)
|
||||
result := Sha1Bytes(b, true)
|
||||
if result != "2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED" {
|
||||
t.Errorf("Sha1Bytes(\"hello world\") failed.Got %s, expected %s", result, "2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED")
|
||||
}
|
||||
|
||||
result = Sha1Bytes(b, false)
|
||||
if result != "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" {
|
||||
t.Errorf("Sha1Bytes(\"hello world\") failed.Got %s, expected %s", result, "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed")
|
||||
}
|
||||
}
|
||||
40
trunk/goutil/securityUtil/sha256.go
Normal file
40
trunk/goutil/securityUtil/sha256.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 对字符串进行SHA256加密,并且可以选择返回大、小写
|
||||
// s:输入字符串
|
||||
// ifUpper:输出是否大写
|
||||
// 返回值:sha256加密后的十六进制字符串
|
||||
func Sha256String(s string, ifUpper bool) string {
|
||||
if len(s) == 0 {
|
||||
panic(errors.New("input string can't be empty"))
|
||||
}
|
||||
|
||||
buf := Sha256Bytes([]byte(s))
|
||||
|
||||
if ifUpper {
|
||||
return fmt.Sprintf("%X", buf)
|
||||
} else {
|
||||
return fmt.Sprintf("%x", buf)
|
||||
}
|
||||
}
|
||||
|
||||
// 对字符数组进行SHA256加密
|
||||
// b:输入字符数组
|
||||
// 返回值:sha256加密后的原数据
|
||||
func Sha256Bytes(b []byte) []byte {
|
||||
if len(b) == 0 {
|
||||
panic(errors.New("input []byte can't be empty"))
|
||||
}
|
||||
|
||||
sha1Instance := sha256.New()
|
||||
sha1Instance.Write(b)
|
||||
result := sha1Instance.Sum(nil)
|
||||
|
||||
return result
|
||||
}
|
||||
15
trunk/goutil/securityUtil/sha256_test.go
Normal file
15
trunk/goutil/securityUtil/sha256_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package securityUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha256(t *testing.T) {
|
||||
source := "oauthConsumerKey=1Nocz0wk0Hi8oGgSosogC4K4k&oauthToken=TOKEN_%2B8vQAR1eoD3ujiGstjzdyakEgbkyvWhfzF1fChQJ46EH07n%2FQvrazkMqy%2BhuprqU&oauthSignatureMethod=HMAC-SHA1&oauthTimestamp=1508486834&oauthNonce=5409983431934290948&oauthVersion=1.0&"
|
||||
sign := "813c8202a31c73371ae0bbe13cb49d65c94da3de2877345603271ca14e5e4bcd"
|
||||
|
||||
result := Sha256String(source, false)
|
||||
if result != sign {
|
||||
t.Fatalf("Sha256编码结果不一致")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user