2016-01-24 9 views
2

Я установил библиотеку phpseclib из github, и я пытаюсь зашифровать пароль (для парообмена) с помощью PHP. Я могу сделать это с помощью Javascript, используя код javascript, который Steam имеет на своем сайте, но я не могу зашифровать пароль, используя чистый PHP.Невозможно использовать классы phpseclib

Код шифрования Javascript:

var RSAPublicKey = function($modulus_hex, $encryptionExponent_hex) { 
    this.modulus = new BigInteger($modulus_hex, 16); 
    this.encryptionExponent = new BigInteger($encryptionExponent_hex, 16); 
}; 

var Base64 = { 
    base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/=", 
    encode: function($input) { 
     if (!$input) { 
      return false; 
     } 
     var $output = ""; 
     var $chr1, $chr2, $chr3; 
     var $enc1, $enc2, $enc3, $enc4; 
     var $i = 0; 
     do { 
      $chr1 = $input.charCodeAt($i++); 
      $chr2 = $input.charCodeAt($i++); 
      $chr3 = $input.charCodeAt($i++); 
      $enc1 = $chr1 >> 2; 
      $enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4); 
      $enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6); 
      $enc4 = $chr3 & 63; 
      if (isNaN($chr2)) $enc3 = $enc4 = 64; 
      else if (isNaN($chr3)) $enc4 = 64; 
      $output += this.base64.charAt($enc1) + this.base64.charAt($enc2) + this.base64.charAt($enc3) + this.base64.charAt($enc4); 
     } while ($i < $input.length); 
     return $output; 
    }, 
    decode: function($input) { 
     if(!$input) return false; 
     $input = $input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 
     var $output = ""; 
     var $enc1, $enc2, $enc3, $enc4; 
     var $i = 0; 
     do { 
      $enc1 = this.base64.indexOf($input.charAt($i++)); 
      $enc2 = this.base64.indexOf($input.charAt($i++)); 
      $enc3 = this.base64.indexOf($input.charAt($i++)); 
      $enc4 = this.base64.indexOf($input.charAt($i++)); 
      $output += String.fromCharCode(($enc1 << 2) | ($enc2 >> 4)); 
      if ($enc3 != 64) $output += String.fromCharCode((($enc2 & 15) << 4) | ($enc3 >> 2)); 
      if ($enc4 != 64) $output += String.fromCharCode((($enc3 & 3) << 6) | $enc4); 
     } while ($i < $input.length); 
     return $output; 
    } 
}; 

var Hex = { 
    hex: "abcdef", 
    encode: function($input) { 
     if(!$input) return false; 
     var $output = ""; 
     var $k; 
     var $i = 0; 
     do { 
      $k = $input.charCodeAt($i++); 
      $output += this.hex.charAt(($k >> 4) &0xf) + this.hex.charAt($k & 0xf); 
     } while ($i < $input.length); 
     return $output; 
    }, 
    decode: function($input) { 
     if(!$input) return false; 
     $input = $input.replace(/[^0-9abcdef]/g, ""); 
     var $output = ""; 
     var $i = 0; 
     do { 
      $output += String.fromCharCode(((this.hex.indexOf($input.charAt($i++)) << 4) & 0xf0) | (this.hex.indexOf($input.charAt($i++)) & 0xf)); 
     } while ($i < $input.length); 
     return $output; 
    } 
}; 

var RSA = { 

    getPublicKey: function($modulus_hex, $exponent_hex) { 
     return new RSAPublicKey($modulus_hex, $exponent_hex); 
    }, 

    encrypt: function($data, $pubkey) { 
     if (!$pubkey) return false; 
     $data = this.pkcs1pad2($data,($pubkey.modulus.bitLength()+7)>>3); 
     if(!$data) return false; 
     $data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus); 
     if(!$data) return false; 
     $data = $data.toString(16); 
     if(($data.length & 1) == 1) 
      $data = "0" + $data; 
     return Base64.encode(Hex.decode($data)); 
    }, 

    pkcs1pad2: function($data, $keysize) { 
     if($keysize < $data.length + 11) 
      return null; 
     var $buffer = []; 
     var $i = $data.length - 1; 
     while($i >= 0 && $keysize > 0) 
      $buffer[--$keysize] = $data.charCodeAt($i--); 
     $buffer[--$keysize] = 0; 
     while($keysize > 2) 
      $buffer[--$keysize] = Math.floor(Math.random()*254) + 1; 
     $buffer[--$keysize] = 2; 
     $buffer[--$keysize] = 0; 
     return new BigInteger($buffer); 
    } 
}; 

И зашифровать я просто позвонить по следующему:

var pubKey = RSA.getPublicKey('<?php echo $curl->response->publickey_mod; ?>', '<?php echo $curl->response->publickey_exp; ?>'); 
var encrypted_password = RSA.encrypt('<?php echo $inviter['password']; ?>', pubKey); 

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

Мой код PHP:

<?php 
// publickey_mod = C2242A41A84E56D9CD7952CCB985343A6DCE26AF7CA31036415B7B9DA190DF68BBEC93ED6A9AAE5CA9D6EB1A65244E0013DB38C9462076F8165EDB2A1ECB383A75FB0C71388AFD2C2DC15F9088BA252B4ED2F2C304F545C3704B6B7F5CEE01AF7DD0DC9038CBFBDE7B99689006C5272EBCEC221DB3D9CEB8514E246A571E49709AD94442A8611BE131E6F3FFA40AD632BBD6C5B5F85F7A5C87310E17632145A57BDF17A4F7305E959B4A6126AA8C64C794975F17051E6EAF5462F1189AAD0E7B5F2F254AEEB030D8ED8BAD0F8BD753482E652FFB2405D8947994E143032D5511AF63977A51C9013B5516FA51C5AC50E56588C09C761A473E8D18566B1D435687 

// publickey_exp = 010001 

require_once 'phpseclib/Crypt/RSA.php'; 
require_once 'phpseclib/Crypt/RSA/PKCS1.php'; 

$pkcs = new \phpseclib\Crypt\RSA\PKCS1(); 

$key = $pkcs->savePublicKey(new \phpseclib\Math\BigInteger(C2242A41A84E56D9CD7952CCB985343A6DCE26AF7CA31036415B7B9DA190DF68BBEC93ED6A9AAE5CA9D6EB1A65244E0013DB38C9462076F8165EDB2A1ECB383A75FB0C71388AFD2C2DC15F9088BA252B4ED2F2C304F545C3704B6B7F5CEE01AF7DD0DC9038CBFBDE7B99689006C5272EBCEC221DB3D9CEB8514E246A571E49709AD94442A8611BE131E6F3FFA40AD632BBD6C5B5F85F7A5C87310E17632145A57BDF17A4F7305E959B4A6126AA8C64C794975F17051E6EAF5462F1189AAD0E7B5F2F254AEEB030D8ED8BAD0F8BD753482E652FFB2405D8947994E143032D5511AF63977A51C9013B5516FA51C5AC50E56588C09C761A473E8D18566B1D435687, 16), new \phpseclib\Math\BigInteger(010001, 16)); 

$rsa = new phpseclib\Crypt\RSA(); 

$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1); 
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1); 

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); 
define('CRYPT_RSA_PKCS15_COMPAT', true); 
$rsa->loadKey($key); 

$password = $rsa->encrypt("mySteamPassword"); // encrypting password 

var_dump($password); 

?> 

И сообщение об ошибке, что этот код выводит:

Fatal error: Class 'phpseclib\Crypt\RSA\PKCS' not found in C:\xampp\htdocs\RSA-Encryption\phpseclib\Crypt\RSA\PKCS1.php on line 40 
+0

Просьба указать код и текст ошибки. – Will

+0

@ При добавлении сообщения об ошибке и кода, я надеюсь, что это поможет вам помочь мне;) – Acidic

+0

Только главная ветвь имеет файл PKCS1.php. Вы должны использовать ветви 1.0 или 2.0, так как они имеют стабильный API. API-интерфейс мастер-филиала может и, вероятно, сильно изменится с течением времени. Как только главная ветка получит версию с версией - например. 3.0 или некоторые из них - вы можете использовать версию 3.0, но никогда не следует использовать главную ветку. – neubert

ответ

1

Смотрите эту часть?

require_once 'phpseclib/Crypt/RSA.php'; 
require_once 'phpseclib/Crypt/RSA/PKCS1.php'; 

Вы явно включая конкретные классы, которые зависят от других классов, но не включая их непосредственно. Правильное решение состоит в том, чтобы вместо ввода в require_once инструкций использовать автозагрузчик.

Если вы загружаете эту библиотеку composer, это очень просто.

  1. Run composer require phpseclib/phpseclib
  2. Добавить require_once 'vendor/autoload.php'; ваших PHP скриптов.

В противном случае, вам нужно использовать spl_autoload_register() вместо:

/** 
* Register a PSR autoloader for a given namespace and directory 
* 
* @param string $namespace 
* @param string $dir 
* @param string $type ('psr0' or 'psr4') 
* @return boolean 
* @throws Exception 
* @ref http://stackoverflow.com/a/35015933/2224584 
*/ 
function generic_autoload($namespace, $dir, $type = 'psr4') 
{ 
    switch ($type) { 
     case 'psr0': 
      $spl = '_'; 
      break; 
     case 'psr4': 
      $spl = '\\'; 
      break; 
     default: 
      throw new Exception('Invalid type; expected "psr0" or "psr4"'); 
    } 
    $ns = trim($namespace, DIRECTORY_SEPARATOR.$spl); 

    return spl_autoload_register(
     function($class) use ($ns, $dir, $spl) 
     { 
      // project-specific namespace prefix 
      $prefix = $ns.$spl; 

      // base directory for the namespace prefix 
      $base_dir = $dir . DIRECTORY_SEPARATOR; 

      // does the class use the namespace prefix? 
      $len = strlen($prefix); 
      if (strncmp($prefix, $class, $len) !== 0) { 
       // no, move to the next registered autoloader 
       return; 
      } 

      // get the relative class name 
      $relative_class = substr($class, $len); 

      // replace the namespace prefix with the base directory, replace 
      // namespace separators with directory separators in the relative 
      // class name, append with .php 
      $file = $base_dir . 
       str_replace($spl, DIRECTORY_SEPARATOR, $relative_class) . 
       '.php'; 

      // if the file exists, require it 
      if (file_exists($file)) { 
       require $file; 
      } 
     } 
    ); 
} 

Использование:

generic_autoload('phpseclib', '/path/to/phpseclib', 'psr4'); 

Слово предостережения:Make sure you aren't using PKCS1v1.5 padding for RSA encryption. Если вы собираетесь использовать RSA, вы должны использовать RSAES-OAEP with MGF1+SHA256 and e = 65537. Я знаю, что phpseclib поддерживает это; если сообщество Steam не делает, поднимайте ад, пока они не сделают это.

+1

Удивительный, спасибо за ответ чувак. На самом деле, я уверен, что другие тоже узнают об этом. – Acidic