class JdPay::Util::Des3

京东支付 des3 加解密,掺杂了京东自定义的一些位转移逻辑

Public Class Methods

bytes_to_int(bytes) click to toggle source

解密

# File lib/jd_pay/util/des3.rb, line 49
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
decrypt(source, base64_key) click to toggle source
# File lib/jd_pay/util/des3.rb, line 17
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, bytes_length].map(&:chr).join
end
encrypt(source, base64_key) click to toggle source
# File lib/jd_pay/util/des3.rb, line 5
def self.encrypt(source, base64_key)
  key = Base64.decode64(base64_key)
  transformed_source = transform_source(source.bytes)

  des = OpenSSL::Cipher::Cipher.new('des-ede3')
  des.encrypt
  des.key = key
  des.padding = 0
  res = des.update(transformed_source) + des.final
  res.unpack("H*").first
end
transform_source(source_bytes) click to toggle source

对要加密的字符串按照京东的规则处理

# File lib/jd_pay/util/des3.rb, line 33
def self.transform_source(source_bytes)
  source_len = source_bytes.length
  x = (source_len + 4) % 8
  y = x == 0 ? 0 : 8 - x

  result_bytes = []
  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