Что нового

[Криптография] Функции шифрования AES128, AES192, AES256 (CBC) совместимые с PHP OpenSSL

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Категория: Кодирование, Шифрование, Microsoft Cryptographic Service Provider, OpenSSL, openssl_encrypt, openssl_decrypt, php, AES, Rijndael

Описание:
Библиотека предназначена для шифрования текста симметричным алгоритмом блочного шифрования (размер блока 128 бит, ключ 128/192/256 бит) с использованием пользовательского пароля.
Функции используют для шифрования Microsoft Cryptographic Service Provider в AutoIt и стандартную библиотеку OpenSSL в PHP.

Особенности:
  • Библиотека не имеет внешних зависимостей.
  • Работает с текстом в кодировке UTF-8
  • Шифрованные данные преобразовывает в формат Base64 для удобной передачи по сети
  • Использует Microsoft API для шифрования/дешифрирование
  • Ключ формируется на основе пользовательского пароля и алгоритма SHA256
  • В отличии от _Crypt_DecryptData использует начальный вектор инициализации (Initialization vector (IV))

Функции:
Код:
;Функция шифрования (Данные, пароль, алгоритм)
_CryptPhp_EncryptString($sData, $sCode[, $sAlgo = 'AES-192-CBC'])
;Функция дешифрирования (Данные, пароль, алгоритм)
_CryptPhp_DecryptString($sData, $sCode[, $sAlgo = 'AES-192-CBC'])



Пример:
Код:
#include "CryptPhp.au3"
Local $sData = 'A pointer to a DWORD value that indicates the length of the pbData buffer.'
Local $sCode = '123_MyPassword!'

Local $sEncrypted = _CryptPhp_EncryptString($sData, $sCode)
ConsoleWrite(@error & ' ' & @extended & ' ' & $sEncrypted & @CRLF)

Local $sDecrypted = _CryptPhp_DecryptString($sEncrypted, $sCode)
ConsoleWrite(@error & ' ' & @extended & ' ' & $sDecrypted & @CRLF)


PHP класс:
PHP:
class CryptPhp
{
    private $cipherAlgorithm;
    private $hashAlgorithm;
    private $iv_num_bytes;

    public function __construct($cipherAlgorithm = 'AES-192-CBC')
    {
        $this->cipherAlgorithm = $cipherAlgorithm;
        $this->hashAlgorithm = 'SHA256';
        $this->iv_num_bytes = openssl_cipher_iv_length($cipherAlgorithm);

        if ( ! in_array($cipherAlgorithm, openssl_get_cipher_methods(true))) {
            throw new \Exception("CryptPhp:: - unknown cipher algo {$cipherAlgorithm}");
        }

        if ( ! in_array($this->hashAlgorithm, openssl_get_md_methods(true))) {
            throw new \Exception("CryptPhp:: - unknown hash algo {$this->hashAlgorithm}");
        }
    }

    public function encryptString($in, $key)
    {
        $iv = mcrypt_create_iv($this->iv_num_bytes, MCRYPT_DEV_URANDOM);
        $hash = openssl_digest($key, $this->hashAlgorithm, true);
        $encrypted = openssl_encrypt($in, $this->cipherAlgorithm, $hash, OPENSSL_RAW_DATA, $iv);
        if ($encrypted === false) {
            throw new \Exception('CryptPhp::encryptString - Encryption failed: ' . openssl_error_string());
        }
        return base64_encode($iv . $encrypted);
    }

    public function decryptString($in, $key)
    {
        $raw = base64_decode($in);
        if (strlen($raw) < $this->iv_num_bytes) {
            throw new \Exception('CryptPhp::decryptString - ' .
                'data length ' . strlen($raw) . " is less than iv length {$this->iv_num_bytes}");
        }
        $iv = substr($raw, 0, $this->iv_num_bytes);
        $raw = substr($raw, $this->iv_num_bytes);
        $hash = openssl_digest($key, $this->hashAlgorithm, true);
        $res = openssl_decrypt($raw, $this->cipherAlgorithm, $hash, OPENSSL_RAW_DATA, $iv);
        if ($res === false) {
            throw new \Exception('CryptPhp::decryptString - decryption failed: ' . openssl_error_string());
        }
        return $res;
    }
}

PHP пример:
PHP:
$data = 'A pointer to a DWORD value that indicates the length of the pbData buffer.';
$code = '123_MyPassword!';

$crypt = new CryptPhp();
$encrypted = $crypt->encryptString($data, $code);
$decrypted = $crypt->decryptString($encrypted, $code);

echo "encrypted => $encrypted\n";
echo "decrypted => $decrypted\n";

Примечание: Для Windows XP вместо SHA256 используйте SHA1

Файл: Скачать CryptPhp.au3

Источник: autoit-script.ru
Автор(ы): inververs
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
964
inververs
1. Я так понимаю, PHP код для примера совместимости?
2. Почему CryptPhp? Как следствие, вытекающие из пункта 1?
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Garrett
Да, тут php для того, что бы показать, как это делать именно на php, что бы полученный результат был совместим.
Я показал необходимый минимум для этих функций, где используется вектор инициализации, хэширование ключа, пароль и сам текст.
Результат я отдаю как iv + данные и кодирую в base64, т.к везде(в любом языке) должны быть функции для работы с ним.

Хочу отметить, что подходы к шифрованию текста могут отличаться. Например, в результат может быть подмешена соль, или ключ может быть сформирован по другим алгоритмам, поэтому нужно обращать внимание на используемый подход в вашем фреймворке или библиотеке.
 
A

Alofa

Гость
Спасибо, возьму в копилку.
Но ИМХО, я думаю куда привычней и правильней задавать алгоритмы "AES-128-CBC", "AES-192-CBC" и "AES-256-CBC" объявленными константами.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Alofa
Вы можете в код дописать так:
Код:
Switch $sAlgo
		Case 'AES-128-CBC', 0x0000660e
			$iAlg = 0x0000660e ;$CALG_AES_128
...

и тогда алгоритм можно будет передать константой
 

joiner

Модератор
Локальный модератор
Сообщения
3,434
Репутация
600
inververs, :ok:
OffTopic:
было бы замечательно, если бы в описаниях был и русский язык.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
joiner
:rolleyes: хотелось бы. Но как 2 языка сделать?
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
964
inververs
OffTopic:

[?]
хотелось бы. Но как 2 языка сделать?
Я задумывался над этим вопросом, но так всё в тестовых вариантах и осталось. С обновлением GUI у меня что-то не клеилось (не менялся язык после перерисовки gui, только после перезагрузки программы).

Задумка следующая, создать программу для просмотра UDF и желающий сделать перевод может редактировать языковой файл.
Как вариант можно попробовать.
 

Webarion

Осваивающий
Сообщения
135
Репутация
22
У меня указанный код почему-то не расшифровывает. Выдаёт:

Код:
0 0 J5kT/MPbHFvqCGEzJrm2EVt73JFGlkHaol7M3symEpdYhggHAnlUhNIqptmnVjt47FyeO7bk6SvuP9l1xpvomBXB1XPLAf3fN5sJhRrZbA1t+RO9s5fyLz+0b5Wjg7Jc
9 0 False

В библиотеке это следующие строки:
Код:
;Determinate buffer size
		$aRet = DllCall($hAdvapi32, "bool", "CryptDecrypt", "handle", $hKey, "handle", 0, "bool", True, "dword", 0, _
			"struct*", Null, "dword*", BinaryLen($bEncrypted))
		If @error Or Not $aRet[0] Then ExitLoop SetError(9, @error, 1)


Подскажите пожалуйста с чем это связано, как исправить?
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Вот этот код можете комментировать
Код:
;Determinate buffer size
;~ 		$aRet = DllCa1ll($hAdvapi32, "bool", "CryptDecrypt", "handle", $hKey, "handle", 0, "bool", True, "dword", 0, _
;~ 			"struct*", Null, "dword*", BinaryLen($bEncrypted))
;~ 		If @error Or Not $aRet[0] Then ExitLoop SetError(9, @error, 1)

А чуть ниже поменяйте так:
Код:
;Create buffer
		Local $hBuffCipherText = DllStructCreate('byte[' & BinaryLen($bEncrypted) & ']')
		DllStructSetData($hBuffCipherText, 1, $bEncrypted)

		;Decrypt
		$aRet = DllCall($hAdvapi32, "bool", "CryptDecrypt", "handle", $hKey, "handle", 0, "bool", True, "dword", 0, _
			"struct*", $hBuffCipherText, "dword*", DllStructGetSize($hBuffCipherText))
		If @error Or Not $aRet[0] Then ExitLoop SetError(10, @error, 1)

Так должно заработать
 

Webarion

Осваивающий
Сообщения
135
Репутация
22
Появляется msgbox с заголовком 87 и текстом 80 Параметр задан неверно. У меня Win7.


Добавлено:
Сообщение автоматически объединено:

inververs сказал(а):
Вот этот код можете комментировать
Код:
;Determinate buffer size
;~ 		$aRet = DllCa1ll($hAdvapi32, "bool", "CryptDecrypt", "handle", $hKey, "handle", 0, "bool", True, "dword", 0, _
;~ 			"struct*", Null, "dword*", BinaryLen($bEncrypted))
;~ 		If @error Or Not $aRet[0] Then ExitLoop SetError(9, @error, 1)

А чуть ниже поменяйте так:
Код:
;Create buffer
		Local $hBuffCipherText = DllStructCreate('byte[' & BinaryLen($bEncrypted) & ']')
		DllStructSetData($hBuffCipherText, 1, $bEncrypted)

		;Decrypt
		$aRet = DllCall($hAdvapi32, "bool", "CryptDecrypt", "handle", $hKey, "handle", 0, "bool", True, "dword", 0, _
			"struct*", $hBuffCipherText, "dword*", DllStructGetSize($hBuffCipherText))
		If @error Or Not $aRet[0] Then ExitLoop SetError(10, @error, 1)

Так должно заработать

Да, так заработало! Благодарю Вас!
В чём же тут была причина, можете рассказать?
 

robinhood3

Новичок
Сообщения
1
Репутация
0
привет, я пытаюсь скачать файл "CryptPhp.au3" ", но это возвращает меня к началу форума. Вы можете мне помочь?
 

sosopi

Новичок
Сообщения
5
Репутация
0
Привет всем , а aes256 gcm есть вообще для autoit ?
 
Верх