| 
本帖最后由 guoxiaomi 于 2017-6-26 16:14 编辑
x
加入我们,或者,欢迎回来。您需要 登录 才可以下载或查看,没有帐号?注册会员  
 ===2017年3月9日更新===
 现在可以用来加密文件
 
 
 最近在6R上看到了这个 HTTP 的脚本:win32异步http通信库dll
 
 感觉非常实用,但是传输不能保密是个大问题,在经过一番资料搜索后,我找到了这个:纯Ruby AES
 
 稍微整理了一下脚本,在RMXP上可以正常运行。本身Ruby有openssl库也不需要这个……
 
 2017/2/10 20:20 修复了一个BUG
 
 
 #==============================================================================# 纯ruby AES_ECB#==============================================================================class Array def rot(offset=1)  # rotate byte  self[offset..-1]+self[0,offset] end  def ^(otherArray)  zip(otherArray).map { |pair| pair[0]^pair[1] } endend class Fixnum def xtime    # GF(2^8) mulitiplication by x  t=(self<<1) & 0xFF  t^=0x1B if self[7]==1  t end  def fm(v)    # GF(2^8) mulitiplication  r=0  xm=self  0.upto(7) {|b| r^=xm if v[b]==1; xm=xm.xtime; }  r endend class Rijndael S=[  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]  I_S=[  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ]  I_MixColPloy=[0xE,0xB,0xD,0x9] T=S.map {|byte| [byte, byte, byte.fm(3), byte.fm(2)]}  I_T=I_S.map {|byte| [byte.fm(0x9), byte.fm(0xD), byte.fm(0xB), byte.fm(0xE)]}  Rcon=[[0x8d,0,0,0]]    # 8d.xtime=01 1.upto(13) {|j| Rcon[j]=[Rcon[j-1][0].xtime,0,0,0]}  def initialize(nb=4)  raise "Illegal value for Nb." unless [4,6,8].include?(nb)   @nb=nb end  def load_ek(key)    # load encrypt key  @ek=keyExpansion(key) end  def load_dk(key)    # load decrypt key  @dk=keyExpansion(key)  @dk[@nb..-5].each {|word| word[0..3]=invMixColumn(word)} end  def invMixColumn(word)  (0..3).map {|i|   I_MixColPloy.zip(word.rot(i)).map{|pair| pair[0].fm(pair[1])}.inject{|a,b| a^b}  } end  def keyExpansion(key)  # key is byte array  nk=[4,6,8].find {|i| i*4==key.size} or raise "Illegal key length."  nr=[@nb, nk].max+6  w=[]  (0..nk-1).each {|i| w[i]=key[4*i,4] }  (nk..@nb*(nr+1)-1).each { |i|   temp=w[i-1]   if i%nk==0    temp = temp.rot.map{|byte| S[byte]} ^ Rcon[i/nk]   elsif nk>6 && i%nk==4    temp = temp.map{|byte| S[byte]}   end   w[i]=w[i-nk]^temp  }  w end  def invKeyExpansion(key)  w=keyExpansion(key)  w[1,-1].each {|word| invMixColumn(word)}  w end  def cipher(plaintext)  raise "Invalid length of input data." if plaintext.size!=@nb*4  a=(0..@nb-1).map {|j| plaintext[j*4,4]}  # map plaintext onto state  nr=@ek.size/4-1  a^=@ek[0,4]         # add round key  1.upto(nr) { |round|   k=@ek[round*4,4]   e=[]   0.upto(3) { |j|    if round!=nr     e[j]= T[a[j][0]].rot(3) ^ T[a[(j+1)%4][1]].rot(2) ^ T[a[(j+2)%4][2]].rot(1) ^ T[a[(j+3)%4][3]]    else     e[j]= [ S[a[j][0]], S[a[(j+1)%4][1]], S[a[(j+2)%4][2]], S[a[(j+3)%4][3]] ]    end   }   a=e^k  }  a.flatten end  def i_cipher(ciphertext)  raise "Invalid length of input data." if ciphertext.size!=@nb*4  a=(0..@nb-1).map {|j| ciphertext[j*4,4]}  # map ciphertext onto state  nr=@dk.size/4-1  k=@dk[nr*4,4]  a^=k         # add round key  (nr-1).downto(0) { |round|   k=@dk[round*4,4]   e=[]   0.upto(3) { |j|    if round!=0     e[j]= I_T[a[j][0]].rot(3) ^ I_T[a[(j-1)%4][1]].rot(2) ^ I_T[a[(j-2)%4][2]].rot(1) ^ I_T[a[(j-3)%4][3]]    else     e[j]= [ I_S[a[j][0]], I_S[a[(j-1)%4][1]], I_S[a[(j-2)%4][2]], I_S[a[(j-3)%4][3]] ]    end   }   a=e^k  }  a.flatten endend # AES=Rijndael.new(4)   # Nb in AES is 4 # Example Vectors (FIPS-197 Appendix C) # plaintext=[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]# AES.load_ek key# AES.load_dk key# ciphertext = AES.cipher plaintext# output = AES.i_cipher ciphertext# output==plaintext# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17] # AES.load_ek key# AES.load_dk key# ciphertext = AES.cipher plaintext# output = AES.i_cipher ciphertext# output==plaintext# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f]# AES.load_ek key# AES.load_dk key# ciphertext = AES.cipher plaintext# output = AES.i_cipher ciphertext# output==plaintext #==============================================================================# 以上片段来自于[url]http://outofmemory.cn[/url]#============================================================================== #==============================================================================# 封装到 AES_ECB 单元类#==============================================================================class AES_ECB        def self.set_key(key)                # key is a string                key_ary = (key.unpack('H*')[0].scan /../).collect{|x| x.to_i(16)}                @aes = Rijndael.new(4)                @aes.load_ek key_ary                @aes.load_dk key_ary                        end         def self.encrypt(str)                result = ""                # encrypt str to hex string                                plaintext = (str.unpack('H*')[0].scan /../).collect{|x| x.to_i(16)}                pad = 16 - plaintext.length % 16                pad.times do                         plaintext.push pad                end                for i in 0..plaintext.length/16-1 do                        text = plaintext[i*16..i*16+15]                                                ciphertext = @aes.cipher(text).collect{|x| sprintf('%02x', x)}.join('')                        result = result + ciphertext                end                return result        end         def self.decrypt(hexstr)                result = []                for i in 0..hexstr.length/32-1 do                        text = hexstr[i*32..i*32+31]                        output = @aes.i_cipher((text.scan /../).collect{|x| x.to_i(16)})                        result = result + output                end                last = result.length - result[-1] - 1                return [result[0..last].collect{|x| sprintf('%02x', x)}.join('')].pack('H*')        end         def self.encrypt_file(filename)                                file1 = File.open(filename, "rb")                file2 = File.open(filename + ".AES_EN", "wb")                begin                        file1.each_line do |line|                                file2 << AES_ECB.encrypt(line.unpack("H*")[0]) + "\n"                        end                ensure                        file1.close                        file2.close                end        end         def self.decrypt_file(filename)                file1 = File.open(filename, "rb")                file2 = File.open(filename + ".AES_DE", "wb")                begin                        file1.each_line do |line|                                line2 = AES_ECB.decrypt(line)                                file2 << line2.scan(/../).pack("H2" * (line2.size / 2))                        end                ensure                        file1.close                        file2.close                end        endend #==============================================================================# AES_ECB加密使用说明#------------------------------------------------------------------------------# key只能是16位字符串(ASCII码)# 待加密的字符串无要求# AES_ECB.set_key 设置 key# AES_ECB.encrypt 加密任意字符串为16进制字符串# AES_ECB.decrypt 解密16进制字符串为目标字符串# AES_ECB.encrypt_file 加密文件,会在文件后面添加后缀 .AES_EN# AES_ECB.decrypt_file 解密文件,会在文件后面添加后缀 .AES_DE# 容错性:无,不按照以上要求或者无解可能随时报错#------------------------------------------------------------------------------# AES_ECB.set_key('rpg.blue/bbs') # key string's length must 16# e = AES_ECB.encrypt('hello!') # plain text can be any length# AES_ECB.decrypt(e)# AES_ECB.encrypt_file("test.txt") # => test.txt.AES_EN# AES_ECB.decrypt_file("test.txt.AES_EN") # => test.txt.AES_EN.AES_DE#------------------------------------------------------------------------------# 用途:加密字符串、文件等#------------------------------------------------------------------------------
#============================================================================== 
# 纯ruby AES_ECB 
#============================================================================== 
class Array 
 def rot(offset=1)  # rotate byte 
  self[offset..-1]+self[0,offset] 
 end 
  
 def ^(otherArray) 
  zip(otherArray).map { |pair| pair[0]^pair[1] } 
 end 
end 
  
class Fixnum 
 def xtime    # GF(2^8) mulitiplication by x 
  t=(self<<1) & 0xFF 
  t^=0x1B if self[7]==1 
  t 
 end 
  
 def fm(v)    # GF(2^8) mulitiplication 
  r=0 
  xm=self 
  0.upto(7) {|b| r^=xm if v[b]==1; xm=xm.xtime; } 
  r 
 end 
end 
  
class Rijndael 
 S=[ 
  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 
  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 
  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 
  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 
  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 
  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 
  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 
  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 
  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 
  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 
  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 
  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 
  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 
  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 
  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 
  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 
 ] 
  
 I_S=[ 
  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 
  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 
  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 
  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 
  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 
  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 
  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 
  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 
  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 
  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 
  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 
  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 
  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 
  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 
  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 
  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 
 ] 
  
 I_MixColPloy=[0xE,0xB,0xD,0x9] 
 T=S.map {|byte| [byte, byte, byte.fm(3), byte.fm(2)]}  
 I_T=I_S.map {|byte| [byte.fm(0x9), byte.fm(0xD), byte.fm(0xB), byte.fm(0xE)]} 
  
 Rcon=[[0x8d,0,0,0]]    # 8d.xtime=01 
 1.upto(13) {|j| Rcon[j]=[Rcon[j-1][0].xtime,0,0,0]} 
  
 def initialize(nb=4) 
  raise "Illegal value for Nb." unless [4,6,8].include?(nb)  
  @nb=nb 
 end 
  
 def load_ek(key)    # load encrypt key 
  @ek=keyExpansion(key) 
 end 
  
 def load_dk(key)    # load decrypt key 
  @dk=keyExpansion(key) 
  @dk[@nb..-5].each {|word| word[0..3]=invMixColumn(word)} 
 end 
  
 def invMixColumn(word) 
  (0..3).map {|i| 
   I_MixColPloy.zip(word.rot(i)).map{|pair| pair[0].fm(pair[1])}.inject{|a,b| a^b} 
  } 
 end 
  
 def keyExpansion(key) 
  # key is byte array 
  nk=[4,6,8].find {|i| i*4==key.size} or raise "Illegal key length." 
  nr=[@nb, nk].max+6 
  w=[] 
  (0..nk-1).each {|i| w[i]=key[4*i,4] } 
  (nk..@nb*(nr+1)-1).each { |i| 
   temp=w[i-1] 
   if i%nk==0 
    temp = temp.rot.map{|byte| S[byte]} ^ Rcon[i/nk] 
   elsif nk>6 && i%nk==4 
    temp = temp.map{|byte| S[byte]} 
   end 
   w[i]=w[i-nk]^temp 
  } 
  w 
 end 
  
 def invKeyExpansion(key) 
  w=keyExpansion(key) 
  w[1,-1].each {|word| invMixColumn(word)} 
  w 
 end 
  
 def cipher(plaintext) 
  raise "Invalid length of input data." if plaintext.size!=@nb*4 
  a=(0..@nb-1).map {|j| plaintext[j*4,4]}  # map plaintext onto state 
  nr=@ek.size/4-1 
  a^=@ek[0,4]         # add round key 
  1.upto(nr) { |round| 
   k=@ek[round*4,4] 
   e=[] 
   0.upto(3) { |j| 
    if round!=nr 
     e[j]= T[a[j][0]].rot(3) ^ T[a[(j+1)%4][1]].rot(2) ^ T[a[(j+2)%4][2]].rot(1) ^ T[a[(j+3)%4][3]] 
    else 
     e[j]= [ S[a[j][0]], S[a[(j+1)%4][1]], S[a[(j+2)%4][2]], S[a[(j+3)%4][3]] ] 
    end 
   } 
   a=e^k 
  } 
  a.flatten 
 end 
  
 def i_cipher(ciphertext) 
  raise "Invalid length of input data." if ciphertext.size!=@nb*4 
  a=(0..@nb-1).map {|j| ciphertext[j*4,4]}  # map ciphertext onto state 
  nr=@dk.size/4-1 
  k=@dk[nr*4,4] 
  a^=k         # add round key 
  (nr-1).downto(0) { |round| 
   k=@dk[round*4,4] 
   e=[] 
   0.upto(3) { |j| 
    if round!=0 
     e[j]= I_T[a[j][0]].rot(3) ^ I_T[a[(j-1)%4][1]].rot(2) ^ I_T[a[(j-2)%4][2]].rot(1) ^ I_T[a[(j-3)%4][3]] 
    else 
     e[j]= [ I_S[a[j][0]], I_S[a[(j-1)%4][1]], I_S[a[(j-2)%4][2]], I_S[a[(j-3)%4][3]] ] 
    end 
   } 
   a=e^k 
  } 
  a.flatten 
 end 
end 
  
# AES=Rijndael.new(4)   # Nb in AES is 4 
  
# Example Vectors (FIPS-197 Appendix C) 
  
# plaintext=[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff] 
# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f] 
# AES.load_ek key 
# AES.load_dk key 
# ciphertext = AES.cipher plaintext 
# output = AES.i_cipher ciphertext 
# output==plaintext 
# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17]  
# AES.load_ek key 
# AES.load_dk key 
# ciphertext = AES.cipher plaintext 
# output = AES.i_cipher ciphertext 
# output==plaintext 
# key=[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f] 
# AES.load_ek key 
# AES.load_dk key 
# ciphertext = AES.cipher plaintext 
# output = AES.i_cipher ciphertext 
# output==plaintext 
  
#============================================================================== 
# 以上片段来自于[url]http://outofmemory.cn[/url] 
#============================================================================== 
  
#============================================================================== 
# 封装到 AES_ECB 单元类 
#============================================================================== 
class AES_ECB 
        def self.set_key(key) 
                # key is a string 
                key_ary = (key.unpack('H*')[0].scan /../).collect{|x| x.to_i(16)} 
                @aes = Rijndael.new(4) 
                @aes.load_ek key_ary 
                @aes.load_dk key_ary                 
        end 
  
        def self.encrypt(str) 
                result = "" 
                # encrypt str to hex string                 
                plaintext = (str.unpack('H*')[0].scan /../).collect{|x| x.to_i(16)} 
                pad = 16 - plaintext.length % 16 
                pad.times do  
                        plaintext.push pad 
                end 
                for i in 0..plaintext.length/16-1 do 
                        text = plaintext[i*16..i*16+15]                         
                        ciphertext = @aes.cipher(text).collect{|x| sprintf('%02x', x)}.join('') 
                        result = result + ciphertext 
                end 
                return result 
        end 
  
        def self.decrypt(hexstr) 
                result = [] 
                for i in 0..hexstr.length/32-1 do 
                        text = hexstr[i*32..i*32+31] 
                        output = @aes.i_cipher((text.scan /../).collect{|x| x.to_i(16)}) 
                        result = result + output 
                end 
                last = result.length - result[-1] - 1 
                return [result[0..last].collect{|x| sprintf('%02x', x)}.join('')].pack('H*') 
        end 
  
        def self.encrypt_file(filename)                 
                file1 = File.open(filename, "rb") 
                file2 = File.open(filename + ".AES_EN", "wb") 
                begin 
                        file1.each_line do |line| 
                                file2 << AES_ECB.encrypt(line.unpack("H*")[0]) + "\n" 
                        end 
                ensure 
                        file1.close 
                        file2.close 
                end 
        end 
  
        def self.decrypt_file(filename) 
                file1 = File.open(filename, "rb") 
                file2 = File.open(filename + ".AES_DE", "wb") 
                begin 
                        file1.each_line do |line| 
                                line2 = AES_ECB.decrypt(line) 
                                file2 << line2.scan(/../).pack("H2" * (line2.size / 2)) 
                        end 
                ensure 
                        file1.close 
                        file2.close 
                end 
        end 
end 
  
#============================================================================== 
# AES_ECB加密使用说明 
#------------------------------------------------------------------------------ 
# key只能是16位字符串(ASCII码) 
# 待加密的字符串无要求 
# AES_ECB.set_key 设置 key 
# AES_ECB.encrypt 加密任意字符串为16进制字符串 
# AES_ECB.decrypt 解密16进制字符串为目标字符串 
# AES_ECB.encrypt_file 加密文件,会在文件后面添加后缀 .AES_EN 
# AES_ECB.decrypt_file 解密文件,会在文件后面添加后缀 .AES_DE 
# 容错性:无,不按照以上要求或者无解可能随时报错 
#------------------------------------------------------------------------------ 
# AES_ECB.set_key('rpg.blue/bbs') # key string's length must 16 
# e = AES_ECB.encrypt('hello!') # plain text can be any length 
# AES_ECB.decrypt(e) 
# AES_ECB.encrypt_file("test.txt") # => test.txt.AES_EN 
# AES_ECB.decrypt_file("test.txt.AES_EN") # => test.txt.AES_EN.AES_DE 
#------------------------------------------------------------------------------ 
# 用途:加密字符串、文件等 
#------------------------------------------------------------------------------ 
 服务端那边也找了个“某听说是最好的语言”的版本:
 
 
 <?php        //--------AES-128-ECB加密方案--------    echo '第三种AES加密方案:<br>';        $key = 'rpg.blue/bbs'; // $key必须是16位字符串,且都是ascii码    $content = 'hello!';    $e_content = aesEncrypt($key, $content);    echo "128-bit encrypted result:".$e_content.'<br>';           echo '解密:';        echo aesDecrypt($key, $e_content);     //--------AES-128-ECB加密方案--------    // 调用的函数    function aesEncrypt($key, $content) {        $iv = 'iloveaes'; // ECB方案不需要iv        $content = pad2Length($content,16);            return bin2hex( mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key,$content,MCRYPT_MODE_ECB,$iv) ); #加密     }    function aesDecrypt($key, $hexstring) {        $iv = 'iloveaes'; // ECB方案不需要iv        $jiemi = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,hexToStr($hexstring),MCRYPT_MODE_ECB,$iv); #解密            return trimEnd($jiemi);    }    // 辅助函数    //将$text补足$padlen倍数的长度        function pad2Length($text, $padlen){            $len = strlen($text) % $padlen;            $res = $text;            $span = $padlen-$len;        for($i=0; $i<$span; $i++){                $res .= chr($span);                                }            return $res;        }        //将解密后多余的长度去掉(因为在加密的时候 补充长度满足block_size的长度)        function trimEnd($text){            $len = strlen($text);            $c = $text[$len-1];            if(ord($c) <$len){                for($i=$len-ord($c); $i<$len; $i++){                    if($text[$i] != $c){                        return $text;                    }                }                return substr($text, 0, $len-ord($c));            }            return $text;        }        //16进制的转为2进制字符串        function hexToStr($hex)         {             $bin="";             for($i=0; $i<strlen($hex)-1; $i+=2)             {                $bin.=chr(hexdec($hex[$i].$hex[$i+1]));             }            return $bin;         } ?>
<?php     
    //--------AES-128-ECB加密方案-------- 
    echo '第三种AES加密方案:<br>';     
    $key = 'rpg.blue/bbs'; // $key必须是16位字符串,且都是ascii码 
    $content = 'hello!'; 
    $e_content = aesEncrypt($key, $content); 
    echo "128-bit encrypted result:".$e_content.'<br>';        
    echo '解密:';     
    echo aesDecrypt($key, $e_content); 
  
    //--------AES-128-ECB加密方案-------- 
    // 调用的函数 
    function aesEncrypt($key, $content) { 
        $iv = 'iloveaes'; // ECB方案不需要iv 
        $content = pad2Length($content,16);     
        return bin2hex( mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key,$content,MCRYPT_MODE_ECB,$iv) ); #加密  
    } 
    function aesDecrypt($key, $hexstring) { 
        $iv = 'iloveaes'; // ECB方案不需要iv 
        $jiemi = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,hexToStr($hexstring),MCRYPT_MODE_ECB,$iv); #解密     
        return trimEnd($jiemi); 
    } 
    // 辅助函数 
    //将$text补足$padlen倍数的长度     
    function pad2Length($text, $padlen){     
        $len = strlen($text) % $padlen;     
        $res = $text;     
        $span = $padlen-$len; 
        for($i=0; $i<$span; $i++){     
            $res .= chr($span);                         
        }     
        return $res;     
    }     
    //将解密后多余的长度去掉(因为在加密的时候 补充长度满足block_size的长度)     
    function trimEnd($text){     
        $len = strlen($text);     
        $c = $text[$len-1];     
        if(ord($c) <$len){     
            for($i=$len-ord($c); $i<$len; $i++){     
                if($text[$i] != $c){     
                    return $text;     
                }     
            }     
            return substr($text, 0, $len-ord($c));     
        }     
        return $text;     
    }     
    //16进制的转为2进制字符串     
    function hexToStr($hex)      
    {      
        $bin="";      
        for($i=0; $i<strlen($hex)-1; $i+=2)      
        {     
            $bin.=chr(hexdec($hex[$i].$hex[$i+1]));      
        }     
        return $bin;      
    }  
?> 
 这样就可以手动进行加密的http通信啦!当然用来加密其他的字符串也可以……
 
 pack / unpack / scan / collect / join / sprintf ...什么的太讨厌了……根本就不知道自己在写些什么……反正能凑合用就行(微笑)
 
 其他资料:
 1. 在线AES加密网站:http://www.seacha.com/tools/aes.html 上面的2个脚本的输入输出都是和这个网站对标的。
 
 |