使用密码块链接在AES PyCrypto中的块大小关系

时间:2014-09-01 15:13:12

标签: python python-2.7 pycrypto

我正在使用numpy在以下代码中创建字符串或位数组,并使用微小的转换方法。

我想知道的是,给定明文,可以给出block_size = 128, 可以使用以下代码中的ECB使用AES标准解密全文吗?

from operator import add
from itertools import imap, izip
import numpy as np

from Crypto.Cipher import AES

ASCII_BITS = 8

XOR = lambda k,m: k ^ m

#converts a string to list of binary repr of char
mbin = lambda word: imap(np.binary_repr,imap(ord, word))
#concatenates list of N ASCII_BIT binary repr of char to one string
string_to_bits = lambda word: reduce(add,(i.zfill(ASCII_BITS) for i in mbin(word)))

#Converts byte string to int to ascii character
bits_to_string = lambda bitstr: ''.join([chr(int(bitstr[i:i+ASCII_BITS], 2)) for i in xrange(0,len(bitstr), ASCII_BITS)])

#Convert byte string to 1D matrix of bits
strbits_to_bitmat = lambda X: np.matrix(list(X), dtype=int)
#Convert 1D matrix of bits to byte string
bitmat_to_strbits = lambda X: ''.join((np.matrix(X, dtype=str)).tolist()[0])

def arr_ascii_bin_strchops(string, block_size):
    '''Array of ASCII Binary String Chops of size block_size'''
    return (string[i:i+block_size] for i in xrange(0,len(string),block_size))

这些是我正在使用的标准转换功能。

arr_ascii_bin_strchops :将一个字符串切换成block_size长度位字符串列表

编码器和解码器

def aes_encoder(block, key):
    #block = pad_bits_append(block, len(key))
    maxibit = abs(len(block)-len(key))
    block += ''.zfill(maxibit)
    # the pycrypto library expects the key and block in 8 bit ascii
    # encoded strings so we have to convert from the bit string
    block = bits_to_string(block)
    key = bits_to_string(key)
    ecb = AES.new(key, AES.MODE_ECB)
    return string_to_bits(ecb.encrypt(block))

def aes_decoder(block, key):
    #block = pad_bits_append(block, len(key))
    maxibit = abs(len(block)-len(key))
    block += ''.zfill(maxibit)
    # the pycrypto library expects the key and block in 8 bit ascii
    # encoded strings so we have to convert from the bit string
    block = bits_to_string(block)
    key = bits_to_string(key)
    #AES.new( self.key, AES.MODE_CBC, iv )
    ecb = AES.new(key, AES.MODE_ECB)
    return string_to_bits(ecb.decrypt(block))

CBC加密及其依赖方法

def crypto_cal(m,k,cminus,block_size,block_enc):
    '''
    for Cipher Block Chaining - Main Block_Enc(M^IV,Key)
    '''
    m += ''.zfill(block_size - len(m))
    k += ''.zfill(block_size - len(k))
    cminus += ''.zfill(block_size - len(cminus))

    cminus = np.matrix(list(cminus), dtype=int)
    m = np.matrix(list(m), dtype=int)
    #convert 1D XORed matrix of int to byte string
    xor = ''.join(np.matrix(XOR(cminus,m),dtype=str).tolist()[0])
    cminus = block_enc(xor,k)  #xor = iv ^ mbloc0
    return cminus

def cipher_block_chaining(plaintext, key, init_vec, block_size, block_enc):
    """Return the cbc encoding of `plaintext`

    Args:
        plaintext: bits to be encoded
        key: bits used as key for the block encoder
            init_vec: bits used as the initalization vector for
                  the block encoder
        block_size: size of the block used by `block_enc`
        block_enc: function that encodes a block using `key`
    """
    cipher = []
    key = string_to_bits(key)
    iv = string_to_bits(init_vec)
    plaintext = string_to_bits(plaintext)

    mbloc = arr_ascii_bin_strchops(plaintext,block_size)
    kbloc = arr_ascii_bin_strchops(key,block_size)
    iv = next(arr_ascii_bin_strchops(iv,block_size))
    mbloc0 = next(mbloc)
    kbloc0 = next(kbloc)
    cminus = crypto_cal(mbloc0,kbloc0,iv,block_size,block_enc)
    cipher.append(cminus)

    for m,k in izip(mbloc, kbloc):
        assert len(cminus) == block_size  #len(''.zfill(block_size - len(cminus)))
        cminus = crypto_cal(m,k,cminus,block_size,block_enc)
        cipher.append(cminus)
    return ''.join(cipher)

CBC解密及其依赖方法

def decrypto_cal(cipher_msg,key,cminus,block_size,block_enc):
    key += ''.zfill(block_size - len(key))
    cminus += ''.zfill(block_size - len(cminus))

    return bitmat_to_strbits(XOR(strbits_to_bitmat(block_enc(cipher_msg,key)),\
    strbits_to_bitmat(cminus)))

def cipher_block_decrypt(cipher, key, init_vec, block_size, block_enc):
    '''
    Return the cbc decoding of `cipher`

    Args:
        cipher: bit string to be decoded
        key: bits used as symmetric key for the block decoder
            init_vec: bits used as the initalization vector for
                  the block encoder/decoder
        block_size: size of the block used by `block_enc`
        block_enc: function that decodes a block using `key`
    '''
    cipher_blocks = []
    key = string_to_bits(key)
    iv = string_to_bits(init_vec)
    cipher = string_to_bits(cipher)
    #print "init vec {}".format(init_vec)
    iv = next(arr_ascii_bin_strchops(iv,block_size))
    kbloc = (arr_ascii_bin_strchops(key,block_size))
    cipher_chops = (arr_ascii_bin_strchops(cipher, block_size))
    lst = zip(cipher_chops, kbloc)
    cipher_blocks.extend([decrypto_cal(cipher_msg,key,lst[num-1][0],block_size,block_enc)\
     if num > 0 else decrypto_cal(cipher_msg,key,iv,block_size,block_enc) \
     for num,(cipher_msg,key) in enumerate(lst)])

    return ''.join(cipher_blocks)


def test():
    block_size = 256
    key = '4h8f.093mJo:*9#$'
    iv = '89JIlkj3$%0lkjdg'
    plaintext = "One if by land; two if by sea"
    cipher = (cipher_block_chaining(plaintext, key, iv, block_size, aes_encoder))
    cipher = bits_to_string(cipher)
    print "cipher {}".format(cipher)
    msg_bits = cipher_block_decrypt(cipher, key, iv, block_size, aes_decoder)
    p = bits_to_string(msg_bits)
    print p
    return

它使用256块大小并且能够解密整个明文但是使用128,只有

  

一个是陆地;

被解密。

为什么我只剪切那个大小的位串?它不应该限制字符串长度。 是否有一些使用的方法限制了字符串数组的总数?

0 个答案:

没有答案