Проблема кодировки PHP, но только с char T, по крайней мере, это мое предположение - PullRequest
0 голосов
/ 25 декабря 2011

Я опубликовал этот класс в разных местах, но теперь нашел ошибку.Это стало очень популярным, поэтому мне было интересно, если кто-то может помочь мне разобраться в этом.Я был на нем часами, и обнаружил, что в 99% случаев проблема связана с буквой T в нижнем и верхнем регистре. Я пробовал использовать другую кодировку, а переменную t изменили на другой символ.но это всегда только такие швы.

Класс

<?php
/**
 * An open source PHP library collection
 *
 * @category     RoboTamer
 * @author       Dennis T Kaplan
 * @copyright    Copyright (c) 2008 - 2011, Dennis T Kaplan
 * @license      http://www.RoboTamer.com/license.html
 * @link         http://www.RoboTamer.com
 **/

/**
 * RTCrypt
 *
 * RTCrypt allows for encryption and decryption on the fly using
 * a simple but effective method.
 *
 * RTCrypt does not require mcrypt, mhash or any other PHP extension,
 * it uses only PHP.
 *
 * @category     RoboTamer
 * @package      RTCrypt
 * @author       Dennis T Kaplan
 * @copyright    Copyright (c) 2011, Dennis T Kaplan
 * @license      http://www.RoboTamer.com/license.html
 * @link         http://www.RoboTamer.com
 **/
class RTCrypt
{
    const streight = '012345679ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    private $scramble1 = NULL;
    private $scramble2 = NULL;

    public function __construct()
    {
        $this->setScramble1();
    }

    public function __destruct(){}

    public function getStreight()
    {
        return self::streight;
    }

    public function getScramble1()
    {
        return implode($this->scramble1);
    }

    public function getScramble2()
    {
        return implode($this->scramble2);
    }

    /**
     * Set the characters you like to replace
     *
     * @access  private
     * @param   string $str
     */
    private function setScramble1()
    {
        $this->scramble1 = str_split(self::streight);
    }

    /**
     * This is your private key.
     * You can generate a random private key based on scramble1 via
     * the randomizeString($scramble1) function.
     *
     * @access  public
     * @param   string $str
     * @return  bool TRUE
     */
    public function setScramble2($str=NULL)
    {
        if($str===NULL){
            trigger_error('No key, use genKey($str)', E_USER_ERROR );
            die;
        }
        $this->scramble2 = str_split($str);
        return TRUE;
    }

    /**
     * This will encrypt your data
     *
     * @access  public
     * @param   string $str
     * @return  string encrypt data
     */
    public function encrypt($str)
    {
        if($this->scramble2 === NULL) $this->setScramble2();
        $str = base64_encode($str);
        $len = strlen($str);
        $newstr='';
        for($i=0; $i < $len;$i++){
            $r = substr($str, -1);
            $str = substr($str, 0, -1);
            $an = array_search($r,$this->scramble1);
            if($an > 0){
                $newstr .= $this->scramble2[$an];
            }else{
                $newstr .= $r;
            }
        }
        return $newstr;
    }

    /**
     * This will decrypt a Crypted string back to the original data
     *
     * @access  public
     * @param   string $str
     * @return  string
     */
    public function decrypt($str)
    {
        if($this->scramble2 === NULL) $this->setScramble2();
        $len = strlen($str);
        $newstr='';
        for($i=0; $i < $len;$i++){
            $r = substr($str, -1);
            $str = substr($str, 0, -1);
            $an = array_search($r,$this->scramble2);
            if($an > 0){
                $newstr .= $this->scramble1[$an];
            }else{
                $newstr .= $r;
            }
        }
        $str = base64_decode($newstr);
        return $str;
    }

    /**
     * Generates your private key.
     * You would use it to set scramble2
     * Keep it save!
     *
     * @access  public
     * @return  string
     */
    public function genKey()
    {
        $array = str_split(self::streight);
        shuffle($array);
        return implode($array);
    }
}
?>

Тестовый скрипт:

define('BR',"\n");
Locale::setDefault('en-US');

include 'RTCrypt.php';

$Crypter = new RTCrypt();
$key = $Crypter->genKey();
echo BR.'Your Key: '.BR.$Crypter->getStreight().BR.$key.BR.BR;
$Crypter->setScramble2($key);

$str = '/**
 * encode, decode and also serialize when nessesery.
 * Works with anything that php can serialize.
 * string, array, etc.
 *
 * @category     RoboTaMeR
 * @package      Strsafe
 * @author       Dennis T Kaplan
 * @copyright    Copyright (c) 2008 - 2011, Dennis T Kaplan
 * @license      http://RoboTamer.com/license.html
 * @link         http://RoboTamer.com
 * @todo         combine this with RTCrypt to one class
 */';
echo 'String before RTCrypt: '.BR.$str.BR.BR;

//echo BR.base64_encode($str).BR.BR;

$str = $Crypter->encrypt($str);
echo 'RTCrpted: '.$str.BR.BR;
echo 'String after RTCrypt: '.BR.$Crypter->decrypt($str);
echo BR.BR;
?>

Строка до RTCrypt:

/**
 * encode, decode and also serialize when nessesery.
 * Works with anything that php can serialize.
 * string, array, etc.
 *
 * @category     RoboTaMeR
 * @package      Strsafe
 * @author       Dennis T Kaplan
 * @copyright    Copyright (c) 2008 - 2011, Dennis T Kaplan
 * @license      http://RoboTamer.com/license.html
 * @link         http://RoboTamer.com
 * @todo         combine this with RTCrypt to one class
 */

Строка после RTCrypt:

/**
 * encode, decode and also serialize when nessesery.
 * Works wich anyching chac php can serialize.
 * string, array, etc.
 *
 * @category     RoboTaMeR
 * @package      Strsafe
 * @auchor       Dennis T Kaplan
 * @copyrighc    Copyright (c) 2008 - 2011, Dennis T Kaplan
 * @license      hctp://RoboTamer.com/license.html
 * @link         hctp://RoboTamer.com
 * @codo         combine chis with RTCrypt co one class
 */

Ответы [ 2 ]

3 голосов
/ 25 декабря 2011

Единственное, о чем я могу думать:

if($an > 0){

Может быть ключ в индексе 0. Вы должны проверить на FALSE, используя:

if ($an !== FALSE)
1 голос
/ 25 декабря 2011

Даже когда эта ошибка исправлена, ваш код совершенно небезопасен.Я сразу вижу три недостатка:

  1. Это шифр замещения.Древний метод, который очень слабый.Подсчет частоты символов - это простой способ победить его.Использование Base64 несколько усложняет атаку, но не сильно.=> Разбит по конструкции.

  2. Несколько символов в выводе Base64 всегда будут отображаться на себя.А именно +, /, 8 (похоже, вы просто забыли об этом в своей строке) и =.Отображение идентификатора = является приемлемым, поскольку это только маркер конца строки, но остальные три являются недостатками безопасности.

  3. Вы используете shuffle для созданиязакрытый ключ.shuffle не предназначен для криптографических целей и поэтому, вероятно, использует слабый генератор случайных чисел.Я не удивлюсь, если он будет сопоставлен с c RNG, который имеет только 32-битное начальное число.Это означало бы, что существует всего 4 миллиарда различных ключей, что тривиально для грубой силы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...