本文整理匯總了Golang中github.com/chanxuehong/wechat/util.AESDecryptMsg函數的典型用法代碼示例。如果您正苦於以下問題:Golang AESDecryptMsg函數的具體用法?Golang AESDecryptMsg怎麽用?Golang AESDecryptMsg使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了AESDecryptMsg函數的9個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, irh InvalidRequestHandler) {
LogInfoln("[WECHAT_DEBUG] request uri:", r.RequestURI)
LogInfoln("[WECHAT_DEBUG] request remote-addr:", r.RemoteAddr)
LogInfoln("[WECHAT_DEBUG] request user-agent:", r.UserAgent())
switch r.Method {
case "POST": // 消息處理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes": // 安全模式, 兼容模式
signature := queryValues.Get("signature") // 隻讀取, 不驗證了
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
irh.ServeInvalidRequest(w, r, errors.New("msg_signature is empty"))
return
}
if len(msgSignature1) != 40 { // sha1
err := fmt.Errorf("the length of msg_signature mismatch, have: %d, want: 40", len(msgSignature1))
irh.ServeInvalidRequest(w, r, err)
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
irh.ServeInvalidRequest(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
irh.ServeInvalidRequest(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
irh.ServeInvalidRequest(w, r, errors.New("nonce is empty"))
return
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
irh.ServeInvalidRequest(w, r, err)
return
}
LogInfoln("[WECHAT_DEBUG] request msg http body:\r\n", string(reqBody))
var requestHttpBody RequestHttpBody
if err := xml.Unmarshal(reqBody, &requestHttpBody); err != nil {
irh.ServeInvalidRequest(w, r, err)
return
}
// 安全考慮驗證下 ToUserName
haveToUserName := requestHttpBody.ToUserName
if wantToUserName := srv.OriId(); wantToUserName != "" {
if len(haveToUserName) != len(wantToUserName) {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveToUserName, wantToUserName)
irh.ServeInvalidRequest(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(haveToUserName), []byte(wantToUserName)) != 1 {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveToUserName, wantToUserName)
irh.ServeInvalidRequest(w, r, err)
return
}
}
token := srv.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
irh.ServeInvalidRequest(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
irh.ServeInvalidRequest(w, r, err)
return
}
appId := srv.AppId()
aesKey := srv.CurrentAESKey()
random, rawMsgXML, err := util.AESDecryptMsg(encryptedMsgBytes, appId, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
irh.ServeInvalidRequest(w, r, err)
return
}
//.........這裏部分代碼省略.........
示例2: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler mp.ErrorHandler) {
switch r.Method {
case "POST": // 消息處理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes":
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
if len(msgSignature1) != 40 { // sha1
err := fmt.Errorf("the length of msg_signature mismatch, have: %d, want: 40", len(msgSignature1))
errHandler.ServeError(w, r, err)
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
var requestHttpBody RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
appId := srv.AppId()
// 安全考慮驗證下 AppId
haveAppId := requestHttpBody.AppId
if len(haveAppId) != len(appId) {
err = fmt.Errorf("the RequestHttpBody's AppId mismatch, have: %s, want: %s", haveAppId, appId)
errHandler.ServeError(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(haveAppId), []byte(appId)) != 1 {
err = fmt.Errorf("the RequestHttpBody's AppId mismatch, have: %s, want: %s", haveAppId, appId)
errHandler.ServeError(w, r, err)
return
}
token := srv.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, err := util.AESDecryptMsg(encryptedMsgBytes, appId, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, err = util.AESDecryptMsg(encryptedMsgBytes, appId, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
// 解密成功, 解析 MixedMessage
var mixedMsg MixedMessage
if err := xml.Unmarshal(rawMsgXML, &mixedMsg); err != nil {
errHandler.ServeError(w, r, err)
return
//.........這裏部分代碼省略.........
示例3: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, urlValues url.Values,
agentServer AgentServer, invalidRequestHandler InvalidRequestHandler) {
switch r.Method {
case "POST": // 消息處理
msgSignature1, timestampStr, nonce, err := parsePostURLQuery(urlValues)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 首先判斷簽名長度是否合法
if len(msgSignature1) != 40 {
err = fmt.Errorf("the length of msg_signature mismatch, have: %d, want: 40", len(msgSignature1))
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 解析 RequestHttpBody
var requestHttpBody RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
haveCorpId := requestHttpBody.CorpId
wantCorpId := agentServer.CorpId()
if len(haveCorpId) != len(wantCorpId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveCorpId, wantCorpId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(haveCorpId), []byte(wantCorpId)) != 1 {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveCorpId, wantCorpId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
haveAgentId := requestHttpBody.AgentId
wantAgentId := agentServer.AgentId()
if haveAgentId != wantAgentId && haveAgentId != 0 {
err = fmt.Errorf("the RequestHttpBody's AgentId mismatch, have: %d, want: %d", haveAgentId, wantAgentId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 此時
// 要麽 haveAgentId == wantAgentId,
// 要麽 haveAgentId == 0
agentToken := agentServer.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(agentToken, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 解密
EncryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
AESKey := agentServer.CurrentAESKey()
Random, RawMsgXML, err := util.AESDecryptMsg(EncryptedMsgBytes, wantCorpId, AESKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
LastAESKey := agentServer.LastAESKey()
if bytes.Equal(AESKey[:], LastAESKey[:]) || bytes.Equal(zeroAESKey[:], LastAESKey[:]) {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
AESKey = LastAESKey // NOTE
Random, RawMsgXML, err = util.AESDecryptMsg(EncryptedMsgBytes, wantCorpId, AESKey)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
}
// 解密成功, 解析 MixedMessage
var MixedMsg MixedMessage
if err = xml.Unmarshal(RawMsgXML, &MixedMsg); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
//.........這裏部分代碼省略.........
示例4: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv AgentServer, errHandler ErrorHandler) {
switch r.Method {
case "POST": // 消息處理
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
// 解析 RequestHttpBody
var requestHttpBody RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
haveCorpId := requestHttpBody.CorpId
wantCorpId := srv.CorpId()
if wantCorpId != "" && !security.SecureCompareString(haveCorpId, wantCorpId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveCorpId, wantCorpId)
errHandler.ServeError(w, r, err)
return
}
haveAgentId := requestHttpBody.AgentId
wantAgentId := srv.AgentId()
if wantCorpId != "" && wantAgentId != -1 {
if haveAgentId != wantAgentId && haveAgentId != 0 {
err = fmt.Errorf("the RequestHttpBody's AgentId mismatch, have: %d, want: %d", haveAgentId, wantAgentId)
errHandler.ServeError(w, r, err)
return
}
// 此時
// 要麽 haveAgentId == wantAgentId,
// 要麽 haveAgentId == 0
}
agentToken := srv.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(agentToken, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err := fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, aesAppId, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, aesAppId, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
if haveCorpId != string(aesAppId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName(==%s) mismatch the CorpId with aes encrypt(==%s)", haveCorpId, aesAppId)
errHandler.ServeError(w, r, err)
return
}
// 解密成功, 解析 MixedMessage
//.........這裏部分代碼省略.........
示例5: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 確保所有參數合法, r.Body 能正確讀取數據
func ServeHTTP(w http.ResponseWriter, r *http.Request,
urlValues url.Values, agent Agent, invalidRequestHandler InvalidRequestHandler) {
switch r.Method {
case "POST": // 消息處理
msgSignature1, timestampStr, nonce, err := parsePostURLQuery(urlValues)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
const signatureLen = sha1.Size * 2
if len(msgSignature1) != signatureLen {
err = fmt.Errorf("the length of msg_signature mismatch, have: %d, want: %d", len(msgSignature1), signatureLen)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, fmt.Errorf("can not parse timestamp(==%q) to int64, error: %s", timestampStr, err.Error()))
return
}
var requestHttpBody request.RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
agentCorpId := agent.GetCorpId()
if len(requestHttpBody.CorpId) != len(agentCorpId) {
err = fmt.Errorf("the message RequestHttpBody's ToUserName mismatch, have: %s, want: %s", requestHttpBody.CorpId, agentCorpId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(requestHttpBody.CorpId), []byte(agentCorpId)) != 1 {
err = fmt.Errorf("the message RequestHttpBody's ToUserName mismatch, have: %s, want: %s", requestHttpBody.CorpId, agentCorpId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
agentAgentId := agent.GetAgentId()
if requestHttpBody.AgentId != agentAgentId && requestHttpBody.AgentId != 0 {
err = fmt.Errorf("the message RequestHttpBody's AgentId mismatch, have: %d, want: %d", requestHttpBody.AgentId, agentAgentId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 此時
// 要麽 requestHttpBody.AgentId == agent.GetAgentId(),
// 要麽 requestHttpBody.AgentId == 0
msgSignature2 := util.MsgSignature(agent.GetToken(), timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check signature failed, have: %s, want: %s", msgSignature1, msgSignature2)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
EncryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
random, rawXMLMsg, err := util.AESDecryptMsg(EncryptedMsgBytes, agentCorpId, agent.GetAESKey())
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
var msgReq request.Request
if err := xml.Unmarshal(rawXMLMsg, &msgReq); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if requestHttpBody.CorpId != msgReq.ToUserName {
err = fmt.Errorf("the RequestHttpBody's ToUserName(==%s) mismatch the Request's ToUserName(==%s)", requestHttpBody.CorpId, msgReq.ToUserName)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if requestHttpBody.AgentId != msgReq.AgentId {
err = fmt.Errorf("the RequestHttpBody's AgentId(==%d) mismatch the Request's AgengId(==%d)", requestHttpBody.AgentId, msgReq.AgentId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
// 訂閱/取消訂閱 整個企業號, requestHttpBody.AgentId == 0
if requestHttpBody.AgentId != agentAgentId {
if msgReq.MsgType == request.MSG_TYPE_EVENT &&
(msgReq.Event == request.EVENT_TYPE_SUBSCRIBE || msgReq.Event == request.EVENT_TYPE_UNSUBSCRIBE) {
// do nothing
} else {
err = fmt.Errorf("the message Request's AgentId mismatch, have: %d, want: %d", msgReq.AgentId, agentAgentId)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
//.........這裏部分代碼省略.........
示例6: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler mp.ErrorHandler) {
mp.LogInfoln("[WECHAT_DEBUG] request uri:", r.RequestURI)
mp.LogInfoln("[WECHAT_DEBUG] request remote-addr:", r.RemoteAddr)
mp.LogInfoln("[WECHAT_DEBUG] request user-agent:", r.UserAgent())
switch r.Method {
case "POST": // 消息處理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes":
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
mp.LogInfoln("[WECHAT_DEBUG] request msg http body:\r\n", string(reqBody))
var requestHttpBody RequestHttpBody
if err := xml.Unmarshal(reqBody, &requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
haveAppId := requestHttpBody.AppId
wantAppId := srv.AppId()
if wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) {
err = fmt.Errorf("the RequestHttpBody's AppId mismatch, have: %s, want: %s", haveAppId, wantAppId)
errHandler.ServeError(w, r, err)
return
}
token := srv.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err = fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, aesAppId, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, aesAppId, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
if haveAppId != string(aesAppId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName(==%s) mismatch the AppId with aes encrypt(==%s)", haveAppId, aesAppId)
errHandler.ServeError(w, r, err)
return
}
mp.LogInfoln("[WECHAT_DEBUG] request msg raw xml:\r\n", string(rawMsgXML))
//.........這裏部分代碼省略.........
示例7: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler corp.ErrorHandler) {
corp.LogInfoln("[WECHAT_DEBUG] request uri:", r.RequestURI)
corp.LogInfoln("[WECHAT_DEBUG] request remote-addr:", r.RemoteAddr)
corp.LogInfoln("[WECHAT_DEBUG] request user-agent:", r.UserAgent())
switch r.Method {
case "POST": // 消息處理
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
if len(msgSignature1) != 40 { // sha1
err := fmt.Errorf("the length of msg_signature mismatch, have: %d, want: 40", len(msgSignature1))
errHandler.ServeError(w, r, err)
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
corp.LogInfoln("[WECHAT_DEBUG] request msg http body:\r\n", string(reqBody))
// 解析 RequestHttpBody
var requestHttpBody RequestHttpBody
if err := xml.Unmarshal(reqBody, &requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
haveSuiteId := requestHttpBody.SuiteId
wantSuiteId := srv.SuiteId()
if wantSuiteId != "" {
if len(haveSuiteId) != len(wantSuiteId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveSuiteId, wantSuiteId)
errHandler.ServeError(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(haveSuiteId), []byte(wantSuiteId)) != 1 {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveSuiteId, wantSuiteId)
errHandler.ServeError(w, r, err)
return
}
}
suiteToken := srv.SuiteToken()
// 驗證簽名
msgSignature2 := util.MsgSign(suiteToken, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, aesSuiteId, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, aesSuiteId, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
//.........這裏部分代碼省略.........
示例8: ServeHTTP
//.........這裏部分代碼省略.........
//if subtle.ConstantTimeCompare([]byte(signature1), []byte(signature2)) != 1 {
// err = fmt.Errorf("check signature failed, have: %s, want: %s", signature1, signature2)
// invalidRequestHandler.ServeInvalidRequest(w, r, err)
// return
//}
var requestHttpBody request.RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
wantToUserName := agent.GetId()
if len(requestHttpBody.ToUserName) != len(wantToUserName) {
err = fmt.Errorf("the message RequestHttpBody's ToUserName mismatch, have: %s, want: %s", requestHttpBody.ToUserName, wantToUserName)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if subtle.ConstantTimeCompare([]byte(requestHttpBody.ToUserName), []byte(wantToUserName)) != 1 {
err = fmt.Errorf("the message RequestHttpBody's ToUserName mismatch, have: %s, want: %s", requestHttpBody.ToUserName, wantToUserName)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
msgSignature2 := util.MsgSignature(agent.GetToken(), timestampStr, nonce, requestHttpBody.EncryptedMsg)
if subtle.ConstantTimeCompare([]byte(msgSignature1), []byte(msgSignature2)) != 1 {
err = fmt.Errorf("check signature failed, have: %s, want: %s", msgSignature1, msgSignature2)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
EncryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
AESKey := agent.GetCurrentAESKey()
random, rawXMLMsg, err := util.AESDecryptMsg(EncryptedMsgBytes, agent.GetAppId(), AESKey)
if err != nil {
// 嘗試上一個 AESKey
LastAESKey := agent.GetLastAESKey()
if bytes.Equal(zeroAESKey[:], LastAESKey[:]) || bytes.Equal(AESKey[:], LastAESKey[:]) {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
AESKey = LastAESKey // !!!
random, rawXMLMsg, err = util.AESDecryptMsg(EncryptedMsgBytes, agent.GetAppId(), AESKey)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
}
var msgReq request.Request
if err = xml.Unmarshal(rawXMLMsg, &msgReq); err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
if requestHttpBody.ToUserName != msgReq.ToUserName {
err = fmt.Errorf("the RequestHttpBody's ToUserName(==%s) mismatch the Request's ToUserName(==%s)", requestHttpBody.ToUserName, msgReq.ToUserName)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
aesMsgDispatch(w, r, &msgReq, rawXMLMsg, timestamp, nonce, AESKey, random, agent)
default: // 未知的加密類型
invalidRequestHandler.ServeInvalidRequest(w, r, errors.New("unknown encrypt_type"))
return
}
case "GET": // 首次驗證
signature1, timestamp, nonce, echostr, err := parseGetURLQuery(urlValues)
if err != nil {
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
const signatureLen = sha1.Size * 2
if len(signature1) != signatureLen {
err = fmt.Errorf("the length of signature mismatch, have: %d, want: %d", len(signature1), signatureLen)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
signature2 := util.Signature(agent.GetToken(), timestamp, nonce)
if subtle.ConstantTimeCompare([]byte(signature1), []byte(signature2)) != 1 {
err = fmt.Errorf("check signature failed, have: %s, want: %s", signature1, signature2)
invalidRequestHandler.ServeInvalidRequest(w, r, err)
return
}
io.WriteString(w, echostr)
}
}
示例9: ServeHTTP
// ServeHTTP 處理 http 消息請求
// NOTE: 調用者保證所有參數有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler ErrorHandler) {
switch r.Method {
case "POST": // 消息處理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes": // 安全模式, 兼容模式
signature := queryValues.Get("signature") // 隻讀取, 不做校驗
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
var requestHttpBody RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
// 安全考慮驗證下 ToUserName
haveToUserName := requestHttpBody.ToUserName
wantToUserName := srv.OriId()
if wantToUserName != "" && !security.SecureCompareString(haveToUserName, wantToUserName) {
err := fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveToUserName, wantToUserName)
errHandler.ServeError(w, r, err)
return
}
token := srv.Token()
// 驗證簽名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err := fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, haveAppIdBytes, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 嘗試用上一次的 AESKey 來解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, haveAppIdBytes, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
haveAppId := string(haveAppIdBytes)
wantAppId := srv.AppId()
if wantAppId != "" && wantAppId != haveAppId {
err := fmt.Errorf("the message's appid mismatch, have: %s, want: %s", haveAppId, wantAppId)
errHandler.ServeError(w, r, err)
return
}
// 解密成功, 解析 MixedMessage
var mixedMsg MixedMessage
if err := xml.Unmarshal(rawMsgXML, &mixedMsg); err != nil {
errHandler.ServeError(w, r, err)
return
}
// 安全考慮再次驗證 ToUserName
//.........這裏部分代碼省略.........