def sha1_hmac(data, key): if len(key) > 20: key = sha1(key) key = null_padding(key, 20) o_key_pad = xor_str(key, '\x5c' * 20) i_key_pad = xor_str(key, '\x36' * 20) return sha1(o_key_pad + sha1(i_key_pad + data))
def sha256_hmac(data, key): if len(key) > 32: key = sha256(key) key = null_padding(key, 64) o_key_pad = xor_str(key, '\x5c' * 64) i_key_pad = xor_str(key, '\x36' * 64) return sha256(o_key_pad + sha256(i_key_pad + data))
def decrypt_raw(data, key, iv="\0" * 32): "Decrypt data" key = fixed_length_key(key, 32) plaintext = "" for i in range(0, len(data), 32): block = data[i:i + 32] iv = hash(xor_str(iv, key)) plaintext += xor_str(iv, block) plaintext = remove_padding(plaintext) return plaintext
def encrypt_raw(data, key, iv="\0" * 32): "Encrypt data" # Weak: IV reuse with default parameters # Weak: Vulnerable to ciphertex manipulation key = fixed_length_key(key, 32) ciphertext = "" data = add_padding(data, 32) for i in range(0, len(data), 32): block = data[i:i + 32] iv = hash(xor_str(iv, key)) ciphertext += xor_str(iv, block) return ciphertext
def encrypt_256_ctr(data, key): key = fixed_length_key(key, 32) counter = os.urandom(16) r = counter for i in range(0, len(data), 16): encrypted_counter = aes256enc(counter, key) r += xor_str(encrypted_counter, data[i:i + 16]) counter = advance_counter(counter) return r
def cbc_mac(data, key): key = fixed_length_key(key, 16) data = pkcs7.add_padding(data, 16) iv = "\0" * 16 r = "" for i in range(0, len(data), 16): cipherblock = aes128enc(xor_str(data[i:i + 16], iv), key) r += cipherblock iv = cipherblock return iv
def decrypt_256_ctr(data, key): key = fixed_length_key(key, 32) counter = data[:16] data = data[16:] r = "" for i in range(0, len(data), 16): encrypted_counter = aes256enc(counter, key) r += xor_str(encrypted_counter, data[i:i + 16]) counter = advance_counter(counter) return r
def chacha20_decrypt(data, key, counter=1): "Decrypt a string using a key" key = fixed_length_key(key, 32) key_words = [littleendian2int(key[i:i + 4]) for i in range(0, 32, 4)] nonce_words = [littleendian2int(data[i:i + 4]) for i in range(0, 12, 4)] ciphertext = data[12:] plaintext = "" for i in range(0, len(ciphertext), 64): j = _i32(i // 64) key_stream = chacha20_block(key_words, [_i32(counter + j)], nonce_words) block = ciphertext[i:i + 64] plaintext += xor_str(block, key_stream) return plaintext
def chacha20_encrypt(plaintext, key, counter=1): "Encrypt a string using a key" key = fixed_length_key(key, 32) key_words = [littleendian2int(key[i:i + 4]) for i in range(0, 32, 4)] nonce_words = [littleendian2int(urandom(4)) for _ in range(3)] ciphertext = "".join([int2littleendian(n, 4) for n in nonce_words]) for i in range(0, len(plaintext), 64): j = _i32(i // 64) key_stream = chacha20_block(key_words, [_i32(counter + j)], nonce_words) block = plaintext[i:i + 64] ciphertext += xor_str(block, key_stream) return ciphertext
def decrypt_256_cbc(data, key, padding=True, gen_iv=True): key = fixed_length_key(key, 32) r = "" if gen_iv: iv = data[:16] data = data[16:] else: iv = "\0" * 16 for i in range(0, len(data), 16): cipherblock = data[i:i + 16] r += xor_str(aes256dec(cipherblock, key), iv) iv = cipherblock if padding: return pkcs7.remove_padding(r) else: return r
def encrypt_256_cbc(data, key, padding=True, gen_iv=True): key = fixed_length_key(key, 32) if padding: data = pkcs7.add_padding(data, 16) r = "" if gen_iv: iv = os.urandom(16) r = iv else: iv = "\0" * 16 r = "" for i in range(0, len(data), 16): cipherblock = aes256enc(xor_str(data[i:i + 16], iv), key) r += cipherblock iv = cipherblock return r
def update_buffer(self): self.buf += xor_str(hash(self.seed), self.key) self.seed = self.buf
def mac(H, data, key): "Message authentication code" # Weak: trivial modification of first data block for i in range(0, len(data), 32): H = hash(xor_str(data[i:i + 32], H)) return H