Convert PasswordDeriveBytes functionality to Python

1.4k Views Asked by At

I'm trying to re-create PowerShell's PasswordDeriveBytes method in python using pycryptodome's KDF module.

The main thing I can't get passed right now is getting the correct DerivedKey result in Python that I get from PowerShell.

PARAMETERS:

password = '1234567890'
salt = '0987654321'
length = 16
iterations = 2

SAMPLE POWERSHELL CODE:

$AsciiEncoder = New-Object System.Text.ASCIIEncoding;
$DerivedPass = New-Object System.Security.Cryptography.PasswordDeriveBytes('1234567890', $AsciiEncoder.GetBytes('0987654321'), "SHA1", 2);
[Byte[]] $KeyBytes = $DerivedPass.GetBytes(16);
-join($KeyBytes | ForEach { $_.ToString("X2")});

RESULT:

C937511EBDBE12C7A0FCC8D6CB42BEDC 

*NOTE: The PowerShell code above is amended from https://github.com/PowerShellMafia/PowerSploit/blob/master/ScriptModification/Out-EncryptedScript.ps1. I am trying to re-implement the functionality in the Python code below.

PYTHON CODE:

from Crypto.Protocol import KDF
from Crypto.Hash import SHA1

def password_derive_key(password, salt, length, count):
    return KDF.PBKDF2(password, salt, length, count)

def main():
    derivedKey = password_derive_key('1234567890', '0987654321', 16, 2)
    print derivedKey.encode('hex')

if __name__ == "__main__":
    main()

RESULT:

5a3f103f5dc4558f8dca5d5b145ed0b4

The only thing that I can think of us that the ".GetBytes" method of PasswordDeriveBytes is generating a different result than what pycryptodome's KDF module.

Any help would be greatly appreciated.

1

There are 1 best solutions below

2
On

The arguments need to be the same, in the question code the iterations are different:

POWERSHELL iterations: 2
System.Security.Cryptography.PasswordDeriveBytes('1234567890', $AsciiEncoder.GetBytes('0987654321'), "SHA1", 2);

PYTHON iterations: 1000
derivedKey = password_derive_key('1234567890', '0987654321', 16, 1000)

Make sure the correct encoding are used for each.

Note: By using functions as arguments makes debugging more difficult, example: $AsciiEncoder.GetBytes('0987654321').