示例#1
0
def get_basekeys(filePass, salt):
    '''
    Generate user and file keys from the respective passwords
    and a hopefully random salt.

    user password if not provided, fallsback to a default.
    If provided, it should be readable only by the user and
    not by group or all.
    '''
    # process file password
    kdf = pbkdf2.PBKDF2HMAC(
        algorithm=SHA256(),
        length=32,
        salt=salt,
        iterations=186926,  # Gandhi+
        backend=default_backend())
    fileKey = base64.urlsafe_b64encode(kdf.derive(bytes(filePass, "utf-8")))
    # get and process user password
    try:
        f = open("~/.config/spreadsheetkvc/userpass")
        l = f.readline()
        userPass = l.strip()
        f.close()
    except:
        userPass = "******"
    kdf = pbkdf2.PBKDF2HMAC(
        algorithm=SHA256(),
        length=32,
        salt=salt,
        iterations=186922,  # Gandhi+
        backend=default_backend())
    userKey = base64.urlsafe_b64encode(kdf.derive(bytes(userPass, "utf-8")))
    return userKey, fileKey
示例#2
0
def wcdb_decrypt_first_page(raw, page_size, device_salt, password):
    salt_mask = 0x3a
    salt_size = 16
    cipher_key_size = 32
    cipher_key_iter = 4000
    cipher_iv_size = algorithms.AES.block_size // 8
    hmac_key_size = cipher_key_size
    hmac_key_iter = 2
    hmac_sig_size = hashes.SHA1.digest_size
    reserved_size = (cipher_iv_size + hmac_sig_size +
                     algorithms.AES.block_size // 8 -
                     1) // (algorithms.AES.block_size //
                            8) * (algorithms.AES.block_size // 8)

    page = raw[0:page_size]
    page_salt = page[:salt_size]
    page_content_enc = page[salt_size:-reserved_size]
    page_reserved = page[-reserved_size:]

    cipher_iv = page_reserved[0:cipher_iv_size]
    hmac_sig = page_reserved[cipher_iv_size:cipher_iv_size + hmac_sig_size]

    cipher_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(), cipher_key_size, device_salt,
                                   1, default_backend()).derive(
                                       pbkdf2.PBKDF2HMAC(
                                           hashes.SHA1(), cipher_key_size,
                                           page_salt, cipher_key_iter,
                                           default_backend()).derive(password))

    hmac_key = pbkdf2.PBKDF2HMAC(
        hashes.SHA1(), hmac_key_size, device_salt, 1,
        default_backend()).derive(
            pbkdf2.PBKDF2HMAC(hashes.SHA1(), hmac_key_size,
                              bytes([x ^ salt_mask
                                     for x in page_salt]), hmac_key_iter,
                              default_backend()).derive(cipher_key))

    h = hmac.HMAC(hmac_key, hashes.SHA1(), default_backend())
    h.update(page_content_enc)
    h.update(cipher_iv)
    h.update(int(1).to_bytes(4, 'little'))
    h.verify(hmac_sig)

    decryptor = Cipher(algorithms.AES(cipher_key), modes.CBC(cipher_iv),
                       default_backend()).decryptor()

    page_content_dec = decryptor.update(
        page_content_enc) + decryptor.finalize()
    assert (page_content_dec[21 - 16] == 64)
    assert (page_content_dec[22 - 16] == 32)
    assert (page_content_dec[23 - 16] == 32)
    assert (all(v == 0 for v in page_content_dec[72 - 16:72 - 16 + 20]))

    return b'SQLite format 3\x00' + page_content_dec
示例#3
0
def wcdb_decrypt_left_pages(raw, page_size, device_salt, password):
    salt_mask = 0x3a
    salt_size = 16
    cipher_key_size = 32
    cipher_key_iter = 4000
    cipher_iv_size = algorithms.AES.block_size // 8
    hmac_key_size = cipher_key_size
    hmac_key_iter = 2
    hmac_sig_size = hashes.SHA1.digest_size
    reserved_size = (cipher_iv_size + hmac_sig_size +
                     algorithms.AES.block_size // 8 -
                     1) // (algorithms.AES.block_size //
                            8) * (algorithms.AES.block_size // 8)

    salt = raw[0:salt_size]

    cipher_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(), cipher_key_size, device_salt,
                                   1, default_backend()).derive(
                                       pbkdf2.PBKDF2HMAC(
                                           hashes.SHA1(), cipher_key_size,
                                           salt, cipher_key_iter,
                                           default_backend()).derive(password))

    hmac_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(), hmac_key_size, device_salt, 1,
                                 default_backend()).derive(
                                     pbkdf2.PBKDF2HMAC(
                                         hashes.SHA1(), hmac_key_size,
                                         bytes([x ^ salt_mask
                                                for x in salt]), hmac_key_iter,
                                         default_backend()).derive(cipher_key))

    raw_dec = bytearray()
    for i in range(1, len(raw) // page_size):
        page = raw[i * page_size:i * page_size + page_size]
        page_content_enc = page[:-reserved_size]
        page_reserved = page[-reserved_size:]

        cipher_iv = page_reserved[0:cipher_iv_size]
        hmac_sig = page_reserved[cipher_iv_size:cipher_iv_size + hmac_sig_size]

        h = hmac.HMAC(hmac_key, hashes.SHA1(), default_backend())
        h.update(page_content_enc)
        h.update(cipher_iv)
        h.update((i + 1).to_bytes(4, 'little'))
        h.verify(hmac_sig)

        decryptor = Cipher(algorithms.AES(cipher_key), modes.CBC(cipher_iv),
                           default_backend()).decryptor()

        raw_dec.extend(
            decryptor.update(page_content_enc) + decryptor.finalize())

    return bytes(raw_dec)
示例#4
0
文件: crypto.py 项目: wxh0000mm/grr
 def _CalculateHash(self, password, salt, iteration_count):
     kdf = pbkdf2.PBKDF2HMAC(algorithm=hashes.SHA256(),
                             length=32,
                             salt=salt,
                             iterations=iteration_count,
                             backend=openssl.backend)
     return kdf.derive(password)
示例#5
0
    def __init__(self, enckey):
        params = fetch(
            enckey,
            "./xenc11:DerivedKey/xenc11:KeyDerivationMethod/pkcs5:PBKDF2-params"
        )
        if params is None:
            raise ValueError("XML file is missing PBKDF2 parameters!")

        salt = fetch(params, "./Salt/Specified/text()", base64.b64decode)
        itrs = fetch(params, "./IterationCount/text()", int)
        klen = fetch(params, "./KeyLength/text()", int)
        hmod = fetch(params, "./PRF/@Algorithm", convertHMACType, hashes.SHA1)

        if salt is None:
            raise ValueError("XML file is missing PBKDF2 salt!")

        if itrs is None:
            raise ValueError("XML file is missing PBKDF2 iteration count!")

        if klen is None:
            raise ValueError("XML file is missing PBKDF2 key length!")

        self.kdf = pbkdf2.PBKDF2HMAC(algorithm=hmod(),
                                     length=klen,
                                     salt=salt,
                                     iterations=itrs,
                                     backend=default_backend())
示例#6
0
def _derive_key(password: bytes) -> bytes:
    kdf = pbkdf2.PBKDF2HMAC(algorithm=hashes.SHA256(),
                            length=32,
                            salt=b'',
                            iterations=pow(10, 7),
                            backend=backends.default_backend())
    return base64.urlsafe_b64encode(kdf.derive(password))
def encrypt(key, iv, salt, plaintext, iterations=1000):
    """
    Returns:
       (bytes) ciphertext
    """
    if len(salt) != 16:
        raise Exception("Expected 128 bits of salt - got %i bits" % len(
            (salt) * 8))
    if len(iv) != 16:
        raise Exception("Expected 128 bits of IV - got %i bits" %
                        (len(iv) * 8))

    sha = hashes.SHA512()
    kdf = pbkdf2.PBKDF2HMAC(sha, 64, salt, iterations, backend)
    k = kdf.derive(key)

    aes_key = k[0:32]
    sha_key = k[32:]

    packed_file = (
        b"\x01"  # version
        + salt + iv + struct.pack(">L", iterations) +
        encrypt_ctr(aes_key, iv, plaintext))
    packed_file += hmac_sha256(sha_key, packed_file)

    return (b"-----BEGIN MEGOLM SESSION DATA-----\n" +
            base64.encodestring(packed_file) +
            b"-----END MEGOLM SESSION DATA-----")
示例#8
0
    def DecryptString(self, ciphertext: str) -> str:
        ciphertext_bytes = base64.b64decode(ciphertext)

        salt, header, body = ciphertext_bytes[:48], ciphertext_bytes[
            48:48 + 16], ciphertext_bytes[48 + 16:]
        if len(salt) == 48 and len(header) == 16:
            xts_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(),
                                        128 // 8 * 2, salt[0:40], 1000,
                                        default_backend()).derive(
                                            self._password)
        else:
            raise ValueError('Broken ciphertext: length is too short.')

        xts_cipher = Cipher(
            algorithms.AES(xts_key),
            modes.XTS(
                b'\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00'
            ), default_backend())
        xts_decryptor = xts_cipher.decryptor()
        header = xts_decryptor.update(header) + xts_decryptor.finalize()
        header_tag, header_textlength, header_blocksize = \
            header[0:4], int.from_bytes(header[4:12], 'little'), int.from_bytes(header[12:16], 'little')
        padded_textlength = header_textlength if header_textlength % 16 == 0 else header_textlength + 16 - header_textlength % 16
        if not (header_tag == b'XTS1'):
            raise ValueError('Broken ciphertext: header_tag is corrupted.')
        if not (padded_textlength == len(body)):
            raise ValueError(
                'Broken ciphertext: header_textlength is corrupted.')
        if not (0 < header_blocksize <= 0x100000
                and header_blocksize % 16 == 0):
            raise ValueError(
                'Broken ciphertext: header_blocksize is corrupted.')

        plaintext_bytes = bytearray()
        for i in itertools.count():
            offset_begin = i * header_blocksize
            offset_end = offset_begin + header_blocksize
            if offset_begin < len(body):
                xts_cipher = Cipher(algorithms.AES(xts_key),
                                    modes.XTS(i.to_bytes(16, 'little')),
                                    default_backend())
                xts_decryptor = xts_cipher.decryptor()

                block = xts_decryptor.update(
                    body[offset_begin:offset_end]) + xts_decryptor.finalize()
                if len(
                        block
                ) < header_blocksize and header_textlength != padded_textlength:
                    block = block[0:header_textlength - padded_textlength]

                plaintext_bytes.extend(block)
            else:
                break

        return plaintext_bytes.decode('utf-8')
示例#9
0
 def configure(self):
     backend = self.configured_data['BACKEND']
     digest = self.configured_data['DIGEST']
     salt = self.configured_data['SALT']
     # Key Derivation Function
     kdf = pbkdf2.PBKDF2HMAC(
         algorithm=digest,
         length=digest.digest_size,
         salt=salt,
         iterations=30000,
         backend=backend,
     )
     self.configured_data['KEY'] = kdf.derive(
         force_bytes(self.configured_data['KEY'] or settings.SECRET_KEY))
     return self.configured_data
示例#10
0
    def EncryptString(self, plaintext: str) -> str:
        plaintext_bytes = plaintext.encode('utf-8')

        salt = os.urandom(48)

        header_tag = b'XTS1'
        header_textlength = len(plaintext_bytes)
        header_blocksize = 0x10000

        xts_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(),
                                    128 // 8 * 2, salt[0:40], 1000,
                                    default_backend()).derive(self._password)

        body = bytearray()
        for i in itertools.count():
            offset_begin = i * header_blocksize
            offset_end = offset_begin + header_blocksize
            if offset_begin < len(plaintext_bytes):
                xts_cipher = Cipher(algorithms.AES(xts_key),
                                    modes.XTS(i.to_bytes(16, 'little')),
                                    default_backend())
                xts_encryptor = xts_cipher.encryptor()

                block = plaintext_bytes[offset_begin:offset_end]
                if len(block) % 16 != 0:
                    block += b'\x00' * (16 - len(block) % 16)

                body.extend(
                    xts_encryptor.update(block) + xts_encryptor.finalize())
            else:
                break

        xts_cipher = Cipher(
            algorithms.AES(xts_key),
            modes.XTS(
                b'\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00'
            ), default_backend())
        xts_encryptor = xts_cipher.encryptor()
        header = xts_encryptor.update(
            header_tag + header_textlength.to_bytes(8, 'little') +
            header_blocksize.to_bytes(4, 'little')) + xts_encryptor.finalize()

        ciphertext_bytes = salt + header + body

        return base64.b64encode(ciphertext_bytes).decode('utf-8')
示例#11
0
 def _create_encryption_key(
     password: Union[bytes, str], hash_salt: bytes, hash_iterations: int
 ) -> bytes:
     password = password.encode() if isinstance(password, str) else password
     kdf = pbkdf2.PBKDF2HMAC(hashes.SHA256(), 32, hash_salt, hash_iterations)
     return base64.urlsafe_b64encode(kdf.derive(password))
示例#12
0
 def pbkdf2_sha256(password, salt, iters):
     """PBKDF2 with HMAC-SHA256"""
     ctx = pbkdf2.PBKDF2HMAC(hashes.SHA256(), 32, salt, iters,
                             default_backend())
     return ctx.derive(password)
示例#13
0
def wcdb_generate_device_salt(serialno: bytes, cpu_serial: bytes):
    serial = serialno + cpu_serial
    return pbkdf2.PBKDF2HMAC(hashes.SHA1(), 16, serial, 1,
                             default_backend()).derive(serial)
示例#14
0
 def _transform_password(password: str, hash_salt: bytes,
                         hash_iterates: int) -> bytes:
     kdf = pbkdf2.PBKDF2HMAC(hashes.SHA256(), 32, hash_salt, hash_iterates)
     return b64.urlsafe_b64encode(kdf.derive(password.encode()))