def decrypt_PBEWithSHAAndTwofishCBC(encrypted_data, password, salt, iteration_count): """ Decrypts PBEWithSHAAndTwofishCBC, assuming PKCS#12-generated PBE parameters. (Not explicitly defined as an algorithm in RFC 7292, but defined here nevertheless because of the assumption of PKCS#12 parameters). """ iv = derive_key(hashlib.sha1, PURPOSE_IV_MATERIAL, password, salt, iteration_count, 16) key = derive_key(hashlib.sha1, PURPOSE_KEY_MATERIAL, password, salt, iteration_count, 256//8) encrypted_data = bytearray(encrypted_data) encrypted_data_len = len(encrypted_data) if encrypted_data_len % 16 != 0: raise BadDataLengthException("encrypted data length is not a multiple of 16 bytes") plaintext = bytearray() # slow and dirty CBC decrypt from twofish import Twofish cipher = Twofish(key) last_cipher_block = bytearray(iv) for block_offset in range(0, encrypted_data_len, 16): cipher_block = encrypted_data[block_offset:block_offset+16] plaintext_block = xor_bytearrays(bytearray(cipher.decrypt(bytes(cipher_block))), last_cipher_block) plaintext.extend(plaintext_block) last_cipher_block = cipher_block plaintext = strip_pkcs7_padding(plaintext, 16) return bytes(plaintext)
class TwofishCipher: """ This class handles all the cryptographic operations. """ def __init__(self, key): self.__bs = bs self.__cipher = Twofish(key) def __add_pad(self, chunk): """ Return a chunk with padding added (ISO 10126). """ padding = self.__bs - len(chunk) for idx, i in enumerate(range(padding), start=1): chunk += os.urandom(1) if idx != padding else bytes([padding]) return chunk def __del_pad(self, chunk): """ Return a chunk with padding removed (ISO 10126). """ return chunk[:-chunk[-1]] def encrypt(self, chunk): """ Return an encrypted chunk. """ if len(chunk) != bs: return self.__cipher.encrypt(self.__add_pad(chunk)) else: return self.__cipher.encrypt(chunk) def decrypt(self, chunk, unpad=False): """ Return a decrypted chunk. """ if unpad: return self.__del_pad(self.__cipher.decrypt(chunk)) else: return self.__cipher.decrypt(chunk)
def decrypt(self, message, key): cipher = Twofish(key) data = b'' for i in range(0, len(message), 16): st = message[i:i + 16] data += cipher.decrypt(st) return data
def decrypt_PBEWithSHAAndTwofishCBC(encrypted_data, password, salt, iteration_count): """ Decrypts PBEWithSHAAndTwofishCBC, assuming PKCS#12-generated PBE parameters. (Not explicitly defined as an algorithm in RFC 7292, but defined here nevertheless because of the assumption of PKCS#12 parameters). """ iv = derive_key(hashlib.sha1, PURPOSE_IV_MATERIAL, password, salt, iteration_count, 16) key = derive_key(hashlib.sha1, PURPOSE_KEY_MATERIAL, password, salt, iteration_count, 256 // 8) encrypted_data = bytearray(encrypted_data) encrypted_data_len = len(encrypted_data) if encrypted_data_len % 16 != 0: raise BadDataLengthException( "encrypted data length is not a multiple of 16 bytes") plaintext = bytearray() # slow and dirty CBC decrypt from twofish import Twofish cipher = Twofish(key) last_cipher_block = bytearray(iv) for block_offset in range(0, encrypted_data_len, 16): cipher_block = encrypted_data[block_offset:block_offset + 16] plaintext_block = xor_bytearrays( bytearray(cipher.decrypt(bytes(cipher_block))), last_cipher_block) plaintext.extend(plaintext_block) last_cipher_block = cipher_block plaintext = strip_pkcs7_padding(plaintext, 16) return bytes(plaintext)
class TwofishCBCDecryption(object): def __init__(self, key, iv): self.log = logging.getLogger("twofish.cbc.%s" % type(self).__name__) self.log.debug('initing') assert len(iv) == 16 from twofish import Twofish self.key = key self.iv = iv self.tw = Twofish(self.key) def decrypt(self, blocks): assert len(blocks) % 16 == 0, "Expected cipher text length to be a multiple of 16. Got %r. " % len(blocks) ret = '' while len(blocks) > 0: block = blocks[:16] blocks = blocks[16:] ret += self.decryptBlock(block) return ret def decryptBlock(self, block): assert len(block) == 16 intr = self.tw.decrypt(block) oldIV = self.iv self.iv = block return xor(oldIV, intr)
class TwofishCBCDecryption(object): def __init__(self, key, iv): self.log = logging.getLogger("twofish.cbc.%s" % type(self).__name__) self.log.debug('initing') assert len(iv) == 16 from twofish import Twofish self.key = key self.iv = iv self.tw = Twofish(self.key) def decrypt(self, blocks): assert len( blocks ) % 16 == 0, "Expected cipher text length to be a multiple of 16. Got %r. " % len( blocks) ret = b'' while len(blocks) > 0: block = blocks[:16] blocks = blocks[16:] ret += self.decryptBlock(block) return ret def decryptBlock(self, block): assert len(block) == 16 intr = self.tw.decrypt(block) oldIV = self.iv self.iv = block return xor(oldIV, intr)
def decrypt(self, msg): d_start_ts = time.time() end_timestamp = round(time.time(), 5) print('End timestamp at decryption:', end_timestamp, 's') random.seed(seed_no2) self.sk2 = ''.join(random.choice(possible_chars) for i in range(16)) algo2 = Rijndael(self.sk2, self.block_size) decrypt_msg2 = algo2.decrypt(msg) random.seed(seed_no1) self.sk1 = ''.join(random.choice(possible_chars) for i in range(16)) algo1 = Twofish(self.sk1.encode('utf-8')) decrypt_msg1 = algo1.decrypt(decrypt_msg2[:16]) print('Size of decrypt1:', len(decrypt_msg1), 'bytes') print('\nSize of decrypt2:', len(decrypt_msg2), 'bytes') start_timestamp = float((decrypt_msg2[16:]).decode('utf-8')) print('Start timestamp extracted at decryption:', start_timestamp) diff_timestamp = end_timestamp - start_timestamp d_end_ts = time.time() print('Time taken for decrypt():', (d_end_ts - d_start_ts) * 10**3, 'ms') return decrypt_msg1.decode('utf-8'), diff_timestamp
def fdecrypt(filen,password): f=open(filen,'rb') smstr=f.read() f.close() psswd=Twofish(password) decredstr=b'' for x in range(int(len(smstr)/16)): decredstr+=psswd.decrypt(smstr[x*16:(x+1)*16]) return codecs.decode(decredstr,'utf-8').strip('%')
def TWOde(key, in_filename, out_filename=None, chunksize=16): key = key.encode('utf-8') key = Twofish(key) if not out_filename: out_filename = in_filename[:-4] with open(in_filename, 'rb') as infile: with open(out_filename, 'wb') as outfile: while True: chunk = infile.read(chunksize) if len(chunk) == 0: break outfile.write(key.decrypt(chunk))
def whale(key , cipher): #Define key: #key = str(raw_input("Key: ")) #cipher = str(raw_input("Cipher: ")) #Get key: try: tuna = Twofish(key) print(key + ": " + tuna.decrypt(cipher).decode()) except: #print("Key :" + key + " failed") pass; # save your eye some trouble
def whale(key, cipher): #Define key: #key = str(raw_input("Key: ")) #cipher = str(raw_input("Cipher: ")) #Get key: try: tuna = Twofish(key) print(key + ": " + tuna.decrypt(cipher).decode()) except: #print("Key :" + key + " failed") pass
def twofish_decrypt(password, path): infile = open(path, "rb") data = infile.read() infile.close() cipher = Twofish(bytes(password, 'utf-8')) decrypted = b'' # decrypted string for x in range(int(len(data) / 16)): decrypted += cipher.decrypt(data[x * 16:(x + 1) * 16]) outfile = open(path + '.decrypted', "wb") outfile.write(decrypted) outfile.close()
class TwofishExample: """ A class to represent an TwofishExample. METHODS ------- encrypt(msg): Encrypts the msg and returns it. decrypt(encrypted): Decrypts the encrypted msg and returns it. """ def __init__(self): """ Constructs the TwofishExample object. """ self.key = b'FSMF73R873YM1872Y' self.tf = Twofish(self.key) def encrypt(self, msg): """ Encrypts the msg. PARAMETERS ---------- :param msg : Message to be encrypted :type msg : str RETURNS ------- :returns encrypted message :rtype bytearray """ return self.tf.encrypt(msg) def decrypt(self, encrypted): """ Decrypts the encrypted message. PARAMETERS ---------- :param encrypted : Encrypted message to be decrypted :type encrypted : bytearray RETURNS ------- :returns decrypted message :rtype str """ return self.tf.decrypt(encrypted).decode()
def test_ecb(self): from twofish import Twofish tw = Twofish(self.key) for testData in self.testData: self.assertTrue( len(testData) % 16 == 0, "Test data length needs to be evenly divisible by 16. Got %r" % len(testData) ) # Can take multiple blocks cipherText = tw.encrypt(testData) self.assertNotEqual(cipherText, testData, "Plain and cipher text should not be the same") decrypted = tw.decrypt(cipherText) self.assertEqual( decrypted, testData, "The encrypted and then decrypted text should match the original text" )
def TWOde(key, in_filename, out_filename=None, chunksize=16) : key = key.encode('utf-8') key = Twofish(key) if not out_filename : out_filename = in_filename[:-4] with open(in_filename, 'rb') as infile : with open(out_filename, 'wb') as outfile : while True : chunk = infile.read(chunksize) if len(chunk) == 0 : break outfile.write(key.decrypt(chunk)) # key = 'pass' # TWOen(key, 'Capture.PNG') # TWOde(key, 'Capture.PNG.enc', 'random.png')
class TwoFish: def __init__(self, key=None): if key is None: self.key = secrets.token_bytes(16) else: self.key = key self.tf = Twofish(self.key) def encode(self, strs): strs = _16fillblock(strs) ret = b'' for i in range(len(strs)): ret += self.tf.encrypt(strs[i]) return ret def decode(self, strs): strs = _16fillblock(strs) ret = b'' for i in range(len(strs)): ret += self.tf.decrypt(strs[i]) return ret[:len(ret) - 16]
def twofishDecrypt(): # twf_var.get() #ini get password start_time = time() global decrypt_twofish_join text = hc_join key = twofish_password.get() T = Twofish(key) n = 32 ii = 0 x = [] res = "" for c in text: if (ii % n == 0): if (ii == 0): res += c else: x.append(res) res = "" res += c else: res += c ii = ii + 1 x.append(res) print(x) twofish_array = [] for twofish_plain_res in x: print(twofish_plain_res) twofish_decrypt = T.decrypt(twofish_plain_res.decode("hex")) print(twofish_decrypt) twofish_array.append(twofish_decrypt) decrypt_twofish_join = "".join(twofish_array) print(decrypt_twofish_join) messagebox.showinfo("Success", "Decrypt Twofish Success") end_time = time() time_taken = end_time - start_time hours, rest = divmod(time_taken, 3600) minutes, seconds = divmod(rest, 60) print("Time taken:", format_timespan(end_time - start_time))
def decrypt(self, msg): d_start_ts = time.time() end_timestamp = round(time.time(), 5) print('End timestamp at decryption:', end_timestamp, 's') algo2 = Rijndael(self.sk, self.block_size) decrypt_msg2 = algo2.decrypt(msg) algo1 = Twofish(self.sk.encode('utf-8')) decrypt_msg1 = algo1.decrypt(decrypt_msg2[:16]) print('\nSize of decrypt2:', len(decrypt_msg2), 'bytes') print('Size of decrypt1:', len(decrypt_msg1), 'bytes') start_timestamp = float((decrypt_msg2[16:]).decode('utf-8')) print('Start timestamp extracted at decryption:', start_timestamp, 's') diff_timestamp = end_timestamp - start_timestamp d_end_ts = time.time() print('Time taken for decrypt():', (d_end_ts - d_start_ts) * 10**3, 'ms') return decrypt_msg1.decode('utf-8'), diff_timestamp
def fdecrypt(filen, password, tweak=0, mode='twofish'): # reading file in byte mode f=open(filen,'rb') smstr=f.read() f.close() if mode=='twofish': psswd=Twofish(password) decredstr=b'' # decrypting blocks for x in range(int(len(smstr)/16)): decredstr+=psswd.decrypt(smstr[x*16:(x+1)*16]) elif mode=='threefish': psswd=threefish(password,tweak) decredstr=b'' # decrypting blocks for x in range(int(len(smstr)/128)): decredstr+=psswd.decrypt_block(smstr[x*128:(x+1)*128]) return decode(decredstr,'utf-8').strip('%')
def decrypttwofish(importx, filepath, export, expfilepath, inputformat, passwd, raw, keyimport): if keyimport == 'base64': key = base64.b64decode(passwd) elif keyimport == 'raw': key = passwd elif keyimport == 'base32': key = base64.b32decode(passwd) elif keyimport == 'base16': key = base64.b16decode(passwd) elif keyimport == 'base58': key = base58.b58decode(passwd) elif keyimport == 'base85': print('\033[1;31m[-]\033[0m Option not available yet') elif keyimport == 'hex': key = passwd.decode('hex') elif keyimport == 'dec': print('\033[1;31m[-]\033[0m Option not available yet') elif keyimport == 'octal': print('\033[1;31m[-]\033[0m Option not available yet') elif keyimport == 'binary': key = text_from_bits(passwd) else: print('\033[1;31m[-]\033[0m Unknown error.') return False if importx == 'file': f = open(impfilepath, 'r') raw = f.read() f.close() elif importx == 'print': raw = raw else: print('\033[1;31m[-]\033[0m Unknown error.') return False inp = raw if inputformat == 'base64': iput = base64.b64decode(inp) elif inputformat == 'base32': iput = base64.b32decode(inp) elif inputformat == 'base16': iput = base64.b16decode(inp) elif inputformat == 'base58': iput = base58.b58decode(inp) elif inputformat == 'base85': print('\033[1;31m[-]\033[0m Option not available yet') elif inputformat == 'hex': iput = inp.decode('hex') elif inputformat == 'dec': print('\033[1;31m[-]\033[0m Option not available yet') elif inputformat == 'octal': print('\033[1;31m[-]\033[0m Option not available yet') elif inputformat == 'binary': iput = text_from_bits(inp) else: print('\033[1;31m[-]\033[0m Unknown error.') return False e = Twofish(key) out = e.decrypt(iput) out = unpad(out) if outputformat == 'base64': output = base64.b64encode(out) elif outputformat == 'raw': output = out elif outputformat == 'base32': output = base64.b32encode(out) elif outputformat == 'base16': output = base64.b16encode(out) elif outputformat == 'base58': output = base58.b58encode(out) elif outputformat == 'base85': print('\033[1;31m[-]\033[0m Option not available yet') elif outputformat == 'hex': output = out.encode('hex') elif outputformat == 'dec': print('\033[1;31m[-]\033[0m Option not available yet') elif outputformat == 'octal': print('\033[1;31m[-]\033[0m Option not available yet') elif outputformat == 'binary': output = text_to_bits(out) else: print('\033[1;31m[-]\033[0m Unknown error.') return False if export == 'file': f = open(outfilepath, 'w') f.write(output) f.close() return True elif export == 'print': return output else: print('\033[1;31m[-]\033[0m Unknown error.') return False
class TwofishCipher: """ This class handles all the cryptographic operations. """ def __init__(self, key, file_size): self.__cipher = Twofish(key) self.__prev = bytes() self.__file_size = file_size self.__block_count = 0 def encrypt(self, buf): """ Return an encrypted block. """ self.__block_count += block_size # First block, iv generated and prepened to the 1st encrypted block. if not self.__prev: iv = os.urandom(block_size) self.__prev = self.__cipher.encrypt(self.__xor(buf, iv)) return iv + self.__prev # Default blocks. elif (len(buf) == block_size) and (self.__block_count != self.__file_size): self.__prev = self.__cipher.encrypt(self.__xor(buf, self.__prev)) return self.__prev # Last block, add some extra padding. elif len(buf) != block_size: self.__prev = self.__cipher.encrypt(self.__xor(self.__pad(buf), self.__prev)) return self.__prev # Last block equal to 16 bytes, add an extra 16 bytes padding block. elif self.__block_count == self.__file_size: random_block = os.urandom(block_size - 1) + bytes([16]) self.__prev = self.__xor(self.__cipher.decrypt(buf), self.__prev) return self.__prev + random_block def decrypt(self, buf): """ Return a decrypted block. """ self.__block_count += block_size # First block of the file: this is the initialization vector. # Return an empty byte string to maintain compatibility with write(). if not self.__prev: self.__prev = buf return b'' # Decrypt a block. elif self.__block_count != self.__file_size: xored = self.__xor(self.__cipher.decrypt(buf), self.__prev) self.__prev = buf return xored # Decrypt the last block and remove its padding. else: return self.__unpad(self.__xor(self.__cipher.decrypt(buf), self.__prev)) def __pad(self, buf): """ Return a block with padding added (ISO 10126). """ padding = block_size - len(buf) for idx, i in enumerate(range(padding), start=1): buf += os.urandom(1) if idx != padding else bytes([padding]) return buf def __unpad(self, buf): """ Return a block with padding removed (ISO 10126). """ return buf[:-buf[-1]] if buf[:-buf[-1]] else b'' def __xor(self, x, y): """ Return the XOR from two 16bytes blocks. """ x = int.from_bytes(x, byteorder='big') y = int.from_bytes(y, byteorder='big') return (x ^ y).to_bytes(16, byteorder='big')
def unfish(self, cyperbits): encryptor = Twofish(self.keyGen()) padded = encryptor.decrypt(cyperbits).decode() return "\n".join(padded.split("\n")[1:])
from twofish import Twofish start='keykey' end='11111' flag = b'\x61\xd1\xd3\x3c\x8f\xcf\x28\xd6\xe3\xff\x8e\xd3\xab\x1d\x00\x6d' for i in range(10000,100000): key = str.encode(start + str(i) + end) T = Twofish(key) out = T.decrypt(flag) try: outString = out.decode() if 'bank' in outString: print(outString + ' ' + key) except: pass
def CBC_decrypt(IV_str, key_str, data): ''' Decrypt a Twofish-CBC encrypted file. IV - Initalization Vector (aka nonce) key - The key used to decrypt the file (type str) data - the file to be decrypted (type str) ''' print('[*] Decrypting database...') IV = IV_str.encode('utf-8') key = key_str.encode('utf-8') assert type(data) == bytes if len(IV) > 16: #while len(IV) != 16: # IV = IV[1:] IV = IV[len(IV)-16:] elif len(IV) < 16: # TODO: How to do this better? copy = IV[:] while len(IV) != 16: for i in copy: IV += i if len(IV) == 16: break assert len(IV) == 16 # keysize is limited to 32 bytes as per libtwofish, the libary # that pytwofish is based off of if len(key) > 32: while len(key) != 32: key = key[1:] #print(len(key)) cipher = Twofish(key) padlen = 0 if b'PADDING' in data: data = data.replace(b'PADDING = ', b'') padlen = int(data[:data.find(b'\n')]) data = data[data.find(b'\n')+1:] # number or rounds is equal the the number of 16-byte blocks rounds = len(data) // 16 #print('padding length: {}'.format(padlen)) #print('data length: {}'.format(len(data))) #print('[+] Initiating decryption process..') buf = b'' old_block = data[:16] #print('old block: {}'.format(len(old_block))) data = data[16:] #print('old_block len: {}'.format(len(old_block))) hexxed = byte_hexxor(cipher.decrypt(old_block), IV) new_block = byte_hexxor(cipher.decrypt(old_block), IV) buf += new_block assert type(new_block) == bytes and type(old_block) == bytes for rnd in range(rounds-1): new_block = data[:16] data = data[16:] #print('old: {}\nnew: {}'.format(base64.b64encode(old_block), base64.b64encode(new_block))) #print('='*5) buf += byte_hexxor(cipher.decrypt(new_block), old_block) old_block = new_block[:] # strip obfuscation end_block_index = buf.find(ASCII_0END_BLOCK) # USE find() here, rfind() breaks sutff if end_block_index != -1: buf = buf[:end_block_index] # strip padding if padlen != 0: buf = buf[:len(buf)-padlen] print('[*] Database decrypted.') return buf
def decrypt(password: bytes) -> str: twofish = Twofish(session['password_hash']) decrypted = b'' for chunk in yield_chunks(password, 16): decrypted += twofish.decrypt(chunk) return decrypted.rstrip(b'\0').decode('utf-8')
from twofish import Twofish import sys T = Twofish(sys.argv[1]) crypt = raw_input('encrypted data: ') print 'decrypted:' i = 0 while (i < len(crypt)): sys.stdout.write(T.decrypt(crypt[i:i+16])) i+=16