switch to cryptography
Fernet could not be used as it is not a streaming cipher. CFB mode does not require padding, so removed padding code. Depends-On: https://review.openstack.org/c/575199/ Change-Id: I14f58d9d473c20ce7863baa0b2adadbfda268b7a
This commit is contained in:
parent
10814141a4
commit
7c16877195
|
@ -124,7 +124,7 @@ Linux Requirements
|
|||
- libffi-dev
|
||||
- libssl-dev
|
||||
- python-dev
|
||||
- pycrypto
|
||||
- cryptography
|
||||
- At least 128 MB of memory reserved for Freezer
|
||||
|
||||
Windows Requirements
|
||||
|
@ -587,7 +587,7 @@ Freezer architectural components are the following:
|
|||
- freezer client running on the node where the backups and restores are to be executed
|
||||
|
||||
Freezer uses GNU Tar or Rsync algorithm under the hood to execute incremental backup and
|
||||
restore. When a key is provided, it uses OpenSSL or pycrypto module (OpenSSL compatible)
|
||||
restore. When a key is provided, it uses OpenSSL or cryptography module (OpenSSL compatible)
|
||||
to encrypt data. (AES-256-CFB)
|
||||
|
||||
=============
|
||||
|
|
|
@ -145,7 +145,6 @@ class Rsyncv2Engine(engine.BackupEngine):
|
|||
flushed_data += compressor.flush()
|
||||
if flushed_data and cipher:
|
||||
flushed_data = cipher.encrypt(flushed_data)
|
||||
flushed_data += cipher.flush()
|
||||
|
||||
return flushed_data
|
||||
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
|
||||
import hashlib
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto import Random
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.ciphers import algorithms
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers import modes
|
||||
from os import urandom
|
||||
|
||||
SALT_HEADER = 'Salted__'
|
||||
AES256_KEY_LENGTH = 32
|
||||
BS = AES.block_size
|
||||
BS = 16 # static 16 bytes, 128 bits for AES
|
||||
|
||||
|
||||
class AESCipher(object):
|
||||
|
@ -56,40 +59,21 @@ class AESEncrypt(AESCipher):
|
|||
|
||||
def __init__(self, pass_file):
|
||||
super(AESEncrypt, self).__init__(pass_file)
|
||||
self._salt = Random.new().read(BS - len(SALT_HEADER))
|
||||
self._salt = urandom(BS - len(SALT_HEADER))
|
||||
key, iv = self._derive_key_and_iv(self._password,
|
||||
self._salt,
|
||||
AES256_KEY_LENGTH,
|
||||
BS)
|
||||
self.cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=BS * 8)
|
||||
self.remain = None
|
||||
self.cipher = Cipher(algorithms.AES(key),
|
||||
modes.CFB(iv),
|
||||
backend=default_backend())
|
||||
|
||||
def generate_header(self):
|
||||
return SALT_HEADER + self._salt
|
||||
|
||||
def encrypt(self, data):
|
||||
remain = self.remain
|
||||
if remain:
|
||||
data = remain + data
|
||||
remain = None
|
||||
|
||||
extra_bytes = len(data) % BS
|
||||
if extra_bytes:
|
||||
remain = data[-extra_bytes:]
|
||||
data = data[:-extra_bytes]
|
||||
|
||||
self.remain = remain
|
||||
return self.cipher.encrypt(data)
|
||||
|
||||
def flush(self):
|
||||
def pad(s):
|
||||
return s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
|
||||
|
||||
buff = self.remain
|
||||
if buff:
|
||||
return self.cipher.encrypt(pad(buff))
|
||||
|
||||
return b''
|
||||
encryptor = self.cipher.encryptor()
|
||||
return encryptor.update(data) + encryptor.finalize()
|
||||
|
||||
|
||||
class AESDecrypt(AESCipher):
|
||||
|
@ -105,17 +89,14 @@ class AESDecrypt(AESCipher):
|
|||
self._salt,
|
||||
AES256_KEY_LENGTH,
|
||||
BS)
|
||||
self.cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=BS * 8)
|
||||
self.cipher = Cipher(algorithms.AES(key),
|
||||
modes.CFB(iv),
|
||||
backend=default_backend())
|
||||
|
||||
@staticmethod
|
||||
def _prepare_salt(salt):
|
||||
return salt[len(SALT_HEADER):]
|
||||
|
||||
def decrypt(self, data):
|
||||
# def unpad(s):
|
||||
# return s[0:-ord(s[-1])]
|
||||
#
|
||||
# if last_block:
|
||||
# return unpad(self.cipher.decrypt(data))
|
||||
# else:
|
||||
return self.cipher.decrypt(data)
|
||||
decryptor = self.cipher.decryptor()
|
||||
return decryptor.update(data) + decryptor.finalize()
|
||||
|
|
|
@ -12,7 +12,7 @@ chardet==3.0.4
|
|||
cliff==2.11.0
|
||||
cmd2==0.8.1
|
||||
coverage==4.0
|
||||
cryptography==2.1.4
|
||||
cryptography==2.1
|
||||
ddt==1.0.1
|
||||
debtcollector==1.19.0
|
||||
decorator==4.2.1
|
||||
|
@ -74,7 +74,6 @@ prettytable==0.7.2
|
|||
psutil==3.2.2
|
||||
pyasn1==0.4.2
|
||||
pycparser==2.18
|
||||
pycrypto==2.6
|
||||
pyflakes==1.0.0
|
||||
Pygments==2.2.0
|
||||
pyinotify==0.9.6
|
||||
|
|
|
@ -18,7 +18,7 @@ keystoneauth1>=3.4.0 # Apache-2.0
|
|||
os-brick>=2.2.0 # Apache-2.0
|
||||
oslo.service!=1.28.1,>=1.24.0 # Apache-2.0
|
||||
|
||||
pycrypto>=2.6 # Public Domain
|
||||
cryptography>=2.1 # Apache-2.0
|
||||
PyMySQL>=0.7.6 # MIT License
|
||||
pymongo!=3.1,>=3.0.2 # Apache-2.0
|
||||
paramiko>=2.0.0 # LGPLv2.1+
|
||||
|
|
Loading…
Reference in New Issue