Crypt.au3 <-> PHP mcrypt

  • vereinfachtes script au3:

    Spoiler anzeigen
    [autoit]


    #include <Crypt.au3>
    $TEXT="ich"
    $PASS="pass"

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $TEXT = ' & $TEXT & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $EncryptData=_Crypt_EncryptData($TEXT, $PASS, $CALG_AES_256, True) ; oder $CALG_RC2

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $EncryptData = ' & $EncryptData & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $EncryptData = ' & BinaryToString($EncryptData) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $DecryptData=BinaryToString(_Crypt_DecryptData($EncryptData, $PASS, $CALG_AES_256, True)) ; oder $CALG_RC2
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DecryptData = ' & $DecryptData & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit]

    nur die function php:

    Spoiler anzeigen

    Der String soll übertragen in beide Richtungen gehen!
    Das Password/CryptKey is beiden Seiten bekannt!

    das was ich nicht hinbekomme ist encrypt/decrypt egal von wo aus php zu Autoit oder Autoit zu php
    das Übertragung und holen ist nicht das Problem des Crypstring.

    Einmal editiert, zuletzt von Maniac (1. Juli 2010 um 17:28)

  • selber eine lösung gefunden:
    Windows höher als Win 2000
    php4/5 benötigt mcrypt
    Prüfen mit:

    PHP
    phpinfo();


    unter mcrypt dort "Supported ciphers" -> "rijndael-256" stehen!


    Autoit zu PHP:

    Spoiler anzeigen
    [autoit]


    #include <rijndael.au3> ; <----- http://www.autoitscript.com/forum/index.php?showtopic=44581
    #include <String.au3>
    #include <Crypt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $dat = "verschlüssel mich!"
    $key = 'ich bin da'

    [/autoit] [autoit][/autoit] [autoit]

    $key=StringLower(StringTrimLeft ( _Crypt_HashData($key, $CALG_MD5), 2 ))
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $key = ' & $key& @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $enc = _StringToHex(BinaryToString(_rijndaelCipher($key,$dat,256,0,_IV())))
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $enc = ' & $enc & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit]

    So jetzt kann $enc zu PHP übergeben werden! z.b. per POST oder GET

    PHP zu Autoit:

    Spoiler anzeigen
    PHP
    $key =md5("ich bin da"),"\n";
    $text = "verschlüssel mich!";
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
    echo "Encode: ",$encode=strtoupper(bin2hex($crypttext));

    wie ihr die daten von PHP holt ist euch überlassen!!
    _INetGetSource oder InetGet z.b.

    [autoit]


    #include <rijndael.au3> ; <----- http://www.autoitscript.com/forum/index.php?showtopic=44581
    #include <String.au3>
    #include <Crypt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    $enc wie auch immer ihr die daten holt
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    $den=_HexToString($enc)
    $den=_rijndaelInvCipher($key,$den,256,0,_IV())
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $den = ' & BinaryToString($den) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    Func _IV()
    Local $Temp
    For $i=1 to 64
    $Temp&=Random ( 0 , 9 , 1 )
    Next
    Return Binary("0x"&$Temp)
    EndFunc

    [/autoit]

    hoffe mal das ich nicht noch ein schussel Fehler drin eingebaut habe sollte es gehen!
    Wer Verbesserungsvorschläge hat immer her da mit!?

    4 Mal editiert, zuletzt von Maniac (1. Juli 2010 um 17:39)

  • Ich habs mir mal durchgelesen, wirklich verstehen kann ich nicht warum AES 256 und als Gegenstück Rijndael 128 verwendet werden soll.
    Die Algos unterscheiden sich doch nur darin, dass Rijndael variable Blockgrößen/Keygrößen zulässt (32 bit Abstufungen)

    edit: Die Beispiele von "Maniac" funktionieren alle Einwandfrei! Da der Vorschlag nur mit der Crypt UDF zu arbeiten super ist, wäre es toll, wenn du wie er Sample Code liefern könntest oder mir etwas mehr Informationen zukommen lassen könntest, denn selbsterklärend ist das Thema nicht. (auch nicht über den Link).

    In summary: If you want to be AES compliant, always choose MCRYPT_RIJNDAEL_128. :wacko:

    3 Mal editiert, zuletzt von horst290 (10. Oktober 2011 um 12:58)

  • Der Algorithmus Rjindael wurde aus mehreren Bewerbern als AES ausgewählt. Es ist ein Blockcipher, die Daten werden in Blöcken verschlüsselt. Zahl bei MCRYPT_RIJNDAEL_### gibt die Blocklänge an. Für AES wurde die Blocklänge 128 bit gewählt. Bei AES 256 steht die Zahl dagegen für die Schlüsellänge.
    Ich musste übrigens auch erst dahinterkommen, wie man bei Crypt.au3 den Schlüssel direkt angibt und nicht von einem Hash ableitet. Hier die nötigen Funktionen: (PS: MS Crypto hat AES erst seit XP, auf Win2000 geht es also nicht)

    AutoIt
    [autoit]

    #include<Crypt.au3>
    $key = "12345678901234567890123456789012"; // 32 byte key --> AES-256
    $data = "Hello World!1234"
    $IV = '1234567890123456'

    [/autoit] [autoit][/autoit] [autoit]

    _Crypt_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $key = _CryptImportKey($CALG_AES_256, $key, 32)

    [/autoit] [autoit][/autoit] [autoit]

    Const $KP_IV = 1
    _CryptSetKeyParam($key, $KP_IV, $IV, 0, "str")

    [/autoit] [autoit][/autoit] [autoit]

    ; So könnte man den Modus auf ECB stellen, dann wird der IV nicht verwendet,
    ; die Verschlüsselung ist schlechter.
    Const $KP_MODE = 4
    Const $CRYPT_MODE_ECB = 2
    ;~ _CryptSetKeyParam($key, $KP_MODE, $CRYPT_MODE_ECB, 0, "dword*")

    [/autoit] [autoit][/autoit] [autoit]

    $crypt = _Crypt_EncryptData($data, $key, $CALG_USERKEY)
    $crypt = Hex($crypt)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("Encrypted: " & $crypt & @LF)

    [/autoit] [autoit][/autoit] [autoit]

    $decrypt = _Crypt_DecryptData(Binary('0x' & $crypt), $key, $CALG_USERKEY)
    ConsoleWrite("Decrypted: " & BinaryToString($decrypt) & @LF)

    [/autoit] [autoit][/autoit] [autoit]

    _Crypt_DestroyKey($key)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _Crypt_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    Func _CryptImportKey($CALG, $bKey, $iKeyLength = -1)
    ; Author: ProgAndy
    If $iKeyLength < 1 Then $iKeyLength = BinaryLen($bKey)
    Local $blob = DllStructCreate("align 1;BYTE bType;BYTE bVersion;WORD reserved;dword aiKeyAlg;dword keysize;byte key[" & $iKeyLength & "]")
    DllStructSetData($blob, 1, 0x8)
    DllStructSetData($blob, 2, 2)
    DllStructSetData($blob, 4, $CALG)
    DllStructSetData($blob, 5, $iKeyLength)
    DllStructSetData($blob, 6, Binary($bKey))
    Local $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptImportKey", "handle", __Crypt_Context(), "ptr", DllStructGetPtr($blob), "dword", DllStructGetSize($blob), "ptr", 0, "dword", 0, "ptr*", 0)
    If @error Then Return SetError(2, @error, 0)
    Return SetError(Not $aRet[0], 0, $aRet[6])
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _CryptSetKeyParam($hKey, $iParam, $vValue, $iFlags=0, $sValType=Default)
    ; Author: ProgAndy
    If Not $sValType Or $sValType = Default Then $sValType = "ptr"
    Local $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptSetKeyParam", "handle", $hKey, "uint", $iParam, $sValType, $vValue, "dword", $iFlags)
    If @error Then Return SetError(2, @error, 0)
    Return SetError(Not $aRet[0], 0, $aRet[0])
    EndFunc

    [/autoit]
    PHP

    2 Mal editiert, zuletzt von progandy (10. Oktober 2011 um 14:38)

  • :thumbup: Oh man, ein absoluter Traum, ich danke dir vielmals. Ich würd dir dafür gern ein Bier ausgeben ;)

    Der Initialisierungsvektor ist jetzt immer gleich bzw. wird jetzt zwar ausgeschlossen, da aber die Anzahl der zu verschlüssenden Dateien bzw. Strings eher gering ist, gibt es da kein Problem. Das es in Windows 2000 Probleme gibt, steht auch in der Crypt.au3.

    "To provide backwards compatibility with Windows 2000 it will use the PROV_RSA_FULL provider for Win2000 and PROV_RSA_AES for windows xp and higher".

    Einmal editiert, zuletzt von horst290 (10. Oktober 2011 um 14:24)

  • Der Initialisierungsvektor ist jetzt immer gleich bzw. wird jetzt zwar ausgeschlossen


    Wenn du einen variablen IV haben willst, dann musst du diesen beim verschlüsseln erstellen, z.B. im ECB-Modus verschlüsseln und zusätzlich zu den eigentlichen Daten verschicken. Beim entschlüsseln wird dann zuerst der IV entschlüsselt und letztendlich damit dann die eigentlichen Daten.


  • Wenn du einen variablen IV haben willst, dann musst du diesen beim verschlüsseln erstellen, z.B. im ECB-Modus verschlüsseln und zusätzlich zu den eigentlichen Daten verschicken. Beim entschlüsseln wird dann zuerst der IV entschlüsselt und letztendlich damit dann die eigentlichen Daten.


    Ist zu überlegen, da der Standard ansonsten "verletzt" wird, da aber die Anzahl der zu sichernden Dateien eher gering ist, werde ich es wahrscheinlich lassen.