Home > Mobile >  "Class name must be a valid object or a string" When Installing PHPSecLib Without Composer
"Class name must be a valid object or a string" When Installing PHPSecLib Without Composer

Time:12-19

I'm trying to do RSA encryption using PHPSecLib, with a manual install (ie not using Composer).

I'm following these manual installation instructions I found here: https://davescripts.com/manual-installation-of-phpseclib

And trying to do this example which I located here: How to Decrypt RSA OAEP with SHA256 using openssl on PHP

My steps I've taken so far:

  1. Visited the GitHub repository here: https://github.com/phpseclib/phpseclib/tree/3.0

  2. Under 'Code' selected 'Download ZIP'.

  3. Unzipped the files locally and uploaded the entire 'phpseclib' directory to the server.

  4. Created a test script, and troubleshooted multiple layers of includes and use that were needed to get it working.

  5. However, at the moment, I'm getting a new error - "Class name must be a valid object or a string" which I don't understand and can't seem to resolve.

My test script is now as follows:

<?php

  ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
  header("Content-Type: text/plain");
  $sIncludePath = get_include_path() . PATH_SEPARATOR . '../inc/phpseclib';
  echo $sIncludePath."\n";
  set_include_path($sIncludePath);

  include('Crypt/Common/AsymmetricKey.php');
  include('Math/BigInteger.php');
  include('Crypt/EC.php');
  include('Crypt/PublicKeyLoader.php');
  include('Crypt/RSA.php');

  use phpseclib3\Crypt\RSA;
  use phpseclib3\Crypt\PublicKeyLoader;

  function rsaEncryptionOaepSha256 ($publicKey, $plaintext) {
    $rsa = PublicKeyLoader::load($publicKey)
        ->withHash('sha256')
        ->withMGFHash('sha256');
    return $rsa->encrypt($plaintext);
  }

  function rsaDecryptionOaepSha256 ($privateKey, $ciphertext) {
    $rsa = PublicKeyLoader::load($privateKey)
        ->withHash('sha256')
        ->withMGFHash('sha256');
    return $rsa->decrypt($ciphertext);
  }
  
  function loadRsaPrivateKeyPem() {
    // this is a sample key - don't worry !
    return '
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDwSZYlRn86zPi9
e1RTZL7QzgE/36zjbeCMyOhf6o/WIKeVxFwVbG2FAY3YJZIxnBH 9j1XS6f ewjG
FlJY4f2IrOpS1kPiO3fmOo5N4nc8JKvjwmKtUM0t63uFFPfs69 7mKJ4w3tk2mSN
4gb8J9P9BCXtH6Q78SdOYvdCMspA1X8eERsdLb/jjHs8 gepKqQ6 XwZbSq0vf2B
MtaAB7zTX/Dk ZxDfwIobShPaB0mYmojE2YAQeRq1gYdwwO1dEGk6E5J2toWPpKY
/IcSYsGKyFqrsmbw0880r1BwRDer4RFrkzp4zvY kX3eDanlyMqDLPN ghXT1lv8
snZpbaBDAgMBAAECggEBAIVxmHzjBc11/73bPB2EGaSEg5UhdzZm0wncmZCLB453
XBqEjk8nhDsVfdzIIMSEVEowHijYz1c4pMq9osXR26eHwCp47AI73H5zjowadPVl
uEAot/xgn1IdMN/boURmSj44qiI/DcwYrTdOi2qGA jD4PwrUl4nsxiJRZ/x7PjL
hMzRbvDxQ4/Q4ThYXwoEGiIBBK/iB3Z5eR7lFa8E5yAaxM2QP9PENBr/OqkGXLWV
qA/YTxs3gAvkUjMhlScOi7PMwRX9HsrAeLKbLuC1KJv1p2THUtZbOHqrAF/uwHaj
ygUblFaa/BTckTN7PKSVIhp7OihbD04bSRrh nOilcECgYEA/8atV5DmNxFrxF1P
ODDjdJPNb9pzNrDF03TiFBZWS4Q 2JazyLGjZzhg5Vv9RJ7VcIjPAbMy2Cy5BUff
EFE 8ryKVWfdpPxpPYOwHCJSw4Bqqdj0Pmp/xw928ebrnUoCzdkUqYYpRWx0T7YV
RoA9RiBfQiVHhuJBSDPYJPoP34kCgYEA8H9wLE5L8raUn4NYYRuUVMa 1k4Q1N3X
Bixm5cccc/Ja4LVvrnWqmFOmfFgpVd8BcTGaPSsqfA4j/oEQp7tmjZqggVFqiM2m
J2YEv18cY/5kiDUVYR7VWSkpqVOkgiX3lK3UkIngnVMGGFnoIBlfBFF9uo02rZpC
5o5zebaDImsCgYAE9d5wv0 nq7/STBj4NwKCRUeLrsnjOqRriG3GA/TifAsX jw8
XS2VF PRLuqHhSkQiKazGr2Wsa9Y6d7qmxjEbmGkbGJBC AioEYvFX9TaU8oQhvi
hgA6ZRNid58EKuZJBbe/3ek4/nR3A0oAVwZZMNGIH972P7cSZmb/uJXMOQKBgQCs
FaQAL 4sN/TUxrkAkylqF QJmEZ26l2nrzHZjMWROYNJcsn8/XkaEhD4vGSnazCu
/B0vU6nMppmezF9Mhc112YSrw8QFK5GOc3NGNBoueqMYy1MG8Xcbm1aSMKVv8xba
rh BZQbxy6x61CpCfaT9hAoA6HaNdeoU6y05lBz1DQKBgAbYiIk56QZHeoZKiZxy
4eicQS0sVKKRb24ZUd 04cNSTfeIuuXZrYJ48Jbr0fzjIM3EfHvLgh9rAZ aHe/L
84Ig17KiExe qyYHjut/SC0wODDtzM/jtrpqyYa5JoEpPIaUSgPuTH/WhO3cDsx6
3PIW4/CddNs8mCSBOqTnoaxh
-----END PRIVATE KEY-----
';
  }

  function loadRsaPublicKeyPem() {
    // this is a sample key - don't worry !
    return '
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8EmWJUZ/Osz4vXtUU2S 
0M4BP9 s423gjMjoX qP1iCnlcRcFWxthQGN2CWSMZwR/vY9V0un/nsIxhZSWOH9
iKzqUtZD4jt35jqOTeJ3PCSr48JirVDNLet7hRT37Ovfu5iieMN7ZNpkjeIG/CfT
/QQl7R kO/EnTmL3QjLKQNV/HhEbHS2/44x7PPoHqSqkOvl8GW0qtL39gTLWgAe8
01/w5PmcQ38CKG0oT2gdJmJqIxNmAEHkatYGHcMDtXRBpOhOSdraFj6SmPyHEmLB
ishaq7Jm8NPPNK9QcEQ3q ERa5M6eM72PpF93g2p5cjKgyzzfoIV09Zb/LJ2aW2g
QwIDAQAB
-----END PUBLIC KEY-----
';
  }

  function base64Encoding ($input) {
    return base64_encode($input);
  }
  function base64Decoding ($input) {
    return base64_decode($input);
  }

  echo 'RSA 2048 encryption OAEP SHA-256 string' . PHP_EOL;
  $sDataToEncrypt = "The quick brown fox jumps over the lazy dog";
  echo 'plaintext: ' . $sDataToEncrypt . PHP_EOL;

  // encryption
  echo PHP_EOL . '* * * encrypt the plaintext with the RSA public key * * *' .PHP_EOL;
  $ciphertextBase64 = base64Encoding(rsaEncryptionOaepSha256(loadRsaPublicKeyPem(), $sDataToEncrypt));
  echo 'ciphertextBase64: ' . $ciphertextBase64 . PHP_EOL;

  // transport the encrypted data to recipient

  // receiving the encrypted data, decryption
  echo PHP_EOL . '* * * decrypt the ciphertext with the RSA private key * * *' .PHP_EOL;
  $ciphertextReceivedBase64 = $ciphertextBase64;
  echo 'ciphertextReceivedBase64: ' . $ciphertextReceivedBase64 . PHP_EOL;
  $decryptedtext = rsaDecryptionOaepSha256(loadRsaPrivateKeyPem(), base64Decoding($ciphertextReceivedBase64));
  echo 'decryptedtext: ' . $decryptedtext . PHP_EOL;

?>

However, when I attempt to run this PHP code, I receive the following output which has me stuck:

.:/opt/alt/php70/usr/share/pear:../inc/phpseclib
RSA 2048 encryption OAEP SHA-256 string
plaintext: The quick brown fox jumps over the lazy dog

* * * encrypt the plaintext with the RSA public key * * *
<br />
<b>Fatal error</b>:  Uncaught Error: Class name must be a valid object or a string in /home/.../inc/phpseclib/Math/BigInteger.php:182
Stack trace:
#0 /home/.../inc/phpseclib/Crypt/Common/AsymmetricKey.php(143): phpseclib3\Math\BigInteger-&gt;__construct(0)
#1 /home/.../inc/phpseclib/Crypt/Common/AsymmetricKey.php(162): phpseclib3\Crypt\Common\AsymmetricKey::initialize_static_variables()
#2 /home/.../inc/phpseclib/Crypt/PublicKeyLoader.php(45): phpseclib3\Crypt\Common\AsymmetricKey::load('\r\n-----BEGIN PU...', false)
#3 /home/.../main/phpseclibtest.php(19): phpseclib3\Crypt\PublicKeyLoader::load('\r\n-----BEGIN PU...')
#4 /home/.../main/phpseclibtest.php(94): rsaEncryptionOaepSha256('\r\n-----BEGIN PU...', 'The quick brown...')
#5 {main}
  thrown in <b>/home/.../inc/phpseclib/Math/BigInteger.php</b> on line <b>182</b><br />

In case it helps, note that the test script is in a separate directory like this:

inc
-> phpseclib (the PHPSecLib library with all subdirectories)
main
-> phpseclibtest.php (my test script)

The PHP version is 7.0.33, if that makes any difference.

I'd really like to figure out how to get PHPSecLib working. If someone could help me figure out what's going on that would be awesome.

CodePudding user response:

You're trying to install phpseclib v3 using the instructions for phpseclib v2. There are two options:

Option 1: Use PHPSecLib V3 With Composer

This option requires SSH access on the server.

To install phpseclib v3 you're gonna need Composer. Once you have that installed you can do composer init and then composer require phpseclib/phpseclib:~3.0.

By doing that you can replace this:

  ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
  header("Content-Type: text/plain");
  $sIncludePath = get_include_path() . PATH_SEPARATOR . '../inc/phpseclib';
  echo $sIncludePath."\n";
  set_include_path($sIncludePath);

  include('Crypt/Common/AsymmetricKey.php');
  include('Math/BigInteger.php');
  include('Crypt/EC.php');
  include('Crypt/PublicKeyLoader.php');
  include('Crypt/RSA.php');

With this:

require __DIR__ . '/vendor/autoload.php'; 

Once you do that phpseclib v3 should work without a hitch. The issue you're having is due to the fact that phpseclib v3 is trying to autoload the engine, which it can't do because there's no autoloader.

Note that SSH is not required to use your resulting code once you have it working. To get PHPSecLib v3 to work for people without SSH, what you could do is locally do composer init and then composer require phpseclib/phpseclib:3.0 and then take your vendor directory and your composer.json and composer.lock file and put it into whatever project you want to. ie. end users wouldn't be running composer - you would be running composer. You would be downloading the dependencies and they'd just be using the dependencies you downloaded!

Option 2: Use PHPSecLib2 Manually

This option doesn't require SSH. PHPSecLib2 has less features than PHPSecLib3, however it's still actively maintained. (Even PHPSecLib1 receives regular updates.)

PHPSecLib2 doesn't have the PublicKeyLoader class, so you would use the RSA class instead as follows:

<?php

  ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
  header("Content-Type: text/plain");
  $sIncludePath = get_include_path() . PATH_SEPARATOR . '../s/phpseclib';
  echo $sIncludePath."\n";
  set_include_path($sIncludePath);

  include('Math/BigInteger.php');
  include('Crypt/RSA.php');
  include('Crypt/Hash.php');
  include('Crypt/Random.php');

  use phpseclib\Crypt\RSA;
  use phpseclib\Crypt\Hash;
  use phpseclib\Crypt\Random;

  function rsaEncryptionOaepSha256 ($publicKey, $plaintext) {
    $rsa = new RSA;
    $rsa->loadKey($publicKey);
    $rsa->setHash('sha256');
    $rsa->setMGFHash('sha256');
    return $rsa->encrypt($plaintext);
  }

  function rsaDecryptionOaepSha256 ($privateKey, $ciphertext) {
    $rsa = new RSA;
    $rsa->loadKey($privateKey);
    $rsa->setHash('sha256');
    $rsa->setMGFHash('sha256');
    return $rsa->decrypt($ciphertext);
  }
  
  function loadRsaPrivateKeyPem() {
    // this is a sample key - don't worry !
    return '
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDwSZYlRn86zPi9
e1RTZL7QzgE/36zjbeCMyOhf6o/WIKeVxFwVbG2FAY3YJZIxnBH 9j1XS6f ewjG
FlJY4f2IrOpS1kPiO3fmOo5N4nc8JKvjwmKtUM0t63uFFPfs69 7mKJ4w3tk2mSN
4gb8J9P9BCXtH6Q78SdOYvdCMspA1X8eERsdLb/jjHs8 gepKqQ6 XwZbSq0vf2B
MtaAB7zTX/Dk ZxDfwIobShPaB0mYmojE2YAQeRq1gYdwwO1dEGk6E5J2toWPpKY
/IcSYsGKyFqrsmbw0880r1BwRDer4RFrkzp4zvY kX3eDanlyMqDLPN ghXT1lv8
snZpbaBDAgMBAAECggEBAIVxmHzjBc11/73bPB2EGaSEg5UhdzZm0wncmZCLB453
XBqEjk8nhDsVfdzIIMSEVEowHijYz1c4pMq9osXR26eHwCp47AI73H5zjowadPVl
uEAot/xgn1IdMN/boURmSj44qiI/DcwYrTdOi2qGA jD4PwrUl4nsxiJRZ/x7PjL
hMzRbvDxQ4/Q4ThYXwoEGiIBBK/iB3Z5eR7lFa8E5yAaxM2QP9PENBr/OqkGXLWV
qA/YTxs3gAvkUjMhlScOi7PMwRX9HsrAeLKbLuC1KJv1p2THUtZbOHqrAF/uwHaj
ygUblFaa/BTckTN7PKSVIhp7OihbD04bSRrh nOilcECgYEA/8atV5DmNxFrxF1P
ODDjdJPNb9pzNrDF03TiFBZWS4Q 2JazyLGjZzhg5Vv9RJ7VcIjPAbMy2Cy5BUff
EFE 8ryKVWfdpPxpPYOwHCJSw4Bqqdj0Pmp/xw928ebrnUoCzdkUqYYpRWx0T7YV
RoA9RiBfQiVHhuJBSDPYJPoP34kCgYEA8H9wLE5L8raUn4NYYRuUVMa 1k4Q1N3X
Bixm5cccc/Ja4LVvrnWqmFOmfFgpVd8BcTGaPSsqfA4j/oEQp7tmjZqggVFqiM2m
J2YEv18cY/5kiDUVYR7VWSkpqVOkgiX3lK3UkIngnVMGGFnoIBlfBFF9uo02rZpC
5o5zebaDImsCgYAE9d5wv0 nq7/STBj4NwKCRUeLrsnjOqRriG3GA/TifAsX jw8
XS2VF PRLuqHhSkQiKazGr2Wsa9Y6d7qmxjEbmGkbGJBC AioEYvFX9TaU8oQhvi
hgA6ZRNid58EKuZJBbe/3ek4/nR3A0oAVwZZMNGIH972P7cSZmb/uJXMOQKBgQCs
FaQAL 4sN/TUxrkAkylqF QJmEZ26l2nrzHZjMWROYNJcsn8/XkaEhD4vGSnazCu
/B0vU6nMppmezF9Mhc112YSrw8QFK5GOc3NGNBoueqMYy1MG8Xcbm1aSMKVv8xba
rh BZQbxy6x61CpCfaT9hAoA6HaNdeoU6y05lBz1DQKBgAbYiIk56QZHeoZKiZxy
4eicQS0sVKKRb24ZUd 04cNSTfeIuuXZrYJ48Jbr0fzjIM3EfHvLgh9rAZ aHe/L
84Ig17KiExe qyYHjut/SC0wODDtzM/jtrpqyYa5JoEpPIaUSgPuTH/WhO3cDsx6
3PIW4/CddNs8mCSBOqTnoaxh
-----END PRIVATE KEY-----
';
  }

  function loadRsaPublicKeyPem() {
    // this is a sample key - don't worry !
    return '
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8EmWJUZ/Osz4vXtUU2S 
0M4BP9 s423gjMjoX qP1iCnlcRcFWxthQGN2CWSMZwR/vY9V0un/nsIxhZSWOH9
iKzqUtZD4jt35jqOTeJ3PCSr48JirVDNLet7hRT37Ovfu5iieMN7ZNpkjeIG/CfT
/QQl7R kO/EnTmL3QjLKQNV/HhEbHS2/44x7PPoHqSqkOvl8GW0qtL39gTLWgAe8
01/w5PmcQ38CKG0oT2gdJmJqIxNmAEHkatYGHcMDtXRBpOhOSdraFj6SmPyHEmLB
ishaq7Jm8NPPNK9QcEQ3q ERa5M6eM72PpF93g2p5cjKgyzzfoIV09Zb/LJ2aW2g
QwIDAQAB
-----END PUBLIC KEY-----
';
  }

  function base64Encoding ($input) {
    return base64_encode($input);
  }
  function base64Decoding ($input) {
    return base64_decode($input);
  }

  echo 'RSA 2048 encryption OAEP SHA-256 string' . PHP_EOL;
  $sDataToEncrypt = "The quick brown fox jumps over the lazy dog";
  echo 'plaintext: ' . $sDataToEncrypt . PHP_EOL;

  // encryption
  echo PHP_EOL . '* * * encrypt the plaintext with the RSA public key * * *' .PHP_EOL;
  $ciphertextBase64 = base64Encoding(rsaEncryptionOaepSha256(loadRsaPublicKeyPem(), $sDataToEncrypt));
  echo 'ciphertextBase64: ' . $ciphertextBase64 . PHP_EOL;

  // transport the encrypted data to recipient

  // receiving the encrypted data, decryption
  echo PHP_EOL . '* * * decrypt the ciphertext with the RSA private key * * *' .PHP_EOL;
  $ciphertextReceivedBase64 = $ciphertextBase64;
  echo 'ciphertextReceivedBase64: ' . $ciphertextReceivedBase64 . PHP_EOL;
  $decryptedtext = rsaDecryptionOaepSha256(loadRsaPrivateKeyPem(), base64Decoding($ciphertextReceivedBase64));
  echo 'decryptedtext: ' . $decryptedtext . PHP_EOL;

?>

To manually downgrade to PHPSecLib2 and get the above code to work, you'll need to replace the phpseclib directory with the files located at this GitHub here: https://github.com/phpseclib/phpseclib/tree/2.0

  • Related