2009-01-21 11 views
14

¿Hay alguna manera de utilizar DPAPI (Interfaz de programación de aplicaciones de protección de datos) en Windows XP con Python?¿Usando DPAPI con Python?

Preferiría utilizar un módulo existente si hay uno que pueda hacerlo. Lamentablemente, no he podido encontrar la manera de usar Google o Stack Overflow.

EDIT: que he tomado el código de ejemplo a la que apunta "dF" y ajustado en una biblioteca independiente que se puede utilizar simplemente en un nivel alto para encriptar y descifrar utilizando DPAPI en modo de usuario. Simplemente llame a dpapi.cryptData (text_to_encrypt) que devuelve una cadena encriptada, o al inverso decryptData (encrypted_data_string), que devuelve el texto sin formato. Aquí está la biblioteca:

# 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) 
+0

Dulce - gran actualización. –

+0

Esto no funciona en Win7 de 64 bits, Python 3.5.2. Devuelve una cadena binaria vacía. –

Respuesta

8

He estado usando CryptProtectData y CryptUnprotectData través ctypes, con el código de

http://article.gmane.org/gmane.comp.python.ctypes/420

y ha funcionado bien.

+0

Fantástico, justo lo que estaba buscando. Gracias. –

+1

Gracias por el gran consejo. Hice un poco de refactorización y agregué esta capacidad al proyecto jaraco.windows. Consulte https://svn.jaraco.com/jaraco/python/jaraco.windows/jaraco/windows/dpapi.py para obtener más información. –

+0

¿Este código es compatible con Python 3? –

2

La forma más fácil sería utilizar Iron Python.

+0

Gracias, pero realmente preferiría algo que se pueda usar con la distribución estándar de python.org. –

4

Además, pywin32 implementa CryptProtectData y CryptUnprotectData en el módulo win32crypt.

+0

Gracias por la sugerencia, probablemente empiece a usar eso a partir de ahora. –

Cuestiones relacionadas