lib/jd_pay/util/des3.rb in jd_pay-0.1.4 vs lib/jd_pay/util/des3.rb in jd_pay-0.1.5

- old
+ new

@@ -1,8 +1,8 @@ module JdPay module Util - # 京东支付 des3 加密,掺杂了京东自定义的一些位转移逻辑 + # 京东支付 des3 加解密,掺杂了京东自定义的一些位转移逻辑 class Des3 def self.encrypt(source, base64_key) key = Base64.decode64(base64_key) transformed_source = transform_source(source.bytes) @@ -12,24 +12,48 @@ des.padding = 0 res = des.update(transformed_source) + des.final res.unpack("H*").first end + def self.decrypt(source, base64_key) + key = Base64.decode64(base64_key) + b2 = source.chars.each_slice(2).map{|x| x.join().to_i(16) }.map(&:chr).join + + des = OpenSSL::Cipher::Cipher.new('des-ede3') + des.decrypt + des.key = key + des.padding = 0 + res = des.update(b2) + des.final + decrypt_bytes = res.bytes + + bytes_length = bytes_to_int(decrypt_bytes[0, 4]) + decrypt_bytes[4, 4 + bytes_length].map(&:chr).join + end + # 对要加密的字符串按照京东的规则处理 def self.transform_source(source_bytes) source_len = source_bytes.length x = (source_len + 4) % 8 y = x == 0 ? 0 : 8 - x result_bytes = [] - result_bytes << (source_len >> 24 & 0xFF) - result_bytes << (source_len >> 16 & 0xFF) - result_bytes << (source_len >> 8 & 0xFF) - result_bytes << (source_len & 0xFF) + 0.upto(3).each do |index| + result_bytes << ((source_len >> (3 - index) * 8) & 0xFF) + end result_bytes += source_bytes y.times { result_bytes << 0 } result_bytes.map(&:chr).join + end + + # 解密 + def self.bytes_to_int(bytes) + total = 0 + bytes.each_with_index do |value, index| + shift = (3 - index) * 8 + total += (value & 0xFF) << shift + end + total end end end end