Class: Wechat::Callback::SecureMessage

Inherits:
Object
  • Object
show all
Extended by:
Wechat::Core::Common
Defined in:
lib/wechat/callback/secure_message.rb

Overview

Secure Message 用于组合或者分解安全消息。

Constant Summary collapse

RANDOM_LENGTH =
16
XML_SIZE_LENGTH =
4

Class Method Summary collapse

Class Method Details

.byte_array_to_string(bytes) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/wechat/callback/secure_message.rb', line 55

def self.byte_array_to_string(bytes)

  assert_present! :bytes, bytes
  #raise ArgumentError.new('The bytes argument is required.') if bytes.blank?

  bytes.inject('') do |buffer, byte| buffer += [ byte ].pack 'C' end
end

.create(random_bytes, xml_text, app_id) ⇒ Object

消息加解密mp.weixin.qq.com/wiki/6/90f7259c0d0739bbb41d9f4c4c8e59a2.html

random(16B) + msg_len(4B) + msg + $AppId + padding padding: AES采用CBC模式,秘钥长度为32个字节,数据采用PKCS#7填充;PKCS#7:K为秘钥字节数(采用32),buf为待加密的内容,N为其字节数。Buf需要被填充为K的整数倍。在buf的尾部填充(K-N%K)个字节,每个字节的内容是(K- N%K);去掉rand_msg头部的16个随机字节,4个字节的msg_len,和尾部的$AppId即为最终的xml消息体



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/wechat/callback/secure_message.rb', line 42

def self.create(random_bytes, xml_text, app_id)

  assert_present! :random_bytes, random_bytes
  assert_present! :xml_text,     xml_text
  assert_present! :app_id,       app_id

  xml_size_bytes = [ xml_text.bytes.length ].pack('l').reverse.bytes
  buffer         = random_bytes+xml_size_bytes+xml_text.bytes+app_id.bytes
  padding_length = 32-buffer.length%32
  buffer         += [ padding_length ]*padding_length
  byte_array_to_string buffer
end

.load(message_decryption) ⇒ Object

消息加解密mp.weixin.qq.com/wiki/6/90f7259c0d0739bbb41d9f4c4c8e59a2.html

random(16B) + msg_len(4B) + msg + $AppId + padding padding: AES采用CBC模式,秘钥长度为32个字节,数据采用PKCS#7填充;PKCS#7:K为秘钥字节数(采用32),buf为待加密的内容,N为其字节数。Buf需要被填充为K的整数倍。在buf的尾部填充(K-N%K)个字节,每个字节的内容是(K- N%K);去掉rand_msg头部的16个随机字节,4个字节的msg_len,和尾部的$AppId即为最终的xml消息体



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/wechat/callback/secure_message.rb', line 18

def self.load(message_decryption)

  assert_present! :message_decryption, message_decryption

  random_bytes = message_decryption[0..(RANDOM_LENGTH-1)].bytes
  xml_size     = message_decryption[RANDOM_LENGTH..(RANDOM_LENGTH+XML_SIZE_LENGTH-1)].reverse.unpack('l').first

  text_decryption = message_decryption.bytes[(RANDOM_LENGTH+XML_SIZE_LENGTH)..(message_decryption.length-1)]
  xml_text        = byte_array_to_string text_decryption[0..(xml_size-1)]

  padding_length = message_decryption.last.unpack('C').first
  app_id         = byte_array_to_string text_decryption[xml_size..(text_decryption.length-1-padding_length)]
  padding_bytes  = text_decryption[(text_decryption.length-padding_length)..(text_decryption.length-1)]

  [ random_bytes, xml_size, xml_text, app_id, padding_bytes ]

end