关于AES-CBC模式字节翻转攻击(python3)

# coding:utf-8
from Crypto.Cipher import AES
import base64


def encrypt(iv, plaintext):
    if len(plaintext) % 16 != 0:
        print("plaintext length is invalid")
        return
    if len(iv) != 16:
        print("IV length is invalid")
        return
    key = b"1234567890123456"
    aes_encrypt = AES.new(key, AES.MODE_CBC, IV=iv)
    result = base64.b64encode(aes_encrypt.encrypt(plaintext))
    return result


def decrypt(iv, cipher):
    if len(iv) != 16:
        print("IV length is invalid")
        print(len(iv))
        return
    key = b"1234567890123456"
    aes_decrypt = AES.new(key, AES.MODE_CBC, IV=iv)
    result = (aes_decrypt.decrypt(base64.b64decode(cipher)))
    return result

def test1():
    print("Change the first block plaintext:\n")
    iv = b'ABCDEFGH12345678'
    plaintext = b'0123456789ABCDEFhellocbcflipping0123456789123456'
    cipher = encrypt(iv, plaintext)
    print("NO ATTACK:", end='')
    print(cipher)
    local=2
    before='2'
    target='z'
    iv = list(iv)
    iv[local] = iv[local] ^ ord(before) ^ ord(target)
    decipher = decrypt(bytes(iv), cipher)
    print("ATTACK SUCCESS: Ciphertext doesn't need to be changed")
    print("NOW PLAINTEXT:",end='')
    print(decipher)
    print("NEW IV(base64 encode):",end='')
    print(base64.b64encode(bytes(iv)))

def test2():
    iv = b'ABCDEFGH12345678'
    plaintext = b'0123456789ABCDEFhellocbcflipping0123456789123456'
    cipher = encrypt(iv, plaintext)
    print("NO ATTACK:",end='')
    print(cipher)
    cipher = attack(cipher, 31, 'g', 'G')
    # 进行攻击 cipher是密文,31代表第几位,‘g’是原本的字符,‘G’是改变的字符
    decipher=decrypt(iv,cipher)
    print("NOW PLAINTEXT:", end='')
    print(decipher)
    #由于改变了密文,导致前一组解密乱码,需要修改iv值,先要求出新密文
    newiv=re(iv,decipher,b'0123456789ABCDEF')
    #求新的iv值,传入原iv值,新密文,和已知明文
    de_cipher = decrypt(newiv, cipher)
    print("NOW PLAINTEXT(NEW IV):", end='')
    print(de_cipher)


def attack( cipher, local, before, target):

    cipher = base64.b64decode(cipher)
    cipher = list(cipher)
    cipher[local - 16] = cipher[local - 16] ^ ord(before) ^ ord(target)
    cipher = base64.b64encode(bytes(cipher))
    print("ATTACK SUCCESS:",end='')
    print(cipher)
    return cipher


def re(iv, decipher, cleartext):
    decipher = list(decipher)
    cleartext = bytearray(cleartext)
    bin_iv=bytearray(iv)
    for i in range(0,len(iv)):
        bin_iv[i]= (decipher[i] ^ bin_iv[i] ^ cleartext[i])
    print("NEW IV(base64 encode):",end='')
    print(base64.b64encode(bin_iv))
    return bin_iv

test1()
#test1为改变第一组的函数
#test2()
#test2为改变不是第一组的函数
posted @ 2020-10-28 23:09  LLeaves  阅读(427)  评论(0编辑  收藏  举报