ruby on rails 关于微信企业号回调模式初步验证通过后再次签名验证失败的解决

这块我在8月17号的时候碰到过,再回调模式初步验证通过以后,微信服务器后续的信息会由原来的msg_signature. timestamp. nonce. echostr改为3个参数msg_signature. timestamp. nonce以及一串 xml信息,少了第四个参数,而签名验证的生成又必须要用到第4个参数echostr,否则单一的用timestamp. nonce. token生成的signature会跟接收的msg_signature不一致,导致验证是否为微信服务器发送的消息失败。

因此我们必须自己通过解读xml里的参数Encrypt拿到echostr来加入签名字符串的加密生成,同时也可以拿到其他解密后的xml信息生成一个hashmap进行后续的开发应用:

#@msg_encrypt就是我们要的Encrypt

  # 加密
  def encrypt(aes_key, text, corpid)
    text    = text.force_encoding("ASCII-8BIT")
    random  = SecureRandom.hex(8)
    msg_len = [text.length].pack("N")
    text    = "#{random}#{msg_len}#{text}#{corpid}"
    text    = encode(text)
    text    = handle_cipher(:encrypt, aes_key, text)
    Base64.encode64(text)
  end

  # 对密文进行解密.
  # text 需要解密的密文
  def decrypt(aes_key, text, corpid)
    status = 200
    text        = Base64.decode64(text)
    text        = handle_cipher(:decrypt, aes_key, text)
    result      = decode(text)
    content     = result[16...result.length]
    len_list    = content[0...4].unpack("N")
    xml_len     = len_list[0] 
    xml_content = content[4...4 + xml_len]
    from_corpid = content[xml_len+4...content.size]
    # TODO: refactor
    if corpid != from_corpid
      Rails.logger.debug("#{__FILE__}:#{__LINE__} Failure because #{corpid} != #{from_corpid}")
      status = 401
    end
    [xml_content, status]
  end


  # 对需要加密的明文进行填充补位
  # 返回补齐明文字符串
  def encode(text)
    # 计算需要填充的位数
    amount_to_pad = @BLOCK_SIZE - (text.length % @BLOCK_SIZE)
    amount_to_pad = @BLOCK_SIZE if amount_to_pad == 0
    # 获得补位所用的字符
    pad_chr = amount_to_pad.chr
    "#{text}#{pad_chr * amount_to_pad}"
  end


   def setup_wechat_message
      wx = Wx.new
      # Rails.logger.debug("encoding_aes_key: #{encoding_aes_key}, qy_token: #{qy_token}, corp_id: #{corp_id}")
      param_xml        = request.body.read
      hash             = MultiXml.parse(param_xml)['xml']
      @msg_encrypt  = hash["Encrypt"]
      @body_xml       = OpenStruct.new(hash)
      @content           = decrypt(aes_key, @body_xml.Encrypt, corp_id)[0]
      @hash               = MultiXml.parse(@content)["xml"]
   end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值