def password_encrypt(data, password): """ Encrypt the given text with the password. A key is derived from the password and used to encrypt the text in AES MODE_CBC. The IV is returned together with the cipher text. <IV:Cipher> :param data: The text to encrypt :type data: str or bytes :param password: The password to derive a key from :type password: str or bytes :return: IV and cipher text :rtype: str """ bkey = create_key_from_password(password) # convert input to ascii, so we can securely append bin data for padding input_data = binascii.hexlify(to_bytes(data)) input_data += b"\x01\x02" padding = (16 - len(input_data) % 16) % 16 input_data += padding * b"\0" iv = geturandom(16) cipher = aes_cbc_encrypt(bkey, iv, input_data) iv_hex = hexlify_and_unicode(iv) cipher_hex = hexlify_and_unicode(cipher) return "{0!s}:{1!s}".format(iv_hex, cipher_hex)
def encrypt(self, data, iv, key_id=SecurityModule.TOKEN_KEY): """ security module methods: encrypt :param data: the data that is to be encrypted :type data: bytes :param iv: initialisation vector :type iv: bytes :param key_id: slot of the key array. The key file contains 96 bytes, which are made up of 3 32byte keys. :type key_id: int :return: encrypted data :rtype: bytes """ if self.is_ready is False: raise HSMException('setup of security module incomplete') key = self._get_secret(key_id) # convert input to ascii, so we can securely append bin data for padding input_data = binascii.b2a_hex(data) input_data += b"\x01\x02" padding = (16 - len(input_data) % 16) % 16 input_data += padding * b"\0" res = aes_cbc_encrypt(key, iv, input_data) if self.crypted is False: zerome(key) del key return res
def reencrypt(enc_data, iv, old_key, new_key): # decrypt LinOTP iv = binascii.unhexlify(iv) input_data = binascii.unhexlify(enc_data) output = aes_cbc_decrypt(old_key, iv, input_data) if not output: raise Exception('invalid encoded secret!') # unpad output = output.rstrip(b'\0') data = binascii.unhexlify(output) # encrypt anew iv = os.urandom(16) input_data = binascii.b2a_hex(data) input_data += b"\x01\x02" padding = (16 - len(input_data) % 16) % 16 input_data += padding * b"\0" res = aes_cbc_encrypt(new_key, iv, input_data) return hexlify_and_unicode(res), hexlify_and_unicode(iv)
def reencrypt(enc_data, iv, old_key, new_key): # decrypt LinOTP iv = binascii.unhexlify(iv) input = binascii.unhexlify(enc_data) output = aes_cbc_decrypt(old_key, iv, input) eof = len(output) - 1 if eof == -1: raise Exception('invalid encoded secret!') # unpad while output[eof] == '\0': eof -= 1 output = output[0:eof - 1] data = binascii.unhexlify(output) # encrypt anew iv = os.urandom(16) input_data = binascii.b2a_hex(data) input_data += b"\x01\x02" padding = (16 - len(input_data) % 16) % 16 input_data += padding * b"\0" res = aes_cbc_encrypt(new_key, iv, input_data) return hexlify_and_unicode(res), hexlify_and_unicode(iv)