Jump to content

Problem with encryption, decryption and the Credential Manager


Go to solution Solved by DonChunior,

Recommended Posts

I've got a problem where I just can't figure out the cause. 🤔

The simple script below does the following:

  1. At the beginning, you can enter a test string.
  2. This is then encrypted and temporarily stored in the Credential Manager.
  3. Then the data is read again from the Credential Manager and decrypted.

Many words (e.g. DonChunior or AutoIt) correspond to the originally entered string after decryption.
But for some, for whatever reason I can't figure out, it doesn't?!
For example:

  • VeryLongString (the decrypted string is VeryLongStrin)
  • ILoveAutoIt (the decrypted string is ILoveAutoI)
  • WhatIsHereTheProblem (the decrypted string is WhatIsHere)

I hope some of you specialists can help me. 🙏

#include <Crypt.au3>
#include <WinAPIDlg.au3>

Main()

Func Main()
    Local $sString = ""
    Local Const $sCryptKey = "=>J7U\DJ/qFun?Co"
    Local $dData = Binary("")
    Local Const $sTarget = "Dummy Credentials"
    Local $aData = 0

    ; Get a string that will be used for testing the encryption and decryption
    $sString = InputBox("String Input", "Enter a test string:")
    ConsoleWrite("$sString: " & $sString & @CRLF)

    _Crypt_Startup()

    ; Encrypt the previousely entered string
    $dData = _Crypt_EncryptData(StringToBinary($sString, $SB_UTF8), StringToBinary($sCryptKey, $SB_UTF8), $CALG_RC4)
    If @error Then
        ConsoleWrite("_Crypt_EncryptData: @error = " & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite("$dData: " & $dData & @CRLF)

    ; Store the encrypted string in the Credential Manager
    RunWait('cmdkey /generic:"' & $sTarget & '" /user:DummyUserName /pass:"' & BinaryToString($dData) & '"')

    ; Read the data stored in the Credential Manager
    $aData = _WinAPI_ShellUserAuthenticationDlg( _
            "", _
            "", _
            "", _
            "", _
            $sTarget, _
            $CREDUI_FLAGS_GENERIC_CREDENTIALS)
    ConsoleWrite("$aData[0]: " & $aData[0] & @CRLF)
    ConsoleWrite("$aData[1]: " & $aData[1] & @CRLF)

    ; Delete the entry in the Credential Manager
    RunWait('cmdkey /delete:"' & $sTarget & '"')

    ; Decrypt the data read from the Credential Manager
    $dData = _Crypt_DecryptData($aData[1], StringToBinary($sCryptKey, $SB_UTF8), $CALG_RC4)
    If @error Then
        ConsoleWrite("_Crypt_DecryptData: @error = " & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite("$dData: " & $dData & @CRLF)

    _Crypt_Shutdown()

    ; Convert the data back to a string
    $sString = BinaryToString($dData, $SB_UTF8)
    ConsoleWrite("$sString: " & $sString & @CRLF)
EndFunc   ;==>Main
Link to comment
Share on other sites

Well, when you store the encrypted string in Credential Manager you might end there with some characters that might not be accepted. Let's take for example the string WhatIsHereTheProblem. After you encrypt that string you have a binary like this one 0xD30B275190CF6055989600883E25CDC3D1BA0D9C. It's easy to spot that 11th character is null character (00). Convert that binary to string and you already send messy data to Credential Manager so don't expect anything good when you try to read and decrypt what Credential Manager saved. So it's not about length but about what you get after encryption. You can test that with a string even longer like "Very longggggggggggggggg" and you can see this one doesn't have any problem, but it's just a happy case.

Edited by Andreik
Link to comment
Share on other sites

12 minutes ago, DonChunior said:

Does anyone else have any ideas?

One of the simplest ways would be to store your encrypted data as text using a binary-to-text encoding scheme like Base64.

Link to comment
Share on other sites

  • Solution
38 minutes ago, TheXman said:

One of the simplest ways would be to store your encrypted data as text using a binary-to-text encoding scheme like Base64.

I only had to slightly adjust the code in two places so that it now works as expected. 🙂

Line 28 now reads like this:

RunWait('cmdkey /generic:"' & $sTarget & '" /user:DummyUserName /pass:"' & String($dData) & '"')

And line 45 now reads like this:

$dData = _Crypt_DecryptData(Binary($aData[1]), StringToBinary($sCryptKey, $SB_UTF8), $CALG_RC4)

The complete script now looks like this:

#include <Crypt.au3>
#include <WinAPIDlg.au3>

Main()

Func Main()
    Local $sString = ""
    Local Const $sCryptKey = "=>J7U\DJ/qFun?Co"
    Local $dData = Binary("")
    Local Const $sTarget = "Dummy Credentials"
    Local $aData = 0

    ; Get a string that will be used for testing the encryption and decryption
    $sString = InputBox("String Input", "Enter a test string:")
    ConsoleWrite("$sString: " & $sString & @CRLF)

    _Crypt_Startup()

    ; Encrypt the previousely entered string
    $dData = _Crypt_EncryptData(StringToBinary($sString, $SB_UTF8), StringToBinary($sCryptKey, $SB_UTF8), $CALG_RC4)
    If @error Then
        ConsoleWrite("_Crypt_EncryptData: @error = " & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite("$dData: " & $dData & @CRLF)

    ; Store the encrypted string in the Credential Manager
    RunWait('cmdkey /generic:"' & $sTarget & '" /user:DummyUserName /pass:"' & String($dData) & '"')

    ; Read the data stored in the Credential Manager
    $aData = _WinAPI_ShellUserAuthenticationDlg( _
            "", _
            "", _
            "", _
            "", _
            $sTarget, _
            $CREDUI_FLAGS_GENERIC_CREDENTIALS)
    ConsoleWrite("$aData[0]: " & $aData[0] & @CRLF)
    ConsoleWrite("$aData[1]: " & $aData[1] & @CRLF)

    ; Delete the entry in the Credential Manager
    RunWait('cmdkey /delete:"' & $sTarget & '"')

    ; Decrypt the data read from the Credential Manager
    $dData = _Crypt_DecryptData(Binary($aData[1]), StringToBinary($sCryptKey, $SB_UTF8), $CALG_RC4)
    If @error Then
        ConsoleWrite("_Crypt_DecryptData: @error = " & @error & @CRLF)
        Exit
    EndIf
    ConsoleWrite("$dData: " & $dData & @CRLF)

    _Crypt_Shutdown()

    ; Convert the data back to a string
    $sString = BinaryToString($dData, $SB_UTF8)
    ConsoleWrite("$sString: " & $sString & @CRLF)
EndFunc   ;==>Main
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...