示例#1
0
def encrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz,
            hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz):
    salt_sz = 16
    salt = util.random_bytes(salt_sz)
    enc = salt

    # derive key
    key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz,
                                    key_iter, hmac_key_sz, hmac_key_iter)

    # encrypt pages
    for i in range(0, int(len(raw) / 1024)):
        page = util.get_page(raw, page_sz, i + 1)
        if i == 0:
            # skip header string
            page = page[salt_sz:]
        page_content = page[:-reserve_sz]
        iv = util.random_bytes(iv_sz)
        # encrypt content
        page_enc = util.encrypt(page_content, key, iv)
        # generate hmac
        hmac_new = util.generate_hmac(hmac_key, page_enc + iv, i + 1)
        enc += page_enc + iv + hmac_new
        if reserve_sz > iv_sz + hmac_sz:
            enc += util.random_bytes(reserve_sz - iv_sz - hmac_sz)

    return enc
示例#2
0
def decrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz,
            hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz):
    dec = b'SQLite format 3\0'

    # derive key
    salt_sz = 16
    salt = raw[:salt_sz]
    key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz,
                                    key_iter, hmac_key_sz, hmac_key_iter)

    # decrypt file header, try with default page size
    page_sz, reserve_sz = decrypt_page_header(raw, key, salt_sz, page_sz,
                                              iv_sz, reserve_sz)
    if page_sz < 0 or reserve_sz < 0:
        raise RuntimeError('failed to decide page size or reserve size.')

    # decrypt pages
    for i in range(0, int(len(raw) / 1024)):
        page = util.get_page(raw, page_sz, i + 1)
        if i == 0:
            # skip salt
            page = page[salt_sz:]
        page_content = page[:-reserve_sz]
        reserve = page[-reserve_sz:]
        iv = reserve[:iv_sz]
        # check hmac
        hmac_old = reserve[iv_sz:iv_sz + hmac_sz]
        hmac_new = util.generate_hmac(hmac_key, page_content + iv, i + 1)
        if not hmac_old == hmac_new:
            raise RuntimeError('hmac check failed in page %d.' % (i + 1))
        # decrypt content
        page_dec = util.decrypt(page_content, key, iv)
        dec += page_dec + util.random_bytes(reserve_sz)

    return dec
示例#3
0
def try_get_reserve_size_for_specified_page_size(raw, key, salt_sz, page_sz,
                                                 iv_sz, reserve_sz):
    """Try to decrypt first page with specified page size.

    If default reserve size fail, change reserve size.
    When succeed, return reserve size.
    If always fail, return -1.
    """

    first_page_content = util.get_page(raw, page_sz, 1)[salt_sz:]

    if reserve_sz >= iv_sz:
        first_page_dec = decrypt_by_reserve_size(first_page_content, key,
                                                 iv_sz, reserve_sz)
        # default reserve_sz is ok
        if util.is_valid_decrypted_header(first_page_dec) \
                and page_sz == util.get_page_size_from_database_header(raw[:salt_sz] + first_page_dec) \
                and reserve_sz == util.get_reserved_size_from_database_header(raw[:salt_sz] + first_page_dec):
            return reserve_sz

    # try every possible reserve size.
    # the usable size of a page is at least 480.
    for reserve_sz in range(iv_sz, page_sz - 480):
        first_page_dec = decrypt_by_reserve_size(first_page_content, key,
                                                 iv_sz, reserve_sz)
        if util.is_valid_decrypted_header(first_page_dec) \
                and page_sz == util.get_page_size_from_database_header(raw[:salt_sz] + first_page_dec) \
                and reserve_sz == util.get_reserved_size_from_database_header(raw[:salt_sz] + first_page_dec):
            return reserve_sz

    return -1  # fail
示例#4
0
def encrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz):
    salt_sz = 16
    salt = util.random_bytes(salt_sz)
    enc = salt

    # derive key
    key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter)

    # encrypt pages
    for i in range(0, int(len(raw) / 1024)):
        page = util.get_page(raw, page_sz, i + 1)
        if i == 0:
            # skip header string
            page = page[salt_sz:]
        page_content = page[:-reserve_sz]
        iv = util.random_bytes(iv_sz)
        # encrypt content
        page_enc = util.encrypt(page_content, key, iv)
        # generate hmac
        hmac_new = util.generate_hmac(hmac_key, page_enc + iv, i + 1)
        enc += page_enc + iv + hmac_new
        if reserve_sz > iv_sz + hmac_sz:
            enc += util.random_bytes(reserve_sz - iv_sz - hmac_sz)

    return enc
示例#5
0
def decrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz):
    dec = b'SQLite format 3\0'

    # derive key
    salt_sz = 16
    salt = raw[:salt_sz]
    key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter)

    # decrypt file header, try with default page size
    page_sz, reserve_sz = decrypt_page_header(raw, key, salt_sz, page_sz, iv_sz, reserve_sz)
    if page_sz < 0 or reserve_sz < 0:
        raise RuntimeError('failed to decide page size or reserve size.')

    # decrypt pages
    for i in range(0, int(len(raw) / 1024)):
        page = util.get_page(raw, page_sz, i + 1)
        if i == 0:
            # skip salt
            page = page[salt_sz:]
        page_content = page[:-reserve_sz]
        reserve = page[-reserve_sz:]
        iv = reserve[:iv_sz]
        # check hmac
        hmac_old = reserve[iv_sz:iv_sz+hmac_sz]
        hmac_new = util.generate_hmac(hmac_key, page_content + iv, i + 1)
        if not hmac_old == hmac_new:
            raise RuntimeError('hmac check failed in page %d.' % (i+1))
        # decrypt content
        page_dec = util.decrypt(page_content, key, iv)
        dec += page_dec + util.random_bytes(reserve_sz)

    return dec
示例#6
0
def try_get_reserve_size_for_specified_page_size(raw, key, salt_sz, page_sz, iv_sz, reserve_sz):
    """Try to decrypt first page with specified page size.

    If default reserve size fail, change reserve size.
    When succeed, return reserve size.
    If always fail, return -1.
    """

    first_page_content = util.get_page(raw, page_sz, 1)[salt_sz:]

    if reserve_sz >= iv_sz:
        first_page_dec = decrypt_by_reserve_size(first_page_content, key, iv_sz, reserve_sz)
        # default reserve_sz is ok
        if util.is_valid_decrypted_header(first_page_dec) \
                and page_sz == util.get_page_size_from_database_header(raw[:salt_sz] + first_page_dec) \
                and reserve_sz == util.get_reserved_size_from_database_header(raw[:salt_sz] + first_page_dec):
            return reserve_sz

    # try every possible reserve size.
    # the usable size of a page is at least 480.
    for reserve_sz in range(iv_sz, page_sz - 480):
        first_page_dec = decrypt_by_reserve_size(first_page_content, key, iv_sz, reserve_sz)
        if util.is_valid_decrypted_header(first_page_dec) \
                and page_sz == util.get_page_size_from_database_header(raw[:salt_sz] + first_page_dec) \
                and reserve_sz == util.get_reserved_size_from_database_header(raw[:salt_sz] + first_page_dec):
            return reserve_sz

    return -1   # fail