we_whisper 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/we_whisper/cipher.rb +2 -2
- data/lib/we_whisper/cryptor.rb +72 -0
- data/lib/we_whisper/signature.rb +2 -3
- data/lib/we_whisper/version.rb +1 -1
- data/lib/we_whisper/whisper.rb +3 -2
- data/spec/we_whisper/cryptor_spec.rb +33 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef0014125cbf072561dad5656b85ebad5bcad239
|
4
|
+
data.tar.gz: 02cda09f0da1d9d7c3b7da424100cbfd0e2079fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 442bf44e4f99d8f26620c3b26640c6a7aa8f524ba88067e9697b23151baef2ec7140590565aec3559a8110cdb67de238c30360e75b1a8f32425c108b4e1ad298
|
7
|
+
data.tar.gz: 5f41b5bb2da81e29cdd82036f34ebf30079ae1b2cf7a9e06f7fdc14077b758959a27f80642077ec93d26fe779990f740cf0b113e18ffd1238cbb0df3adaccf85
|
data/lib/we_whisper/cipher.rb
CHANGED
@@ -10,7 +10,7 @@ module WeWhisper
|
|
10
10
|
BLOCK_SIZE = 32
|
11
11
|
CIPHER = 'AES-256-CBC'.freeze
|
12
12
|
|
13
|
-
def
|
13
|
+
def cipher_encrypt(plain, encoding_aes_key)
|
14
14
|
cipher = OpenSSL::Cipher.new(CIPHER)
|
15
15
|
cipher.encrypt
|
16
16
|
|
@@ -22,7 +22,7 @@ module WeWhisper
|
|
22
22
|
cipher.update(plain) + cipher.final
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def cipher_decrypt(msg, encoding_aes_key)
|
26
26
|
cipher = OpenSSL::Cipher.new(CIPHER)
|
27
27
|
cipher.decrypt
|
28
28
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative 'cipher'
|
2
|
+
|
3
|
+
module WeWhisper
|
4
|
+
class Cryptor
|
5
|
+
include Cipher
|
6
|
+
|
7
|
+
attr_reader :value
|
8
|
+
|
9
|
+
def self.encrypt(content, appid, encoding_aes_key)
|
10
|
+
new(content).encrypt(appid, encoding_aes_key)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.decrypt(encrypted_content, encoding_aes_key)
|
14
|
+
new(encrypted_content).decrypt(encoding_aes_key)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(content)
|
18
|
+
@value = content
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def encrypt(appid, encoding_aes_key)
|
23
|
+
pack_with_appid(appid)
|
24
|
+
.encrypt_with_aes_key(encoding_aes_key)
|
25
|
+
.encode()
|
26
|
+
.value
|
27
|
+
end
|
28
|
+
|
29
|
+
def decrypt(encoding_aes_key)
|
30
|
+
decode()
|
31
|
+
.decrypt_with_aes_key(encoding_aes_key)
|
32
|
+
.unpack_with_appid()
|
33
|
+
.value
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def decode
|
39
|
+
@value = Base64.decode64(@value)
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def decrypt_with_aes_key(encoding_aes_key)
|
44
|
+
@value = cipher_decrypt(@value, encoding_aes_key)
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def unpack_with_appid
|
49
|
+
@value = unpack(@value)
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# pack
|
54
|
+
def pack_with_appid(appid)
|
55
|
+
@value = pack(@value, appid)
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
# encrypt
|
60
|
+
def encrypt_with_aes_key(encoding_aes_key)
|
61
|
+
@value = cipher_encrypt(@value, encoding_aes_key)
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
# encode
|
66
|
+
def encode
|
67
|
+
@value = Base64.strict_encode64(@value)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
data/lib/we_whisper/signature.rb
CHANGED
@@ -3,9 +3,8 @@ require 'digest/sha2'
|
|
3
3
|
module WeWhisper
|
4
4
|
module Signature
|
5
5
|
def self.sign(token, timestamp, nonce, encrypted)
|
6
|
-
|
7
|
-
|
8
|
-
Digest::SHA1.hexdigest array.compact.collect(&:to_s).sort.join
|
6
|
+
Digest::SHA1.hexdigest \
|
7
|
+
[token, timestamp, nonce, encrypted].compact.collect(&:to_s).sort.join
|
9
8
|
end
|
10
9
|
end
|
11
10
|
end
|
data/lib/we_whisper/version.rb
CHANGED
data/lib/we_whisper/whisper.rb
CHANGED
@@ -3,6 +3,7 @@ require 'base64'
|
|
3
3
|
require_relative 'cipher'
|
4
4
|
require_relative 'signature'
|
5
5
|
require_relative 'message'
|
6
|
+
require_relative 'cryptor'
|
6
7
|
|
7
8
|
module WeWhisper
|
8
9
|
InvalidSignature = Class.new StandardError
|
@@ -37,7 +38,7 @@ module WeWhisper
|
|
37
38
|
|
38
39
|
# 3. Decode and decrypt the encrypted text
|
39
40
|
decrypted_message, decrypted_appid = \
|
40
|
-
|
41
|
+
Cryptor.decrypt(encrypted_text, encoding_aes_key)
|
41
42
|
|
42
43
|
if options[:assert_appid]
|
43
44
|
raise AppIdNotMatch if decrypted_appid != appid
|
@@ -48,7 +49,7 @@ module WeWhisper
|
|
48
49
|
|
49
50
|
def encrypt_message(message, nonce, timestamp)
|
50
51
|
# 1. Encrypt and encode the xml message
|
51
|
-
encrypt =
|
52
|
+
encrypt = Cryptor.encrypt(message, appid, encoding_aes_key)
|
52
53
|
|
53
54
|
# 2. Create signature
|
54
55
|
sign = Signature.sign(token, timestamp, nonce, encrypt)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WeWhisper::Cryptor do
|
4
|
+
|
5
|
+
let(:timestamp) { "1415979516" }
|
6
|
+
let(:nonce) { "1320562132" }
|
7
|
+
let(:appid) { "wx2c2769f8efd9abc2" }
|
8
|
+
let(:aes_key) { "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG" }
|
9
|
+
let(:signature) { "096d8cda45e4678ca23460f6b8cd281b3faf1fc3" }
|
10
|
+
let(:encrypted) { "3kKZ++U5ocvIF8dAHPct7xvUqEv6vplhuzA8Vwj7OnVcBu9fdmbbI41zclSfKqP6/bdYAxuE3x8jse43ImHaV07siJF473TsXhl8Yt8task0n9KC7BDA73mFTwlhYvuCIFnU6wFlzOkHyM5Bh2qpOHYk5nSMRyUG4BwmXpxq8TvLgJV1jj2DXdGW4qdknGLfJgDH5sCPJeBzNC8j8KtrJFxmG7qIwKHn3H5sqBf6UqhXFdbLuTWL3jwE7yMLhzOmiHi/MX/ZsVQ7sMuBiV6bW0wkgielESC3yNUPo4q/RMAFEH0fRLr76BR5Ct0nUbf9PdClc0RdlYcztyOs54X/KLbYRNCQ2kXxmJYL6ekdNe70PCAReIEfXEp+pGpry4ss8bD6LKAtNvBJUwHshZe6sbf+fOiDiuKEqp1wdQLmgN+8nX62LklySWr8QrNCpsmKClxco0kbVYNX/QVh5yd0UA1sAqIn6baZ9G+Z/OXG+Q4n9lUuzLprLhDBPaCvXm4N14oqXNcw7tqU2xfhYNIDaD72djyIc/4eyAi2ZsJ+3hb+jgiISR5WVveRWYYqGZGTW3u+27JiXEo0fs3DQDbGVIcYxaMgU/RRIDdXzZSFcf6Z1azjzCDyV9FFEsicghHn" }
|
11
|
+
let(:message) { "<xml><ToUserName><![CDATA[oia2TjjewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType> <![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>" }
|
12
|
+
let(:encrypted_message) {
|
13
|
+
"""<xml>
|
14
|
+
<Encrypt><![CDATA[3kKZ++U5ocvIF8dAHPct7xvUqEv6vplhuzA8Vwj7OnVcBu9fdmbbI41zclSfKqP6/bdYAxuE3x8jse43ImHaV07siJF473TsXhl8Yt8task0n9KC7BDA73mFTwlhYvuCIFnU6wFlzOkHyM5Bh2qpOHYk5nSMRyUG4BwmXpxq8TvLgJV1jj2DXdGW4qdknGLfJgDH5sCPJeBzNC8j8KtrJFxmG7qIwKHn3H5sqBf6UqhXFdbLuTWL3jwE7yMLhzOmiHi/MX/ZsVQ7sMuBiV6bW0wkgielESC3yNUPo4q/RMAFEH0fRLr76BR5Ct0nUbf9PdClc0RdlYcztyOs54X/KLbYRNCQ2kXxmJYL6ekdNe70PCAReIEfXEp+pGpry4ss8bD6LKAtNvBJUwHshZe6sbf+fOiDiuKEqp1wdQLmgN+8nX62LklySWr8QrNCpsmKClxco0kbVYNX/QVh5yd0UA1sAqIn6baZ9G+Z/OXG+Q4n9lUuzLprLhDBPaCvXm4N14oqXNcw7tqU2xfhYNIDaD72djyIc/4eyAi2ZsJ+3hb+jgiISR5WVveRWYYqGZGTW3u+27JiXEo0fs3DQDbGVIcYxaMgU/RRIDdXzZSFcf6Z1azjzCDyV9FFEsicghHn]]></Encrypt>
|
15
|
+
<MsgSignature><![CDATA[096d8cda45e4678ca23460f6b8cd281b3faf1fc3]]></MsgSignature>
|
16
|
+
<TimeStamp>1415979516</TimeStamp>
|
17
|
+
<Nonce><![CDATA[1320562132]]></Nonce>
|
18
|
+
</xml>"""
|
19
|
+
}
|
20
|
+
|
21
|
+
it "decrypts message" do
|
22
|
+
decrypted, decrypted_appid = WeWhisper::Cryptor.decrypt(encrypted, aes_key)
|
23
|
+
expect(decrypted_appid).to eq 'wx2c2769f8efd9abc2'
|
24
|
+
expect(decrypted).to eq message
|
25
|
+
end
|
26
|
+
|
27
|
+
it "encryptes message" do
|
28
|
+
expect(SecureRandom).to receive(:hex).with(8).and_return("HLFOQjbkfgUh46s8")
|
29
|
+
_encrypted = WeWhisper::Cryptor.encrypt(message, appid, aes_key)
|
30
|
+
expect(_encrypted).to eq encrypted
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: we_whisper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Qi He
|
@@ -33,12 +33,14 @@ extensions: []
|
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
35
|
- lib/we_whisper/cipher.rb
|
36
|
+
- lib/we_whisper/cryptor.rb
|
36
37
|
- lib/we_whisper/message.rb
|
37
38
|
- lib/we_whisper/signature.rb
|
38
39
|
- lib/we_whisper/version.rb
|
39
40
|
- lib/we_whisper/whisper.rb
|
40
41
|
- lib/we_whisper.rb
|
41
42
|
- spec/spec_helper.rb
|
43
|
+
- spec/we_whisper/cryptor_spec.rb
|
42
44
|
- spec/we_whisper/message_spec.rb
|
43
45
|
- spec/we_whisper/signature_spec.rb
|
44
46
|
- spec/we_whisper/whisper_spec.rb
|
@@ -68,6 +70,7 @@ specification_version: 4
|
|
68
70
|
summary: A Ruby Wrapper for Wechat Message Encryption.
|
69
71
|
test_files:
|
70
72
|
- spec/spec_helper.rb
|
73
|
+
- spec/we_whisper/cryptor_spec.rb
|
71
74
|
- spec/we_whisper/message_spec.rb
|
72
75
|
- spec/we_whisper/signature_spec.rb
|
73
76
|
- spec/we_whisper/whisper_spec.rb
|