class TestBlock(unittest.TestCase): """ Tests raw AES-128 block operations. """ def setUp(self): self.aes = AES(b'\00' * 16) def test_success(self): """ Should be able to encrypt and decrypt block messages. """ message = b'\01' * 16 ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) message = b'a secret message' ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) def test_bad_key(self): """ Raw AES requires keys of an exact size. """ with self.assertRaises(AssertionError): AES(b'short key') with self.assertRaises(AssertionError): AES(b'long key' * 10) def test_expected_value(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ message = b'\x32\x43\xF6\xA8\x88\x5A\x30\x8D\x31\x31\x98\xA2\xE0\x37\x07\x34' key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C' ciphertext = AES(bytes(key)).encrypt_block(bytes(message)) self.assertEqual(ciphertext, b'\x39\x25\x84\x1D\x02\xDC\x09\xFB\xDC\x11\x85\x97\x19\x6A\x0B\x32')
def _test_ecb(test_vals, test_key): for pt_str, ct_str in test_vals: pt_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', pt_str)]) pt_copy = copy.copy(pt_bytes) ct_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', ct_str)]) aes_ecb = AES(mode='ecb', key=test_key) aes_ecb.encrypt(pt_bytes) assert pt_bytes == ct_bytes, "AES ECB mode encryption failure" aes_ecb.decrypt(pt_bytes) assert pt_bytes == pt_copy, "AES ECB mode decryption failure"
def __init__(self, name, address, txseq, rxseq, key, interface, initial_unlock): self.name = name self.address = address self.txseq = txseq self.rxseq = rxseq self.key = [int(x) for x in key.split()] self.aes = AES() self.interface = interface self.open = False self.closed = False self.locked = False self.unlocked = False self.supply_voltage = 0 self.command_time = 0 self.command_accepted = None self.command = None self.periodic = 10 self.relock_time = 0 self.desired_state = Door.LOCK_LOCKED self.buttons_toggle_state = None self.logger = logging.getLogger('logger') self.pressed_buttons = 0 self.initial_unlock = initial_unlock
class AES_TEST(unittest.TestCase): def setUp(self): master_key = 0x2b7e151628aed2a6abf7158809cf4f3c self.AES = AES(master_key) def test_encryption(self): plaintext = 0x3243f6a8885a308d313198a2e0370734 encrypted = self.AES.encrypt(plaintext) self.assertEqual(encrypted, 0x3925841d02dc09fbdc118597196a0b32) def test_decryption(self): ciphertext = 0x3925841d02dc09fbdc118597196a0b32 decrypted = self.AES.decrypt(ciphertext) self.assertEqual(decrypted, 0x3243f6a8885a308d313198a2e0370734)
def get_challenge_response(self, challenge, secret_style, salt): m = hashlib.sha256() m.update(BotClient.get_shared_secret(self.password, secret_style, salt)) digest = m.digest() key = [digest[0:16], digest[16:32]] for i in range(2): key[i] = array('B', key[i]).tolist() aes = AES() challenge = aes.decrypt(challenge, key[1], 16) challenge = aes.decrypt(challenge, key[0], 16) r = unpack('>i', pack('BBBB', challenge[0], challenge[1], challenge[2], challenge[3]))[0] + 1 response = array('B', pack('>i', r)).tolist() while len(response) < 16: response.append(0) response = aes.encrypt(response, key[0], 16) response = aes.encrypt(response, key[1], 16) return response
def cbc_decrypt(cache, cipher, inv=None): if cache is None: raise ValueError('Key cache is NULL.') elif cipher is None: raise ValueError('Ciphertext is NULL.') else: aes = AES() nbr_rounds = 0 esize = len(cache) if esize == aes.ekeySize['SIZE_128']: nbr_rounds = 10 elif esize == aes.ekeySize['SIZE_192']: nbr_rounds = 12 elif esize == aes.ekeySize['SIZE_256']: nbr_rounds = 14 else: raise ValueError('Expanded key has size incorrect.' 'Size should be 176, 208, or either 240 bytes.') # the AES input/output ciphertext = [] iput = [] output = [] plaintext = [0] * 16 # the output plain text string string_out = bytes() if inv is None: inv = [0] * 16 # char firstRound first_round = True if cipher != None: for j in range(int(math.ceil(float(len(cipher))/16))): start = j * 16 end = start + 16 if j * 16 + 16 > len(cipher): end = len(cipher) ciphertext = cipher[start:end] output = aes.decrypt(ciphertext, cache, nbr_rounds) for i in range(16): if first_round: plaintext[i] = inv[i] ^ output[i] else: plaintext[i] = iput[i] ^ output[i] first_round = False string_out += struct.pack('B' *len(plaintext), *plaintext) iput = ciphertext return string_out
def test_cfb128_aes192_f315(): """ From NIST special publication 800-38A, section F.3.15 """ key_str = '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' iv_str = '000102030405060708090a0b0c0d0e0f' pt_str = ( '6bc1bee22e409f96e93d7e117393172a' 'ae2d8a571e03ac9c9eb76fac45af8e51' '30c81c46a35ce411e5fbc1191a0a52ef' 'f69f2445df4f9b17ad2b417be66c3710' ) ct_str = ( 'cdc80d6fddf18cab34c25909c99a4174' '67ce7f7f81173621961a2b70171d3d7a' '2e1e8a1dd59b88b1c8e60fed1efac4c9' 'c05f9f9ca9834fa042ae8fba584b09ff' ) key_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', key_str)]) iv_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', iv_str)]) pt_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', pt_str)]) pt_copy = copy.copy(pt_bytes) ct_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', ct_str)]) aes_cfb = AES(mode='cfb', key=key_bytes, iv=iv_bytes) aes_cfb.encrypt(pt_bytes) assert pt_bytes == ct_bytes, "AES CFB mode encryption failure" aes_cfb.reset() aes_cfb.decrypt(pt_bytes) assert pt_bytes == pt_copy, "AES CFB mode decryption failure"
def test_ofb_aes256_f46(): """ From NIST special publication 800-38A, section F.4.6 """ key_str = '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' iv_str = '000102030405060708090a0b0c0d0e0f' ct_str = ( 'dc7e84bfda79164b7ecd8486985d3860' '4febdc6740d20b3ac88f6ad82a4fb08d' '71ab47a086e86eedf39d1c5bba97c408' '0126141d67f37be8538f5a8be740e484' ) pt_str = ( '6bc1bee22e409f96e93d7e117393172a' 'ae2d8a571e03ac9c9eb76fac45af8e51' '30c81c46a35ce411e5fbc1191a0a52ef' 'f69f2445df4f9b17ad2b417be66c3710' ) key_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', key_str)]) iv_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', iv_str)]) ct_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', ct_str)]) ct_copy = copy.copy(ct_bytes) pt_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', pt_str)]) aes_ofb = AES(mode='ofb', key=key_bytes, iv=iv_bytes) aes_ofb.decrypt(ct_bytes) assert ct_bytes == pt_bytes, "AES OFB mode encryption failure" aes_ofb.reset() aes_ofb.encrypt(ct_bytes) assert ct_bytes == ct_copy, "AES OFB mode decryption failure"
def test_ctr_aes192_f53(): """ From NIST special publication 800-38A, section F.5.3 """ key_str = '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' counter_str = 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff' pt_str = ( '6bc1bee22e409f96e93d7e117393172a' 'ae2d8a571e03ac9c9eb76fac45af8e51' '30c81c46a35ce411e5fbc1191a0a52ef' 'f69f2445df4f9b17ad2b417be66c3710' ) ct_str = ( '1abc932417521ca24f2b0459fe7e6e0b' '090339ec0aa6faefd5ccc2c6f4ce8e94' '1e36b26bd1ebc670d1bd1d665620abf7' '4f78a7f6d29809585a97daec58c6b050' ) key_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', key_str)]) counter_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', counter_str)]) pt_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', pt_str)]) pt_copy = copy.copy(pt_bytes) ct_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', ct_str)]) aes_ctr = AES(mode='ctr', key=key_bytes, iv=counter_bytes) aes_ctr.encrypt(pt_bytes) assert pt_bytes == ct_bytes, "AES CTR mode encryption failure" aes_ctr.reset() aes_ctr.decrypt(pt_bytes) assert pt_bytes == pt_copy, "AES CTR mode decryption failure"
def test_cbc_128_f21(): """ Verify that 4-block CBC encryption works From NIST special publication 800-38A, section F.2.1 """ key_str = '2b7e151628aed2a6abf7158809cf4f3c' iv_str = '000102030405060708090a0b0c0d0e0f' pt_str = ( '6bc1bee22e409f96e93d7e117393172a' 'ae2d8a571e03ac9c9eb76fac45af8e51' '30c81c46a35ce411e5fbc1191a0a52ef' 'f69f2445df4f9b17ad2b417be66c3710' ) ct_str = ( '7649abac8119b246cee98e9b12e9197d' '5086cb9b507219ee95db113a917678b2' '73bed6b8e3c1743b7116e69e22229516' '3ff1caa1681fac09120eca307586e1a7' ) key_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', key_str)]) iv_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', iv_str)]) pt_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', pt_str)]) pt_copy = copy.copy(pt_bytes) ct_bytes = bytearray([int(v, 16) for v in re.findall(r'..?', ct_str)]) aes_cbc = AES(mode='cbc', key=key_bytes, iv=iv_bytes) aes_cbc.encrypt(pt_bytes) assert pt_bytes == ct_bytes, "AES CBC mode encryption failure" aes_cbc.reset() aes_cbc.decrypt(pt_bytes) assert pt_bytes == pt_copy, "AES CBC mode decryption failure"
def get_roundkey_cache(key): if key is None: raise ValueError('Key is NULL.') else: aes = AES() nbr_rounds = 0 size = len(key) if size == aes.keySize['SIZE_128']: nbr_rounds = 10 elif size == aes.keySize['SIZE_192']: nbr_rounds = 12 elif size == aes.keySize['SIZE_256']: nbr_rounds = 14 else: raise ValueError('Key size is incorrect.' 'Size should be 16, 24, or either 32 bytes.') expanded_keysize = 16 * (nbr_rounds + 1) return aes.expandKey(key, size, expanded_keysize)
def aes_cbc_decrypt(key, ciphertext, iv=None): """ Decrypts a ciphertext that was encrypted with AES en CBC mode. If IV is not given take the first ciphertext block. """ aes = AES(key) encrypted_blocks = divide(ciphertext, AES.BLOCK_SIZE) if not iv: iv = encrypted_blocks.pop(0) decrypted_blocks = [] previous = iv for block in encrypted_blocks: data = xor(previous, aes.decrypt_block(block)) previous = block decrypted_blocks.append(data) return unpad_pkcs7(b''.join(decrypted_blocks))
def encryptAES(self): try: self.lineEdit_plaintext.text().decode('ascii') except: self.showdialog() else: aes = AES(self.lineEdit_key.text().encode('latin-1')) self.ciphertext = aes.EncryptAES( self.lineEdit_plaintext.text().encode('latin-1')) # self.lineEdit_cyphertext.setText(''.join( [ "%02X " % ord( x ) for x in self.ciphertext ] ).strip()) cyphertext = '' for item in self.ciphertext: for i in range(0, 4): tmp = item[i] #.strip("0x") # tmp = int(tmp, 16) # print tmp # tmp = unichr(tmp) # print type(tmp), tmp cyphertext = cyphertext + tmp + " " #.encode("latin-1") self.lineEdit_cyphertext.setText(cyphertext)
def testInvCipher(self): debug = True aes = AES(debug) if debug: print '=========================================================' print 'AES-128 Nk = 4 Nr = 10' print 'plaintext = 00112233445566778899aabbccddeeff' print 'key = 000102030405060708090a0b0c0d0e0f' print 'DECRYPTION' print '=========================================================' testInput = 0x69c4e0d86a7b0430d8cdb78070b4c55a testKey = 0x000102030405060708090a0b0c0d0e0f nk = 4 nr = 10 testOutput = 0x00112233445566778899aabbccddeeff outputState = aes.toMatrix(testOutput) self.assertEquals(aes.invCipher(testInput, testKey, nk, nr), outputState) if debug: print '\n\n' print '=========================================================' print 'AES-192 Nk = 6 Nr = 12' print 'plaintext = 00112233445566778899aabbccddeeff' print 'key = 000102030405060708090a0b0c0d0e0f1011121314151617' print 'DECRYPTION' print '=========================================================' testInput = 0xdda97ca4864cdfe06eaf70a0ec0d7191 testKey = 0x000102030405060708090a0b0c0d0e0f1011121314151617 nk = 6 nr = 12 testOutput = 0x00112233445566778899aabbccddeeff outputState = aes.toMatrix(testOutput) self.assertEquals(aes.invCipher(testInput, testKey, nk, nr), outputState) if debug: print '\n\n' print '=========================================================' print 'AES-256 Nk = 8 Nr = 14' print 'plaintext = 00112233445566778899aabbccddeeff' print 'key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' print 'DECRYPTION' print '=========================================================' testInput = 0x8ea2b7ca516745bfeafc49904b496089 testKey = 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f nk = 8 nr = 14 testOutput = 0x00112233445566778899aabbccddeeff outputState = aes.toMatrix(testOutput) self.assertEquals(aes.invCipher(testInput, testKey, nk, nr), outputState)
def cbc_encrypt(cache, msg, inv=None): if cache is None: raise ValueError('Key cache is NULL.') elif msg is None: raise ValueError('Message is NULL.') else: aes = AES() nbr_rounds = 0 esize = len(cache) if esize == aes.ekeySize['SIZE_128']: nbr_rounds = 10 elif esize == aes.ekeySize['SIZE_192']: nbr_rounds = 12 elif esize == aes.ekeySize['SIZE_256']: nbr_rounds = 14 else: raise ValueError('Expanded key has incorrect size.' 'Size should be 176, 208, or either 240 bytes.') plaintext = [] iput = [0] * 16 output = [] cipher = [0] * 16 if inv is None: inv = [0] * 16 first_round = True if msg is not None: for j in range(int(math.ceil(float(len(msg))/16))): start = j * 16 end = start + 16 if end > len(msg): end = len(msg) plaintext = msg[start:end] for i in range(16): if first_round: iput[i] = plaintext[i] ^ inv[i] else: iput[i] = plaintext[i] ^ cipher[i] first_round = False cipher = aes.encrypt(iput, cache, nbr_rounds) output.extend(cipher) return struct.pack('B' * len(output), *output)
def cbc_encrypt(cache, msg, inv=None): if cache is None: raise ValueError('Key cache is NULL.') elif msg is None: raise ValueError('Message is NULL.') else: aes = AES() nbr_rounds = 0 esize = len(cache) if esize == aes.ekeySize['SIZE_128']: nbr_rounds = 10 elif esize == aes.ekeySize['SIZE_192']: nbr_rounds = 12 elif esize == aes.ekeySize['SIZE_256']: nbr_rounds = 14 else: raise ValueError('Expanded key has incorrect size.' 'Size should be 176, 208, or either 240 bytes.') plaintext = [] iput = [0] * 16 output = [] cipher = [0] * 16 if inv is None: inv = [0] * 16 first_round = True if msg is not None: for j in range(int(math.ceil(float(len(msg)) / 16))): start = j * 16 end = start + 16 if end > len(msg): end = len(msg) plaintext = msg[start:end] for i in range(16): if first_round: iput[i] = plaintext[i] ^ inv[i] else: iput[i] = plaintext[i] ^ cipher[i] first_round = False cipher = aes.encrypt(iput, cache, nbr_rounds) output.extend(cipher) return struct.pack('B' * len(output), *output)
def test_ocb(self): for key_len in (128, 192, 256): aes = AES(key_len) ocb = OCB(aes) ocb.setNonce(self.nonce) ocb.setKey(bytearray(range(key_len/8))) plaintext = bytearray('The Magic Words are Squeamish Ossifrage') header = bytearray('Recipient: [email protected]') (tag, ciphertext) = ocb.encrypt(plaintext, header) # decryption aes = AES(key_len) ocb = OCB(aes) ocb.setNonce(self.nonce) ocb.setKey(bytearray(range(key_len/8))) (is_valid, plaintext2) = ocb.decrypt(header, ciphertext, tag) self.assertTrue(is_valid) self.assertEqual(plaintext2, plaintext)
def test_expected_value(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ message = b'\x32\x43\xF6\xA8\x88\x5A\x30\x8D\x31\x31\x98\xA2\xE0\x37\x07\x34' key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C' ciphertext = AES(bytes(key)).encrypt_block(bytes(message)) self.assertEqual( ciphertext, b'\x39\x25\x84\x1D\x02\xDC\x09\xFB\xDC\x11\x85\x97\x19\x6A\x0B\x32' )
def DecryptData(cipherText, HandlerAESKey, Server): AESfunct = AES(HandlerAESKey) stringOfCipherText = str(hex(cipherText)) stringOfCipherText = stringOfCipherText[2:] listOfBlocks = textwrap.wrap(stringOfCipherText, 32) decryptedString = "0x" i = 0 for x in listOfBlocks: #print("Decrypting Block %d = "%i,x) xHex = int(x, 16) decryptedData = AES.decrypt(AESfunct, xHex) tempStr = str(hex(decryptedData)) tempStr = tempStr[2:] decryptedString += tempStr i += 1 temp = binascii.unhexlify(((str('%00x' % int(decryptedString, 16))))) tempDecoded = str(temp, 'utf-8')[:] Server.Evidence = tempDecoded return 0
def generateHash(self, message): """ The KMS v4 hash is a variant of CMAC-AES-128. There are two key differences: * The 'AES' used is modified in particular ways: * The basic algorithm is Rjindael with a conceptual 160bit key and 128bit blocks. This isn't part of the AES standard, but it works the way you'd expect. Accordingly, the algorithm uses 11 rounds and a 192 byte expanded key. * The trailing block is not XORed with a generated subkey, as defined in CMAC. This is probably because the subkey generation algorithm is only defined for situations where block and key size are the same. """ aes = AES() messageSize = len(message) lastBlock = bytearray(16) hashBuffer = bytearray(16) # MessageSize / Blocksize. j = messageSize >> 4 # Remainding bytes. k = messageSize & 0xf # Hash. for i in range(0, j): xorBuffer(message, i << 4, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key))) # Bit Padding. ii = 0 for i in range(j << 4, k + (j << 4)): lastBlock[ii] = message[i] ii += 1 lastBlock[k] = 0x80 xorBuffer(lastBlock, 0, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key))) return hashBuffer #*2to3*
def generateHash(self, message): """ The KMS v4 hash is a variant of CMAC-AES-128. There are two key differences: * The 'AES' used is modified in particular ways: * The basic algorithm is Rjindael with a conceptual 160bit key and 128bit blocks. This isn't part of the AES standard, but it works the way you'd expect. Accordingly, the algorithm uses 11 rounds and a 192 byte expanded key. * The trailing block is not XORed with a generated subkey, as defined in CMAC. This is probably because the subkey generation algorithm is only defined for situations where block and key size are the same. """ aes = AES() messageSize = len(message) lastBlock = bytearray(16) hashBuffer = bytearray(16) # MessageSize / Blocksize j = messageSize >> 4 # Remainding bytes k = messageSize & 0xf # Hash for i in range(0, j): xorBuffer(message, i << 4, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key))) # Bit Padding ii = 0 for i in range(j << 4, k + (j << 4)): lastBlock[ii] = message[i] ii += 1 lastBlock[k] = 0x80 xorBuffer(lastBlock, 0, hashBuffer, 16) hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key))) return str(hashBuffer)
def ex3(m, i, j, key=0x2b7e151628aed2a6abf7158809cf4f3c): normal = AES(key, customMixColumns=False) change = AES(key, customMixColumns=True) mi = change_i_bit(m, i) c = normal.encrypt(m) ci = normal.encrypt(mi) c2 = change.encrypt(m) ci2 = change.encrypt(mi) print("m, mi") print(m, ",", mi) print("----------------") print("c, ci") print(c, ",", ci)
def encrypt_files(files): key = os.urandom(32) aes = AES.AES(key) ivs = {} for file in files: with open(file, 'rb') as f_in: content = f_in.read() encrypted_content, iv = aes.encrypt(content) ivs[file] = iv with open(file, "wb") as f_out: f_out.write(encrypted_content) return key, ivs
class TestBlock(unittest.TestCase): """ Tests raw AES-128 block operations. """ def setUp(self): self.aes = AES(b'\00' * 16) def test_success(self): """ Should be able to encrypt and decrypt block messages. """ message = b'\01' * 16 ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) message = b'a secret message' ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) def test_bad_key(self): """ Raw AES requires keys of an exact size. """ with self.assertRaises(AssertionError): AES(b'short key') with self.assertRaises(AssertionError): AES(b'long key' * 10) def test_expected_value(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ message = b'\x32\x43\xF6\xA8\x88\x5A\x30\x8D\x31\x31\x98\xA2\xE0\x37\x07\x34' key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C' ciphertext = AES(bytes(key)).encrypt_block(bytes(message)) self.assertEqual( ciphertext, b'\x39\x25\x84\x1D\x02\xDC\x09\xFB\xDC\x11\x85\x97\x19\x6A\x0B\x32' )
def __init__(self, address, txseq, rxseq, key, interface, command_queue): self.address = address self.txseq = txseq self.rxseq = rxseq self.key = [int(x) for x in key.split()] self.aes = AES() self.interface = interface self.supply_voltage = 0 self.periodic = 10 self.logger = logging.getLogger("logger") self.pressed_buttons = 0 self.command_queue = command_queue self.all_locked = False
def test_wrong(self): # Take one of the predefined ciphertext/tag pairs (header, plaintext, expected_tag, expected_ciphertext) = ('0001020304050607', '0001020304050607', '8D059589EC3B6AC00CA31624BC3AF2C6', 'C636B3A868F429BB') aes = AES(128) ocb = OCB(aes) ocb.setNonce(self.nonce) ocb.setKey(self.key) # Tamper with tag (dec_valid, dec_plaintext) = ocb.decrypt(bytearray().fromhex(header), bytearray().fromhex(expected_ciphertext), bytearray().fromhex(expected_tag.replace('0', '1'))) self.assertFalse(dec_valid) # Tamper with ciphertext (dec_valid, dec_plaintext) = ocb.decrypt(bytearray().fromhex(header), bytearray().fromhex(expected_ciphertext.replace('3', '1')), bytearray().fromhex(expected_tag)) self.assertFalse(dec_valid) # Tamper with header (dec_valid, dec_plaintext) = ocb.decrypt(bytearray().fromhex(header.replace('0', '1')), bytearray().fromhex(expected_ciphertext), bytearray().fromhex(expected_tag)) self.assertFalse(dec_valid)
def run(keypath, keysize, inputfile, outputfile, mode, operation): with open(keypath, 'rb') as key_content: key = key_content.read() aes = AES(key, keysize) if mode == 'encrypt': with open(inputfile, 'rb') as plaintext, open(outputfile, 'w+b') as encrypted: aes.encrypt_file(plaintext, encrypted, operation) elif mode == 'decrypt': with open(inputfile, 'rb') as encrypted, open(outputfile, 'w+b') as plaintext: aes.decrypt_file(encrypted, plaintext, operation) else: raise Exception('invalid mode provided')
def create_room(): global start global camera global mic global user_id resp = make_response(redirect(url_for('home'))) msg.send_b(b'\x01') ms = msg.rec_b() uid = str(uuid.uuid4()).encode() uid = b'\x05' + uid[1:] aes_key = uid[1:8] + uid[9:13] + uid[14:18] + bytes([uid[19]]) aes = AES(aes_key) msg.set_aes(aes) msg.send_b(b'\x05' + uid) user_data = ms[1:].decode() resp.set_cookie('room', user_data[3:]) resp.set_cookie('id', user_data[:3]) user_id = int(user_data[:3]) camera = True start = True mic = False time.sleep(1.5) return resp
def symmetric_cipher(self): """Selects a symmetric-key chiper. :return: an object of one of the symmetric-key encryption classes or None """ _cipher = None if self.algorithm == AlgEnum.CAESAR.name: _cipher = Caesar() if self.algorithm == AlgEnum.VIGENERE.name: _cipher = Vigenere() if self.algorithm == AlgEnum.AES.name: _cipher = AES() if self.algorithm == AlgEnum.DES.name: _cipher = DES() if self.algorithm == AlgEnum.MAGMA.name: _cipher = Magma() if self.algorithm == AlgEnum.KUZNECHIK.name: _cipher = Kuznechik() if self.algorithm == AlgEnum.RSA.name: _cipher = Kuznechik() return _cipher
def aes_cbc_decrypt(key, ciphertext): aes = AES() def cbc_heart(key, iv, block): #print "block: %r, key: %r, iv: %r" % (block, key, iv) output = aes.decrypt(struct.unpack('>' + 'B' * 16, block), struct.unpack('>' + 'B' * 16, key), 16) return strxor(iv, struct.pack('>' + 'B' * 16, *output)) iv = None plaintext = '' for block in group_by(ciphertext, 16): block = "".join(block) if not iv: iv = block continue plaintext += cbc_heart(key, iv, block) iv = block padding = struct.unpack('>B', plaintext[-1:])[0] print "padding: ", padding return plaintext[-1 * padding:].encode('hex')
def main(): cryptography = AES() mode = True while mode: prompt = input("Do you want to encrypt or decrypt your message? enter q to quit") if prompt == "encrypt": key = input("enter a key 16 characters long ONLY") file = input("choose a file to encrypt") cryptography.encrypt_File(file,key) print("File " + file + " has been encrypted") elif prompt == "decrypt": key = input("enter a key 16 characters long ONLY") file = input("choose a file to decrypt") cryptography.decrypt_File(file, key) print("File " + file + " has been decrypted") elif prompt == 'q': mode = False else: print("that wasn't an option try again please")
p = psutil.Process(os.getpid()) proc_list = p.cpu_affinity() p.cpu_affinity([proc_list[-1]]) # Perform several encryption / decryption operations random_iv = bytearray(os.urandom(16)) random_key = bytearray(os.urandom(16)) data = bytearray(list(range(256))) data1 = data[:151] data2 = data[151:] # Note: __PROFILE_AES__ must be defined when building the native # module in order for the print statements below to work aes_ctr = AES(mode='ctr', key=random_key, iv=random_iv) result = aes_ctr.encrypt(data1) if result: print('Encrypted data1 in: %5d cycles' % result) result = aes_ctr.encrypt(data2) if result: print('Encrypted data2 in: %5d cycles' % result) data_new = data1 + data2 aes_ctr = AES(mode='ctr', key=random_key, iv=random_iv) result = aes_ctr.decrypt(data_new) if result: print('Decrypted data in: %5d cycles' % result) assert data == data_new, "The demo has failed."
def test_256(self): aes = AES(b'P' * 32) message = b'M' * 16 ciphertext = aes.encrypt_block(message) self.assertEqual(aes.decrypt_block(ciphertext), message)
def setUp(self): self.aes = AES(b'\x00' * 16)
class TestCbc(unittest.TestCase): """ Tests AES-128 in CBC mode. """ def setUp(self): self.aes = AES(b'\x00' * 16) self.iv = b'\x01' * 16 self.message = b'my message' def test_single_block(self): """ Should be able to encrypt and decrypt single block messages. """ ciphertext = self.aes.encrypt_cbc(self.message, self.iv) self.assertEqual(self.aes.decrypt_cbc( ciphertext, self.iv), self.message) # Since len(message) < block size, padding won't create a new block. self.assertEqual(len(ciphertext), 16) def test_wrong_iv(self): """ CBC mode should verify the IVs are of correct length.""" with self.assertRaises(AssertionError): self.aes.encrypt_cbc(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.encrypt_cbc(self.message, b'long iv' * 16) with self.assertRaises(AssertionError): self.aes.decrypt_cbc(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.decrypt_cbc(self.message, b'long iv' * 16) def test_different_iv(self): """ Different IVs should generate different ciphertexts. """ iv2 = b'\x02' * 16 ciphertext1 = self.aes.encrypt_cbc(self.message, self.iv) ciphertext2 = self.aes.encrypt_cbc(self.message, iv2) self.assertNotEqual(ciphertext1, ciphertext2) plaintext1 = self.aes.decrypt_cbc(ciphertext1, self.iv) plaintext2 = self.aes.decrypt_cbc(ciphertext2, iv2) self.assertEqual(plaintext1, plaintext2) self.assertEqual(plaintext1, self.message) def test_whole_block_padding(self): """ When len(message) == block size, padding will add a block. """ block_message = b'M' * 16 ciphertext = self.aes.encrypt_cbc(block_message, self.iv) self.assertEqual(len(ciphertext), 32) self.assertEqual(self.aes.decrypt_cbc( ciphertext, self.iv), block_message) def test_long_message(self): """ CBC should allow for messages longer than a single block. """ long_message = b'M' * 100 ciphertext = self.aes.encrypt_cbc(long_message, self.iv) self.assertEqual(self.aes.decrypt_cbc( ciphertext, self.iv), long_message)
class TestCtr(unittest.TestCase): """ Tests AES-128 in CBC mode. """ def setUp(self): self.aes = AES(b'\x00' * 16) self.iv = b'\x01' * 16 self.message = b'my message' def test_single_block(self): """ Should be able to encrypt and decrypt single block messages. """ ciphertext = self.aes.encrypt_ctr(self.message, self.iv) self.assertEqual(self.aes.decrypt_ctr( ciphertext, self.iv), self.message) # Stream mode ciphers don't increase message size. self.assertEqual(len(ciphertext), len(self.message)) def test_wrong_iv(self): """ CBC mode should verify the IVs are of correct length.""" with self.assertRaises(AssertionError): self.aes.encrypt_ctr(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.encrypt_ctr(self.message, b'long iv' * 16) with self.assertRaises(AssertionError): self.aes.decrypt_ctr(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.decrypt_ctr(self.message, b'long iv' * 16) def test_different_iv(self): """ Different IVs should generate different ciphertexts. """ iv2 = b'\x02' * 16 ciphertext1 = self.aes.encrypt_ctr(self.message, self.iv) ciphertext2 = self.aes.encrypt_ctr(self.message, iv2) self.assertNotEqual(ciphertext1, ciphertext2) plaintext1 = self.aes.decrypt_ctr(ciphertext1, self.iv) plaintext2 = self.aes.decrypt_ctr(ciphertext2, iv2) self.assertEqual(plaintext1, plaintext2) self.assertEqual(plaintext1, self.message) def test_whole_block_padding(self): block_message = b'M' * 16 ciphertext = self.aes.encrypt_ctr(block_message, self.iv) self.assertEqual(len(ciphertext), len(block_message)) self.assertEqual(self.aes.decrypt_ctr( ciphertext, self.iv), block_message) def test_long_message(self): long_message = b'M' * 100 ciphertext = self.aes.encrypt_ctr(long_message, self.iv) self.assertEqual(self.aes.decrypt_ctr( ciphertext, self.iv), long_message)
def test_expected_values256(self): message = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' aes = AES(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f') ciphertext = aes.encrypt_block(message) self.assertEqual(ciphertext, b'\x8e\xa2\xb7\xca\x51\x67\x45\xbf\xea\xfc\x49\x90\x4b\x49\x60\x89') self.assertEqual(aes.decrypt_block(ciphertext), message)
def setUp(self): master_key = 0x2b7e151628aed2a6abf7158809cf4f3c self.AES = AES(master_key)
def setUp(self): self.aes = AES(b'\00' * 16) self.iv = b'\01' * 16 self.message = b'my message'
def setUp(self): self.aes = AES(b'\00' * 16)
def get_urls(url): urls = [] servers = { 1:{'server': 'http://58.254.39.6:80/', 'cmd': '\x36\x00\x00\x00\x09\x00\x00\x00', 'key': '\xB6\xC3\x0A\xEB\x99\xCA\xF8\x49\xA7\x34\xCE\x4B\xFD\x90\x6C\x54'}, 2:{'server': 'http://123.129.242.169:80/', 'cmd': '\x36\x00\x00\x00\x55\x00\x00\x00', 'key': '\x18\x3A\x7F\x85\xE4\x21\xC7\x58\x06\x18\x6C\x63\x32\x86\x1E\xCD'}, #3:{'server': 'http://123.129.242.168:80/', # 'cmd': '\x36\x00\x00\x00\x57\x00\x00\x00', # 'key': '\x64\x91\x63\x9D\xE8\x09\x87\x4D\xA5\x0A\x12\x02\x3F\x25\x3C\xF0'} #4:{'server': 'http://123.129.242.168:80/', # 'cmd':'\x36\x00\x00\x00\xf7\x00\x00\x00', # 'key':'\x2D\x33\xD2\x89\x46\xC3\xF8\x39\x76\x7B\xC4\x2F\x46\x1C\x45\x4C'} } for s in servers.values(): server = s['server'] cmd = s['cmd'] key = s['key'] a = AES(key) plaintext = '' plaintext += 'd\x02\x05\x00\x00\x00\xd1\x07\x00' plaintext += pack('<l',len(url)) plaintext += url plaintext += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x10\x00\x00\x0000030D3F968AAYV4\x00\x00\x00\x00j\x01\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x000000\x04\x00\x00\x00' #alignment length = len(plaintext) _,extra = divmod(length,16) if extra: plaintext += chr(extra)*(16-extra) else: plaintext += chr(16)*16 #printf(plaintext) #encryption ciphertext = a.encrypt(plaintext) #printf(ciphertext) #add 12 bytes[command+len] data = '' data += cmd data += pack('<l',len(ciphertext)) data += ciphertext #printf(data) headers = { 'Accept':'*/*', 'Content-type':'application/octet-stream', 'Connection':'Keep-Alive', } opener = urllib2.build_opener() urllib2.install_opener(opener) request = urllib2.Request(server,headers = headers,data=data) try: conn = urllib2.urlopen(request) except urllib2.URLError: continue result = conn.read() #decryption;ignore the first 12 bytes. plaintext = a.decrypt(result[12:]) #printf(plaintext) urls.extend(parse(plaintext)) return list(set(urls))
def test_expected_values192(self): message = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF' aes = AES(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17') ciphertext = aes.encrypt_block(message) self.assertEqual(ciphertext, b'\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0\x6e\xaf\x70\xa0\xec\x0d\x71\x91') self.assertEqual(aes.decrypt_block(ciphertext), message)
def __init__(self, key=None, padding=padWithPadLen(), keySize=16): CBC.__init__(self, AES(key, noPadding(), keySize), padding) self.name = 'AES_CBC'
#-*- coding:utf-8 -*- from z3 import * from aes import AES encflag = "".join("81 74 45 2d f0 56 70 7d 15 82 d8 23 c2 e3 a2 d2".split()).decode("hex") # k11 knownsubkey = "d044e824a4bdc5eb143c74fbc0491c64".decode("hex") knownsubkey = map(ord, knownsubkey) base = 16*11 AES = AES() s = Solver() # make sboxes z3-compatinle rcon = AES.Rcon[::] AES.Rcon = Array("rcon", BitVecSort(8), BitVecSort(8)) for x in xrange(255): s.add(AES.Rcon[x] == rcon[x]) sbox = AES.sbox[::] AES.sbox = Array("sbox", BitVecSort(8), BitVecSort(8)) for x in xrange(256): s.add(AES.sbox[x] == sbox[x]) # compute symbolically master = [BitVec("master%d" % i, 8) for i in xrange(16)] exp = AES.expandKey(master, 16, 15*16) # set constraint
plaintext = "" #KEY for _ in range(16): key_digit = hex(random.randint(0, 255))[2:] if len(key_digit) == 1: key_digit = "0" + key_digit private_key += key_digit # PLAINTEXT for _ in range(num_blocks * 16): text_digit = hex(random.randint(0, 127))[2:] if len(text_digit) == 1: text_digit = "0" + text_digit plaintext += text_digit aes = AES(private_key) ciphertext = aes.encrypt(plaintext) decrypted_text = aes.decrypt(ciphertext) if plaintext != decrypted_text: # Log data if there is a mismatch print("NOT MATCHING") print("Key: ", key) print("PLaintext: ", plaintext) print("Length of plaintext", len(plaintext)) print() print(decrypted_text) exit() except Exception: # Log data if there is an exception print("Met exception!")
import os, psutil from aes import AES # Pin the Python process to the last CPU to measure performance # Note: this code works for psutil 1.2.x, not 2.x! cpu_count = psutil.NUM_CPUS p = psutil.Process(os.getpid()) proc_list = p.get_cpu_affinity() p.set_cpu_affinity([proc_list[-1]]) # Perform several encryption / decryption operations random_iv = bytearray(os.urandom(16)) random_key = bytearray(os.urandom(16)) data = bytearray(list(range(256))) data1 = data[:151] data2 = data[151:] # Note: __PROFILE_AES__ must be defined when building the native # module in order for the print statements below to work aes_ctr = AES(mode='ctr', key=random_key, iv=random_iv) print('Encrypted data1 in: %5d cycles' % aes_ctr.encrypt(data1)) print('Encrypted data2 in: %5d cycles' % aes_ctr.encrypt(data2)) data_new = data1 + data2 aes_ctr = AES(mode='ctr', key=random_key, iv=random_iv) print('Decrypted data in: %5d cycles' % aes_ctr.decrypt(data_new)) print(data == data_new)
def setUp(self): self.aes = AES(b'\x00' * 16) self.iv = b'\x01' * 16 self.message = b'my message'
class Door: DOOR_CLOSED = (1<<0) LOCK_LOCKED = (1<<1) LOCK_UNLOCKED = (1<<2) LOCK_LOCKING = (1<<3) LOCK_UNLOCKING = (1<<4) HANDLE_PRESSED = (1<<5) LOCK_PERM_UNLOCKED = (1<<6) def __init__(self, name, address, txseq, rxseq, key, interface, initial_unlock): self.name = name self.address = address self.txseq = txseq self.rxseq = rxseq self.key = [int(x) for x in key.split()] self.aes = AES() self.interface = interface self.open = False self.closed = False self.locked = False self.unlocked = False self.supply_voltage = 0 self.command_time = 0 self.command_accepted = None self.command = None self.periodic = 10 self.relock_time = 0 self.desired_state = Door.LOCK_LOCKED self.buttons_toggle_state = None self.logger = logging.getLogger('logger') self.pressed_buttons = 0 self.initial_unlock = initial_unlock def unlock(self, relock_timeout=0): self.desired_state = Door.LOCK_UNLOCKED self.relock_time = time.time() + relock_timeout #if timeout: # self._send_command(command=ord('D'), data='\x02') #else: # self._send_command(command=ord('D'), data='\x01') def lock(self): self.desired_state = Door.LOCK_LOCKED self._send_command(command=ord('D'), data='\x00') def update(self, message): if len(message) != 16: self.logger.warning("The received message is not 16 bytes long") return message = self.aes.decrypt([ord(x) for x in message], self.key, AES.keySize["SIZE_128"]) message = ''.join([chr(x) for x in message]) self.logger.debug("Decoded message: %s"%str(list(message))) p = Packet.fromMessage(message) if p.cmd==83: self.supply_voltage = ord(p.data[3])*0.1 ''' pressed_buttons = 0 if self.buttons_toggle_state == None: self.buttons_toggle_state = ord(p.data[0]) else: pressed_buttons = self.buttons_toggle_state ^ ord(p.data[0]) self.buttons_toggle_state = ord(p.data[0]) if pressed_buttons: self.logger.info('Got pressed buttons: %d' % pressed_buttons) if pressed_buttons & 0x01: ''' pressed_buttons = ord(p.data[0]) if pressed_buttons & 0x01 and not self.pressed_buttons & 0x01: self.pressed_buttons |= 0x01 if self.desired_state == Door.LOCK_LOCKED: self.desired_state = Door.LOCK_UNLOCKED elif self.desired_state == Door.LOCK_UNLOCKED: self.desired_state = Door.LOCK_LOCKED elif not pressed_buttons & 0x01: self.pressed_buttons &= ~0x01 doorstate = ord(p.data[1]) state = '' self.closed = doorstate & Door.DOOR_CLOSED \ == Door.DOOR_CLOSED self.locked = doorstate & Door.LOCK_LOCKED \ == Door.LOCK_LOCKED self.unlocked = doorstate & Door.LOCK_UNLOCKED \ == Door.LOCK_UNLOCKED self.locking = doorstate & Door.LOCK_LOCKING \ == Door.LOCK_LOCKING self.unlocking = doorstate & Door.LOCK_UNLOCKING \ == Door.LOCK_UNLOCKING self.handle_pressed = doorstate & Door.HANDLE_PRESSED \ == Door.HANDLE_PRESSED self.perm_unlocked = doorstate & Door.LOCK_PERM_UNLOCKED \ == Door.LOCK_PERM_UNLOCKED self.logger.info('Door state: %s'%self.get_state()) self.logger.info('Desired door state: %s'%self.get_desired_state()) elif p.cmd==ord('A'): accepted = ord(p.data[0]) == 1 if not self.command_accepted: if accepted: self.logger.info('Command at %d was accepted'%self.command_time) self.command_accepted = True else: self.logger.warning('Command at %d was NOT accepted'% self.command_time) def get_state(self): state = '' if self.closed: state += ' CLOSED' if self.locked: state += ' LOCKED' if self.unlocked: state += ' UNLOCKED' if self.locking: state += ' LOCKING' if self.unlocking: state += ' UNLOCKING' if self.handle_pressed: state += ' HANDLE_PRESSED' if self.perm_unlocked: state += ' PERM_UNLOCKED' state = state.strip() state = state + ' Voltage=%.1f V'%self.supply_voltage return state def get_desired_state(self): state = '' if self.desired_state & Door.LOCK_LOCKED: state += ' LOCKED' if self.desired_state & Door.LOCK_UNLOCKED: state += ' UNLOCKED' state = state.strip() return state def tick(self): self.periodic-=1 if self.periodic == 0: self.periodic = 2 self._send_command(ord('D'), chr(self.desired_state)) if self.relock_time: if time.time() > self.relock_time: self.desired_state = Door.LOCK_LOCKED self.relock_time = 0 ''' if time.time() - self.command_time > 5: if self.command_accepted == False: print 'Error: Command at %d was not accepted!' elif self.command_accepted == None: print 'Error: Command was not received' ''' def _send_command(self, command, data): p = Packet(seq=self.txseq, cmd=command, data=data) msg = self.aes.encrypt([ord(x) for x in p.toMessage()], self.key, AES.keySize["SIZE_128"]) msg = ''.join([chr(x) for x in msg]) self.logger.debug('Msg to door %s: %s'%(self.name, list(p.toMessage()))) self.interface.writeMessage(self.address, msg) '''
class TestBlock(unittest.TestCase): """ Tests raw AES-128 block operations. """ def setUp(self): self.aes = AES(b'\00' * 16) def test_success(self): """ Should be able to encrypt and decrypt block messages. """ message = b'\01' * 16 ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) message = b'a secret message' ciphertext = self.aes.encrypt_block(message) self.assertEqual(self.aes.decrypt_block(ciphertext), message) def test_bad_key(self): """ Raw AES requires keys of an exact size. """ with self.assertRaises(AssertionError): AES(b'short key') with self.assertRaises(AssertionError): AES(b'long key' * 10) def test_expected_value_128(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ message = b'\x32\x43\xF6\xA8\x88\x5A\x30\x8D\x31\x31\x98\xA2\xE0\x37\x07\x34' key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C' ciphertext = AES(bytes(key)).encrypt_block(bytes(message)) self.assertEqual(ciphertext, b'\x39\x25\x84\x1D\x02\xDC\x09\xFB\xDC\x11\x85\x97\x19\x6A\x0B\x32') def test_expected_value_printing(self): #Tests taken from the NIST document, Appendix B: #http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf message = b'\x43\x6f\x72\x72\x65\x63\x74\x20\x44\x65\x63\x72\x79\x70\x74\x21' key = b'\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F' ciphertext = AES(bytes(key)).encrypt_block_with_printing(bytes(message)) self.assertEqual(ciphertext, b'\xF4\x35\x15\x03\xAA\x78\x1C\x52\x02\x67\xD6\x90\xC4\x2D\x1F\x43') def test_decrypt_value_printing(self): #Tests taken from the NIST document, Appendix B: #http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf key = b'\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F' ciphertext = b'\xF4\x35\x15\x03\xAA\x78\x1C\x52\x02\x67\xD6\x90\xC4\x2D\x1F\x43' message = AES(bytes(key)).decrypt_block_with_printing(bytes(ciphertext)) self.assertEqual(message, b'\x43\x6f\x72\x72\x65\x63\x74\x20\x44\x65\x63\x72\x79\x70\x74\x21') def test_expected_value2_printing(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ message = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff' key = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' ciphertext = AES(bytes(key)).encrypt_block(bytes(message)) self.assertEqual(ciphertext, b'\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a') def test_decrypt_value2_printing(self): """ Tests taken from the NIST document, Appendix B: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf """ key = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' ciphertext = b'\x69\xc4\xe0\xd8\x6a\x7b\x04\x30\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a' message = AES(bytes(key)).decrypt_block(bytes(ciphertext)) self.assertEqual(message, b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
class MasterController: def __init__(self, address, txseq, rxseq, key, interface, command_queue): self.address = address self.txseq = txseq self.rxseq = rxseq self.key = [int(x) for x in key.split()] self.aes = AES() self.interface = interface self.supply_voltage = 0 self.periodic = 10 self.logger = logging.getLogger("logger") self.pressed_buttons = 0 self.command_queue = command_queue self.all_locked = False def update(self, message): if len(message) != 16: self.logger.warning("The received message is not 16 bytes long") return message = self.aes.decrypt([ord(x) for x in message], self.key, AES.keySize["SIZE_128"]) message = "".join([chr(x) for x in message]) self.logger.debug("Decoded message: %s" % str(list(message))) p = Packet.fromMessage(message) if p.cmd == 83: self.supply_voltage = ord(p.data[3]) * 0.1 pressed_buttons = ord(p.data[0]) self.logger.debug("master: pressed_buttons = %d", pressed_buttons) if pressed_buttons & 0x01 and not self.pressed_buttons & 0x01: self.pressed_buttons |= 0x01 self.command_queue.put("lock") elif not pressed_buttons & 0x01: self.pressed_buttons &= ~0x01 if pressed_buttons & 0x02 and not self.pressed_buttons & 0x02: self.pressed_buttons |= 0x02 self.command_queue.put("toggle_announce") elif not pressed_buttons & 0x02: self.pressed_buttons &= ~0x02 if pressed_buttons & 0x04 and not self.pressed_buttons & 0x04: self.pressed_buttons |= 0x04 elif not pressed_buttons & 0x04: self.pressed_buttons &= ~0x04 self.logger.info("Master state: %s" % self.get_state()) def get_state(self): state = "" state = state + " Voltage=%.1f V" % self.supply_voltage state = state.strip() return state def tick(self): self.periodic -= 1 if self.periodic == 0: self.periodic = 2 self._send_command(ord("S"), "") if self.all_locked: self._send_command(ord("L"), "\x00\x04") else: self._send_command(ord("L"), "\x00\x00") def _send_command(self, command, data): p = Packet(seq=self.txseq, cmd=command, data=data) self.logger.debug("Msg to mastercontroller: %s" % list(p.toMessage())) msg = self.aes.encrypt([ord(x) for x in p.toMessage()], self.key, AES.keySize["SIZE_128"]) msg = "".join([chr(x) for x in msg]) self.interface.writeMessage(self.address, msg) def announce_open(self): self._send_command(ord("L"), "\x02\x04") def announce_closed(self): self._send_command(ord("L"), "\x02\x01") def set_global_state(self, all_locked): self.all_locked = all_locked
class TestCbc(unittest.TestCase): """ Tests AES-128 in CBC mode. """ def setUp(self): self.aes = AES(b'\00' * 16) self.iv = b'\01' * 16 self.message = b'my message' def test_single_block(self): """ Should be able to encrypt and decrypt single block messages. """ ciphertext = self.aes.encrypt_cbc(self.message, self.iv) self.assertEqual(self.aes.decrypt_cbc(ciphertext, self.iv), self.message) # Since len(message) < block size, padding won't create a new block. self.assertEqual(len(ciphertext), 16) def test_wrong_iv(self): """ CBC mode should verify the IVs are of correct length.""" with self.assertRaises(AssertionError): self.aes.encrypt_cbc(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.encrypt_cbc(self.message, b'long iv' * 16) with self.assertRaises(AssertionError): self.aes.decrypt_cbc(self.message, b'short iv') with self.assertRaises(AssertionError): self.aes.decrypt_cbc(self.message, b'long iv' * 16) def test_different_iv(self): """ Different IVs should generate different ciphertexts. """ iv2 = b'\02' * 16 ciphertext1 = self.aes.encrypt_cbc(self.message, self.iv) ciphertext2 = self.aes.encrypt_cbc(self.message, iv2) self.assertNotEqual(ciphertext1, ciphertext2) plaintext1 = self.aes.decrypt_cbc(ciphertext1, self.iv) plaintext2 = self.aes.decrypt_cbc(ciphertext2, iv2) self.assertEqual(plaintext1, plaintext2) self.assertEqual(plaintext1, self.message) def test_whole_block_padding(self): """ When len(message) == block size, padding will add a block. """ block_message = b'M' * 16 ciphertext = self.aes.encrypt_cbc(block_message, self.iv) self.assertEqual(len(ciphertext), 32) self.assertEqual(self.aes.decrypt_cbc(ciphertext, self.iv), block_message) def test_long_message(self): """ CBC should allow for messages longer than a single block. """ long_message = b'M' * 100 ciphertext = self.aes.encrypt_cbc(long_message, self.iv) self.assertEqual(self.aes.decrypt_cbc(ciphertext, self.iv), long_message)
def main(): k = os.urandom(16) cipher = AES(k) secret = b''.join(k[i:i+1]*4 for i in range(16)) flag = os.environ.get('FLAG', 'hkcert21{***********************REDACTED***********************}').encode() assert len(flag) == 64 flag = b''.join([cipher.encrypt(flag[i:i+16]) for i in range(0, 64, 16)]) print(f'Hey. This is the encrypted flag you gotta decrypt: {flag.hex()}.') options = ['ark', 'sb', 'sr', 'mc'] suboptions = ['data', 'secret'] for _ in range(128): [option, suboption, *more] = input('> ').split(' ') if option not in options: raise Exception('invalid option!') if suboption not in suboptions: raise Exception('invalid suboption!') if suboption == 'secret': options.remove(option) message = secret else: message = bytes.fromhex(more[0]) if len(message) != 16: raise Exception('invalid length!') message = message * 4 if option == 'ark': # Stage 1: "AddRoundKey" does nothing cipher = AES(k) cipher._add_round_key = no_op ciphertext = cipher.encrypt(message[0:16]) elif option == 'sb': # Stage 2: "SubBytes" does nothing cipher = AES(k) cipher._sub_bytes = no_op ciphertext = cipher.encrypt(message[16:32]) elif option == 'sr': # Stage 3: "ShiftRows" does nothing cipher = AES(k) cipher._shift_rows = no_op ciphertext = cipher.encrypt(message[32:48]) elif option == 'mc': # Stage 4: "MixColumns" does nothing cipher = AES(k) cipher._mix_columns = no_op ciphertext = cipher.encrypt(message[48:64]) print(ciphertext.hex())