Is there a way to use the DPAPI (Data Protection Application Programming Interface) on Windows XP with Python?
I would prefer to use an existing module if there is one that can do it. Unfortunately I haven't been able to find a way with Google or Stack Overflow.
EDIT: I've taken the example code pointed to by "dF" and tweaked it into a standalone library which can be simply used at a high level to crypt and decrypt using DPAPI in user mode. Simply call dpapi.cryptData(text_to_encrypt) which returns an encrypted string, or the reverse decryptData(encrypted_data_string), which returns the plain text. Here's the library:
# DPAPI access library
# This file uses code originally created by Crusher Joe:
# http://article.gmane.org/gmane.comp.python.ctypes/420
#
from ctypes import *
from ctypes.wintypes import DWORD
LocalFree = windll.kernel32.LocalFree
memcpy = cdll.msvcrt.memcpy
CryptProtectData = windll.crypt32.CryptProtectData
CryptUnprotectData = windll.crypt32.CryptUnprotectData
CRYPTPROTECT_UI_FORBIDDEN = 0x01
extraEntropy = "cl;ad13 \0al;323kjd #(adl;k$#ajsd"
class DATA_BLOB(Structure):
_fields_ = [("cbData", DWORD), ("pbData", POINTER(c_char))]
def getData(blobOut):
cbData = int(blobOut.cbData)
pbData = blobOut.pbData
buffer = c_buffer(cbData)
memcpy(buffer, pbData, cbData)
LocalFree(pbData);
return buffer.raw
def Win32CryptProtectData(plainText, entropy):
bufferIn = c_buffer(plainText, len(plainText))
blobIn = DATA_BLOB(len(plainText), bufferIn)
bufferEntropy = c_buffer(entropy, len(entropy))
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy)
blobOut = DATA_BLOB()
if CryptProtectData(byref(blobIn), u"python_data", byref(blobEntropy),
None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blobOut)):
return getData(blobOut)
else:
return ""
def Win32CryptUnprotectData(cipherText, entropy):
bufferIn = c_buffer(cipherText, len(cipherText))
blobIn = DATA_BLOB(len(cipherText), bufferIn)
bufferEntropy = c_buffer(entropy, len(entropy))
blobEntropy = DATA_BLOB(len(entropy), bufferEntropy)
blobOut = DATA_BLOB()
if CryptUnprotectData(byref(blobIn), None, byref(blobEntropy), None, None,
CRYPTPROTECT_UI_FORBIDDEN, byref(blobOut)):
return getData(blobOut)
else:
return ""
def cryptData(text):
return Win32CryptProtectData(text, extraEntropy)
def decryptData(cipher_text):
return Win32CryptUnprotectData(cipher_text, extraEntropy)
I have been using CryptProtectData
and CryptUnprotectData
through ctypes, with the code from
http://article.gmane.org/gmane.comp.python.ctypes/420
and it has been working well.
Also, pywin32 implements CryptProtectData and CryptUnprotectData in the win32crypt module.
The easiest way would be to use Iron Python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With