Module: Wework::Cipher

Extended by:
ActiveSupport::Concern
Included in:
Api::Corp, Api::Provider, Api::Suite
Defined in:
lib/wework/cipher.rb

Constant Summary collapse

BLOCK_SIZE =
32
CIPHER =
'AES-256-CBC'.freeze

Instance Method Summary collapse

Instance Method Details

#decrypt(msg, encoding_aes_key) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/wework/cipher.rb', line 26

def decrypt(msg, encoding_aes_key)
  cipher = OpenSSL::Cipher.new(CIPHER)
  cipher.decrypt

  cipher.padding = 0
  key_data = Base64.decode64(encoding_aes_key + '=')
  cipher.key = key_data
  cipher.iv = [key_data].pack('H*')

  plain = cipher.update(msg) + cipher.final
  decode_padding(plain)
end

#encrypt(plain, encoding_aes_key) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/wework/cipher.rb', line 14

def encrypt(plain, encoding_aes_key)
  cipher = OpenSSL::Cipher.new(CIPHER)
  cipher.encrypt

  cipher.padding = 0
  key_data = Base64.decode64(encoding_aes_key + '=')
  cipher.key = key_data
  cipher.iv = [key_data].pack('H*')

  cipher.update(plain) + cipher.final
end

#generate_xml(msg, timestamp, nonce) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/wework/cipher.rb', line 71

def generate_xml(msg, timestamp, nonce)
  encrypt = msg_encrypt(msg)
  {
    Encrypt: encrypt,
    MsgSignature: signature(timestamp, nonce, encrypt),
    TimeStamp: timestamp,
    Nonce: nonce
  }.to_xml(root: 'xml', children: 'item', skip_instruct: true, skip_types: true)
end

#msg_decrypt(message) ⇒ Object



57
58
59
# File 'lib/wework/cipher.rb', line 57

def msg_decrypt message
  unpack(decrypt(Base64.decode64(message), encoding_aes_key))[0]
end

#msg_encrypt(message) ⇒ Object



61
62
63
# File 'lib/wework/cipher.rb', line 61

def msg_encrypt message
  Base64.strict_encode64(encrypt(pack(message, corp_id), encoding_aes_key))
end

#pack(content, app_id) ⇒ Object

app_id or corp_id



40
41
42
43
44
45
46
# File 'lib/wework/cipher.rb', line 40

def pack(content, app_id)
  random = SecureRandom.hex(8)
  text = content.force_encoding('ASCII-8BIT')
  msg_len = [text.length].pack('N')

  encode_padding("#{random}#{msg_len}#{text}#{app_id}")
end

#signature(timestamp, nonce, encrypt) ⇒ Object



65
66
67
68
69
# File 'lib/wework/cipher.rb', line 65

def signature(timestamp, nonce, encrypt)
  array = [token, timestamp, nonce]
  array << encrypt unless encrypt.nil?
  Digest::SHA1.hexdigest array.compact.collect(&:to_s).sort.join
end

#unpack(msg) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/wework/cipher.rb', line 48

def unpack(msg)
  msg = decode_padding(msg)
  msg_len = msg[16, 4].reverse.unpack('V')[0]
  content = msg[20, msg_len]
  app_id = msg[(20 + msg_len)..-1]

  [content, app_id]
end