class Ucenter::Interface::Authcode
Constants
- KeyLength
Public Instance Methods
decode(string)
click to toggle source
参考 github.com/daxingplay/dokuwiki_ucenter/blob/master/api/uc.php#L295
# File lib/ucenter/interface/authcode.rb, line 7 def decode string string = '' if string.nil? # 拆分key,并各自做md5 key = md5(Ucenter::Config.uc_key) key_left, key_right = md5(key[0, 16]), md5(key[16, 16]) # 拆分string auth和content部分 string_auth, string_content = string[0, KeyLength], string[KeyLength..-1] # 从key_crypt抽取box key_crypt = key_left + md5(key_left + string_auth) key_crypt_length = key_crypt.length rndkey = [] 0.upto(255) do |i| rndkey[i] = (key_crypt[i % key_crypt_length]).ord end a = b = 0 box = (0..255).to_a while b < 256 do a = (a + box[b] + rndkey[b]) % 256 box[b], box[a] = box[a], box[b] b +=1 end # 联合key_crypt和key_content解密出result string_content_ords = base64_url_decode(string_content).bytes.to_a string_content_ords_length = string_content_ords.length a = b = string_idx = 0 result = "" while string_idx < string_content_ords_length a = (a + 1) % 256 b = (b + box[a]) % 256 box[a], box[b] = box[b], box[a] result << (string_content_ords[string_idx] ^ (box[(box[a] + box[b]) % 256])).chr string_idx +=1 end result_time_valided = (result[0, 10] == '0'*10) || (result[0, 10].to_i - Time.now.to_i > 0) result_string_valided = result[10, 16] == md5("#{result[26..-1]}#{key_right}")[0, 16] # 重新加密和string对比验证 if (result_time_valided && result_string_valided) return result[26..-1] else return '' end end
encode(string)
click to toggle source
# File lib/ucenter/interface/authcode.rb, line 49 def encode string operation = 'ENCODE' expiry = 0 ckey_length = 4 key = md5(Ucenter::Config.uc_key) keya = md5(key[0, 16]) keyb = md5(key[16, 16]) keyc = ckey_length > 0 ? (operation == 'DECODE' ? string[0, ckey_length] : (md5(microtime()))[-ckey_length..-1]) : '' cryptkey = keya + md5(keya+keyc) key_length = cryptkey.size string = operation == 'DECODE' ? base64_url_decode(string[ckey_length..-1]) : sprintf('%010d', expiry>0 ? expiry + Time.now.to_i : 0)+ (md5(string+keyb))[0, 16] + string string_ords = ords(string) string_length = string_ords.size result = '' box = (0..255).to_a rndkey = [] 0.upto(255) do |i| rndkey[i] = (cryptkey[i % key_length]).ord end j = i = 0 while i < 256 do j = (j + box[i] + rndkey[i]) % 256 box[i], box[j] = box[j], box[i] i +=1 end a = j = i = 0 while i < string_length a = (a + 1) % 256 j = (j + box[a]) % 256 box[a], box[j] = box[j], box[a] result += (string_ords[i] ^ (box[(box[a] + box[j]) % 256])).chr i +=1 end if operation == 'DECODE' then if ( result[0,10] == '0'*10 || (result[0, 10]).to_i - Time.now.to_i > 0 ) and result[10, 16] == (md5(result[26..-1] + keyb))[0, 16] then return result[26..-1] else return '' end else keyc + (Base64.encode64(result)).gsub(/=/, '') end end
microtime()
click to toggle source
# File lib/ucenter/interface/authcode.rb, line 99 def microtime epoch_mirco = Time.now.to_f epoch_full = Time.now.to_i epoch_fraction = epoch_mirco - epoch_full epoch_fraction.to_s + ' ' + epoch_full.to_s end
Private Instance Methods
base64_url_decode(str)
click to toggle source
# File lib/ucenter/interface/authcode.rb, line 109 def base64_url_decode str mod = str.to_s.length.modulo(4) str2 = "#{str}#{'=' * (4 - mod)}".tr('-_','+/') Base64.decode64 str2 end
md5(str;)
click to toggle source
# File lib/ucenter/interface/authcode.rb, line 107 def md5 str; Digest::MD5.hexdigest str.to_s end
ords(s)
click to toggle source
# File lib/ucenter/interface/authcode.rb, line 115 def ords(s) s.bytes.to_a end