Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot instantiate abstract class phpseclib3\Crypt\RSA #1937

Open
abunajmi opened this issue Sep 13, 2023 · 6 comments
Open

Cannot instantiate abstract class phpseclib3\Crypt\RSA #1937

abunajmi opened this issue Sep 13, 2023 · 6 comments
Labels

Comments

@abunajmi
Copy link

abunajmi commented Sep 13, 2023

I have code below for decrypt function :

<?php
namespace Modules\Smime;

use phpseclib3\Crypt\RSA;
use phpseclib3\File\X509;

class SmimeDecrypter
{
    public function decrypt($encryptedMessage, $privateKeyPath, $certificatePath, $outputPath)
    {
        // Load the private key
        $rsa = new Rsa();
        $rsa->load(file_get_contents($privateKeyPath));

        // You can continue loading and using the X509 certificate as before
        $x509 = new X509();
        $cert = $x509->loadX509(file_get_contents($certificatePath));

        // Decrypt the S/MIME message using the private key
        $decryptedMessage = $rsa->decrypt($encryptedMessage);

        if ($decryptedMessage !== false) {
            // Save the decrypted message to the specified output path
            file_put_contents($outputPath, $decryptedMessage);
            return true;
        } else {
            return false;
        }
    }
}

but when I execute there is error Cannot instantiate abstract class phpseclib3\Crypt\RSA, is there any suggestion for the right code above for succeded decryption

@terrafrost
Copy link
Member

You're using the phpseclib2 syntax. For phpseclib3 you'd need to do something more like this:

<?php
namespace Modules\Smime;

use phpseclib3\Crypt\RSA;
use phpseclib3\File\X509;

class SmimeDecrypter
{
    public function decrypt($encryptedMessage, $privateKeyPath, $certificatePath, $outputPath)
    {
        // Load the private key
        $rsa = PublicKeyLoader::load(file_get_contents($privateKeyPath));

        // You can continue loading and using the X509 certificate as before
        $x509 = new X509();
        $cert = $x509->loadX509(file_get_contents($certificatePath));

        // Decrypt the S/MIME message using the private key
        $decryptedMessage = $rsa->decrypt($encryptedMessage);

        if ($decryptedMessage !== false) {
            // Save the decrypted message to the specified output path
            file_put_contents($outputPath, $decryptedMessage);
            return true;
        } else {
            return false;
        }
    }
}

@terrafrost
Copy link
Member

Note that phpseclib3 changed some of the default hashes (sha256 is now the default vs sha1, which phpseclib1 used as the default) so you might need to tweak that as well. http://phpseclib.com/docs/why#phpseclib-30-vs-phspeclib-10--20 elaborates.

Alternatively, you could use https://github.com/phpseclib/phpseclib2_compat to use phpseclib2 style code with phpseclib3.

@abunajmi
Copy link
Author

abunajmi commented Sep 14, 2023

I have Implemented using phpseclib version 2 but when execution this controller there is error as I attach image below :

<?php

namespace App\Http\Controllers;

//use Illuminate\Http\Request;
//use Modules\Smime\SmimeService;

use phpseclib\File\ASN1;
use phpseclib\File\X509;
use phpseclib\File\X509Cert;
use phpseclib\Crypt\RSA;

class SmimeController extends Controller
{
    public function showDecryptForm()
    {
        return view('smime/decrypt_smime');
    }

    public function decrypt()
    {

        $p7mFilePath = '/var/www/html/storage/output/smime.p7m';
        $outputFilePath = '/var/www/html/storage/output/decrypted_output.txt';
        $certificateFilePath = '/var/www/html/storage/output/cert_email.pem';
        $privateKeyFilePath = '/var/www/html/storage/output/key_email.pem';

// Load the certificate and private key
        $x509 = new X509();
        $certificate = $x509->loadX509(file_get_contents($certificateFilePath));

        $privateKey = new RSA();
        $privateKey->loadKey(file_get_contents($privateKeyFilePath));
        var_dump($privateKey);

// Decrypt the S/MIME file
        $p7 = file_get_contents($p7mFilePath);
        $asn1 = new ASN1();
        $decoded = $asn1->decodeBER($p7);
        var_dump($decoded);

        $encryptedData = $decoded[0]['content'][0]['content'];
        $decryptedData = $privateKey->decrypt($encryptedData);


// Save the decrypted data to a file
        file_put_contents($outputFilePath, $decryptedData);

    }
}

here the error when execution controller above

image

@terrafrost
Copy link
Member

$decryptedData = $privateKey->decrypt($encryptedData);, by default, uses the more secure, albeit less frequently used OAEPscheme. You probably want to be using the PKCS1 scheme. ie. you'd do $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); before calling $privateKey->decrypt($encryptedData). Since you're (now) using 2.0 see https://phpseclib.sourceforge.net/rsa/2.0/examples.html#encrypt,enc2 for more details.

@abunajmi
Copy link
Author

after I added $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); before calling $privateKey->decrypt($encryptedData) as suggested but there is error below , could you tell me what else should do

image

@terrafrost
Copy link
Member

Maybe your ciphertext doesn't use any padding. Maybe the key that you're using isn't the right one. Could be any number of things.

At this point, without the ciphertext and key I'm not going to be able to provide a ton of insight. And even with those things, if the key is wrong, there's not a whole heck of a lot imma be able to do. Like I'll be able to tell you if the ciphertext doesn't use any padding at all (assuming the key is correct), but that's about it...

@bantu bantu added the support label Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants