Files
2026-02-17 13:06:23 +08:00

118 lines
2.6 KiB
Go

package mmtls
import (
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
"crypto/hmac"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/pem"
"xiawan/wx/clientsdk/baseutils"
)
var verifyPubKey = []byte(`-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8uOhBSSfVijKin+SZO/0IXUrmf8l
9sa7VgqOIH/AO3Xb1MF4Xm25bBSb5znHsknQsNPSye3vVo80NUi2gEHw8g==
-----END PUBLIC KEY-----`)
// Sha256 Sha256
func Sha256(data []byte) []byte {
hash256 := sha256.New()
hash256.Write(data)
hashRet := hash256.Sum(nil)
return hashRet
}
// HmacHash256 HmacHash256
func HmacHash256(key []byte, data []byte) []byte {
hmacTool := hmac.New(sha256.New, key)
hmacTool.Write(data)
return hmacTool.Sum(nil)
}
// HkdfExpand HkdfExpand
func HkdfExpand(key, message []byte, outLen int) []byte {
result := make([]byte, 0)
count := outLen / 32
if outLen%32 != 0 {
count = count + 1
}
for i := 1; i <= count; i++ {
h := hmac.New(sha256.New, key)
tmp := append(message, byte(i))
tmp = append(result, tmp...)
h.Write(tmp)
result = append(result, h.Sum(nil)...)
}
return result[:outLen]
}
// AesGcmEncrypt AesGcmEncrypt
func AesGcmEncrypt(key, nonce, aad, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return []byte{}, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return []byte{}, nil
}
ciphertext := aesgcm.Seal(nil, nonce, data, aad)
return ciphertext, nil
}
// AesGcmDecrypt AesGcmDecrypt
func AesGcmDecrypt(key, nonce, aad, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
plain, err := aesgcm.Open(nil, nonce, data, aad)
if err != nil {
return nil, err
}
return plain, nil
}
// GetNonce GetNonce
func GetNonce(data []byte, seq uint32) []byte {
ret := make([]byte, len(data))
copy(ret, data)
seqBytes := baseutils.Int32ToBytes(seq)
baseOffset := 8
for index := 0; index < 4; index++ {
ret[baseOffset+index] = ret[baseOffset+index] ^ byte(seqBytes[index])
}
return ret
}
// ECDSAVerifyData 校验服务端握手数据
func ECDSAVerifyData(message []byte, signature []byte) (bool, error) {
block, _ := pem.Decode(verifyPubKey)
publicStream, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return false, err
}
//接口转换成公钥
publicKey := publicStream.(*ecdsa.PublicKey)
// 反序列化ecdsaSignature
ecdsaSignature := &EcdsaSignature{}
_, err = asn1.Unmarshal(signature, ecdsaSignature)
if err != nil {
return false, err
}
flag := ecdsa.Verify(publicKey, Sha256(message), ecdsaSignature.R, ecdsaSignature.S)
return flag, nil
}