Passphrase.kdf -> FlexiKey.pbkdf2

This commit is contained in:
Andrey Bienkowski 2022-04-10 05:33:10 +03:00
parent eba6d5cd1c
commit 0850a7c295
4 changed files with 14 additions and 15 deletions

View file

@ -46,7 +46,7 @@ try:
from .constants import * # NOQA
from .compress import CompressionSpec
from .crypto.key import key_creator, key_argument_names, tam_required_file, tam_required
from .crypto.key import RepoKey, KeyfileKey, Blake2RepoKey, Blake2KeyfileKey
from .crypto.key import RepoKey, KeyfileKey, Blake2RepoKey, Blake2KeyfileKey, FlexiKey
from .crypto.keymanager import KeyManager
from .helpers import EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, EXIT_SIGNAL_BASE
from .helpers import Error, NoManifestError, set_ec
@ -626,7 +626,7 @@ class Archiver:
print("KDFs (slow is GOOD, use argon2!) ===============================")
count = 5
for spec, func in [
("pbkdf2", lambda: Passphrase('mypassphrase').kdf(b'salt'*8, PBKDF2_ITERATIONS, 32)),
("pbkdf2", lambda: FlexiKey.pbkdf2(Passphrase('mypassphrase'), b'salt'*8, PBKDF2_ITERATIONS, 32)),
("argon2", lambda: Passphrase('mypassphrase').argon2(64, b'S' * ARGON2_SALT_BYTES, **ARGON2_ARGS)),
]:
print(f"{spec:<24} {count:<10} {timeit(func, number=count):.3f}s")

View file

@ -3,7 +3,7 @@ import hmac
import os
import textwrap
from binascii import a2b_base64, b2a_base64, hexlify
from hashlib import sha256
from hashlib import sha256, pbkdf2_hmac
from ..logger import create_logger
@ -447,8 +447,14 @@ class FlexiKey:
else:
raise UnsupportedKeyFormatError()
@staticmethod
def pbkdf2(passphrase, salt, iterations, output_len_in_bytes):
if os.environ.get("BORG_TESTONLY_WEAKEN_KDF") == "1":
iterations = 1
return pbkdf2_hmac('sha256', passphrase.encode('utf-8'), salt, iterations, output_len_in_bytes)
def decrypt_key_file_pbkdf2(self, encrypted_key, passphrase):
key = passphrase.kdf(encrypted_key.salt, encrypted_key.iterations, 32)
key = self.pbkdf2(passphrase, encrypted_key.salt, encrypted_key.iterations, 32)
data = AES(key, b'\0'*16).decrypt(encrypted_key.data)
if hmac.compare_digest(hmac_sha256(key, data), encrypted_key.hash):
return data
@ -485,7 +491,7 @@ class FlexiKey:
def encrypt_key_file_pbkdf2(self, data, passphrase):
salt = os.urandom(32)
iterations = PBKDF2_ITERATIONS
key = passphrase.kdf(salt, iterations, 32)
key = self.pbkdf2(passphrase, salt, iterations, 32)
hash = hmac_sha256(key, data)
cdata = AES(key, b'\0'*16).encrypt(data)
enc_key = EncryptedKey(

View file

@ -3,7 +3,6 @@ import os
import shlex
import subprocess
import sys
from hashlib import pbkdf2_hmac
from typing import Literal
from . import bin_to_hex
@ -140,11 +139,6 @@ class Passphrase(str):
def __repr__(self):
return '<Passphrase "***hidden***">'
def kdf(self, salt, iterations, length):
if os.environ.get("BORG_TESTONLY_WEAKEN_KDF") == "1":
iterations = 1
return pbkdf2_hmac('sha256', self.encode('utf-8'), salt, iterations, length)
def argon2(
self,
output_len_in_bytes: int,

View file

@ -10,7 +10,7 @@ from ..crypto.low_level import AES256_CTR_HMAC_SHA256, AES256_OCB, CHACHA20_POLY
from ..crypto.low_level import bytes_to_long, bytes_to_int, long_to_bytes
from ..crypto.low_level import hkdf_hmac_sha512
from ..crypto.low_level import AES, hmac_sha256
from ..crypto.key import KeyfileKey, UnsupportedKeyFormatError, RepoKey
from ..crypto.key import KeyfileKey, UnsupportedKeyFormatError, RepoKey, FlexiKey
from ..helpers.passphrase import Passphrase
from ..helpers import msgpack
from ..constants import KEY_ALGORITHMS
@ -294,9 +294,8 @@ def test_decrypt_key_file_argon2_aes256_ctr_hmac_sha256(monkeypatch):
def test_decrypt_key_file_pbkdf2_sha256_aes256_ctr_hmac_sha256(monkeypatch):
plain = b'hello'
salt = b'salt'*4
monkeypatch.setenv('BORG_PASSPHRASE', "hello, pass phrase")
passphrase = Passphrase.new()
key = passphrase.kdf(salt, iterations=1, length=32)
passphrase = Passphrase("hello, pass phrase")
key = FlexiKey.pbkdf2(passphrase, salt, 1, 32)
hash = hmac_sha256(key, plain)
data = AES(key, b'\0'*16).encrypt(plain)
encrypted = msgpack.packb({