Erik Aronesty
Erik Aronesty

Reputation: 12877

Has anyone gotten Dpapi and Roaming Profiles to work?

According to Microsoft, DPAPI should be able to encrypt data on one machine, and decrypt it on another:

See: https://support.microsoft.com/en-us/topic/bf374083-626f-3446-2a9d-3f6077723a60#bkmk_6

When I am logged into a domain controller, and encrypt a file, I expect to be able to log out, transfer and decrypt it on another machine logged in on the same user.

However, I get this error:

error: (-2146893813, 'CryptProtectData', 'Key not valid for use in specified state.')

Which implies that the "roaming" didn't work. I'm assuming there are some group policy things I need to set to get those creds to roam properly.

Also, if there's a better way to do this (some other api to use the logged-in user's existing creds), I'm ok with that.

Here's the script I use to test:

import argparse
import os
import sys

from win32crypt import CryptProtectData, CryptUnprotectData


def dpapi_encrypt(fin, fout):
    dat = fin.read()
    fout.write(CryptProtectData(dat))


def dpapi_decrypt(fin, fout):
    (_descr, dat) = CryptUnprotectData(fin.read())
    if dat and dat[-1] == 0:
        dat = dat[:-1]
    fout.write(dat)


def do_fileop(file, op):
    if file == "-":
        fin = sys.stdin.buffer
        fout = sys.stdout.buffer
        op(fin, fout)
    else:
        with open(file, "rb") as fin:
            tmp = file + ".dpapi-enc"
            with open(tmp, "wb") as fout:
                op(fin, fout)
        os.replace(tmp, file)


def encrypt_file(file):
    do_fileop(file, dpapi_encrypt)


def decrypt_file(file):
    do_fileop(file, dpapi_decrypt)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("file")
    parser.add_argument("--encrypt", "-e", action="store_true")
    parser.add_argument("--decrypt", "-d", action="store_true")
    args = parser.parse_args()

    if args.encrypt:
        encrypt_file(args.file)
    elif args.decrypt:
        decrypt_file(args.file)
    else:
        print("error: specify --encrypt or --decrypt", file=sys.stdout)


if __name__ == "__main__":
    main()

Upvotes: 3

Views: 210

Answers (0)

Related Questions