1
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"github.com/tjfoc/gmsm/sm4"
|
||||
@@ -164,6 +165,37 @@ func (a *API) signParamRSA(params map[string]interface{}, RSAPrivate string) (si
|
||||
return authorization, nil
|
||||
}
|
||||
|
||||
// signParamRSA 支付签名
|
||||
func (a *API) signParamPrivateKey(params map[string]interface{}, RSAPrivate string) (sig string, err error) {
|
||||
block, _ := pem.Decode([]byte(RSAPrivate))
|
||||
private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 签名参数
|
||||
body, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
//bodyData := base64.StdEncoding.EncodeToString(body)
|
||||
nonceStr := GenerateSecureRandomString(12)
|
||||
timeStamp := utils.Int64ToStr(time.Now().Unix())
|
||||
context := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", a.appID, a.serialNo, timeStamp, nonceStr, string(body))
|
||||
|
||||
// 进行rsa加密签名
|
||||
hashed := sha256.Sum256([]byte(context))
|
||||
signedData, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), crypto.SHA256, hashed[:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signData := base64.StdEncoding.EncodeToString(signedData)
|
||||
authorization := fmt.Sprintf(`LKLAPI-SHA256withRSA appid="%s",serial_no="%s",timestamp="%s",nonce_str="%s",signature="%s"`, a.appID, a.serialNo, timeStamp, nonceStr, signData)
|
||||
return authorization, nil
|
||||
}
|
||||
|
||||
// GenerateSecureRandomString 获取随机字符串
|
||||
func GenerateSecureRandomString(length int) string {
|
||||
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
@@ -234,3 +266,105 @@ func CallBackResultInfo(err error) *CallBackResult {
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
/****************************/
|
||||
|
||||
const (
|
||||
MAX_ENCRYPT_BLOCK = 117
|
||||
MAX_DECRYPT_BLOCK = 128
|
||||
)
|
||||
|
||||
func EncryptByPrivateKey(data []byte, privateKeyStr string) (string, error) {
|
||||
// 解析私钥
|
||||
block, _ := pem.Decode([]byte(privateKeyStr))
|
||||
if block == nil {
|
||||
return "", errors.New("failed to parse PEM block")
|
||||
}
|
||||
|
||||
privKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rsaPrivateKey := privKey.(*rsa.PrivateKey)
|
||||
|
||||
// 分段加密
|
||||
var encrypted []byte
|
||||
for offset := 0; offset < len(data); offset += MAX_ENCRYPT_BLOCK {
|
||||
end := offset + MAX_ENCRYPT_BLOCK
|
||||
if end > len(data) {
|
||||
end = len(data)
|
||||
}
|
||||
|
||||
chunk, err := rsa.SignPKCS1v15(nil, rsaPrivateKey, 0, data[offset:end])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
encrypted = append(encrypted, chunk...)
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(encrypted), nil
|
||||
}
|
||||
|
||||
// DecryptByPublicKey 解密函数:分段解密(公钥解密,需手动实现模幂运算)
|
||||
func DecryptByPublicKey(ciphertext []byte, publicKeyStr string) ([]byte, error) {
|
||||
// 解析公钥
|
||||
block, _ := pem.Decode([]byte(publicKeyStr))
|
||||
if block == nil {
|
||||
return nil, errors.New("failed to parse PEM block")
|
||||
}
|
||||
|
||||
pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rsaPublicKey := pubKey.(*rsa.PublicKey)
|
||||
|
||||
n := rsaPublicKey.N // 公钥模数
|
||||
e := rsaPublicKey.E // 公钥指数
|
||||
|
||||
blockSize := rsaPublicKey.Size() // 密钥的字节长度(128字节)
|
||||
var result bytes.Buffer
|
||||
|
||||
for len(ciphertext) > 0 {
|
||||
blockLen := blockSize
|
||||
if len(ciphertext) < blockLen {
|
||||
blockLen = len(ciphertext)
|
||||
}
|
||||
block := ciphertext[:blockLen]
|
||||
ciphertext = ciphertext[blockLen:]
|
||||
|
||||
// 将密文块转换为大整数
|
||||
c := new(big.Int).SetBytes(block)
|
||||
|
||||
// 计算 m = c^e mod n (由于私钥加密,公钥解密时需要e和n)
|
||||
m := new(big.Int).Exp(c, big.NewInt(int64(e)), n)
|
||||
|
||||
// 将结果转换为字节数组,并补零到固定长度
|
||||
mBytes := m.Bytes()
|
||||
if len(mBytes) < blockSize {
|
||||
padding := make([]byte, blockSize-len(mBytes))
|
||||
mBytes = append(padding, mBytes...)
|
||||
}
|
||||
// 写入最终结果
|
||||
result.Write(mBytes)
|
||||
}
|
||||
|
||||
// 移除PKCS1v15填充(需要实现填充剥离)
|
||||
// 注意:此处简化,实际需解析填充结构,比如去除00 02和填充字节
|
||||
return stripPKCS1v15Padding(result.Bytes()), nil
|
||||
}
|
||||
|
||||
// 移除PKCS1v15填充(示例逻辑,需根据实际填充调整)
|
||||
func stripPKCS1v15Padding(data []byte) []byte {
|
||||
var newData = make([]byte, 0, len(data))
|
||||
|
||||
for i := 0; i < len(data); i++ {
|
||||
if data[i] == 0x01 || data[i] == 0xFF || data[i] == 0x00 {
|
||||
continue
|
||||
}
|
||||
newData = append(newData, data[i])
|
||||
}
|
||||
return newData
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user