Что не так с этим классом PHP4 для шифрования AES? - PullRequest
1 голос
/ 10 февраля 2010

Когда я расшифровываю что-то зашифрованное с помощью этой функции, дешифрованная версия не совпадает с оригинальной.

 class AES256encryption {

    var $secret = '';
    var $cipher_key = '';

    function AES256encryption($secret='') {
        if (empty($secret)) {
            global $secret;         
            if (empty($secret)) {
                $secret = "some random secret string";
            }
        }
        $this->secret = $secret;
    }

    function gen_cipher() {
        if (empty($this->cipher_key)) {
            $this->cipher_key = substr(sha1($this->secret),0,20);
        }
    }
    function mciv() {
        return mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
    }
    function encrypt($text) {
        $this->gen_cipher();
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $text, MCRYPT_MODE_CBC, $this->mciv()))); 
    }
    function decrypt($text) {
        $this->gen_cipher();
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($text), MCRYPT_MODE_CBC, $this->mciv())); 
    }
}

Ответы [ 3 ]

4 голосов
/ 11 февраля 2010

Не создавайте новый IV каждый раз, когда вы хотите что-то зашифровать / расшифровать. Вам нужен тот же IV во время шифрования и дешифрования. В режиме CBC нет необходимости получать секрет IV, если он случайный при его создании. Поэтому ваш код должен выглядеть примерно так:

class AES256encryption {

    var $secret = '';
    var $cipher_key = '';
    var $mciv = NULL;

    function AES256encryption($secret='') {
        if (empty($secret)) {
            global $secret;⋅⋅⋅⋅⋅⋅⋅⋅⋅
            if (empty($secret)) {
                $secret = "some random secret string";
            }
        }
        $this->secret = $secret;
        $this->gen_mciv();
    }   

    function gen_cipher() {
        if (empty($this->cipher_key)) {
            $this->cipher_key = substr(sha1($this->secret),0,20);
        }   
    }   

    function gen_mciv() {
        if(NULL === $this->mciv)
        {
            $this->mciv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
        }   
    }   

    function encrypt($text) {
        $this->gen_cipher();
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $text, MCRYPT_MODE_CBC, $this->mciv)));
    }   
    function decrypt($text) {
        $this->gen_cipher();
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($text), MCRYPT_MODE_CBC, $this->mciv));
    }   
}   



$ac = new AES256encryption('my secret pass');
$z = $ac->encrypt('test');
var_dump($z);
$u = $ac->decrypt($z);
var_dump($u);

И это похоже на работу:

mycroft:~ $ php test_aes.php 
string(44) "+KRlfrPp37FfwB4gJXQ67X+8bjbjxEFHjOn55YOgU5o="
string(4) "test"

Пожалуйста, отметьте режим работы блочного шифра , который возобновляет работу.

2 голосов
/ 15 февраля 2010

IV необходимо отправить получателю вместе с зашифрованными данными. Это означает, что ваша encrypt функция должна будет закодировать и отправить ее в base64, а ваша decrypt функция должна ожидать ее получения как части ввода.

1 голос
/ 16 февраля 2010

Основываясь на помощи Патрика и кафе, я пересмотрел свой класс. Я обнаружил, что и секрет, и IV должны быть такими же в расшифровке, как и при шифровании, иначе расшифровка не будет работать. IV должен быть 32 символа. Вот мой пересмотренный класс на случай, если он кому-нибудь пригодится.

class AES256 {

    var $secret = 'some string of any length'; // some random string of any length
    var $iv = '0v6bJhPYe2TElCUrT{TD-drLH(5y4pQj'; // must be 32 chars
    var $cipher_key = '';

    function AES256($secret='', $iv='') {
        if (!empty($secret)) {
            $this->secret = $secret;
        }
        $this->cipher_key = substr(sha1($this->secret),0,20);
        if (!empty($iv) && (strlen($iv) == 32)) {
            $this->iv = $iv;
        }
     }
    function encrypt($plaintext) {
         return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, $plaintext, MCRYPT_MODE_CBC, $this->iv))); 
    }
    function decrypt($ciphertext) {
         return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->cipher_key, base64_decode($ciphertext), MCRYPT_MODE_CBC, $this->iv)); 
    }
}

$r = array();

$ac = new AES256('some string of any length');
$r['ciphertext'] = $ac->encrypt(',23ln1gQ6-3ZY[JI');
$r['plaintext'] = $ac->decrypt("wdkUJRR1qxXLkeseVfiLhKnXsAiVzx4H2ytj+2BFRlo=");
print_r($r);
...