Использование openpgp-php с инфраструктурой Symfony Попытка загрузить класс OpenPGP_SecretKeyPacket из пространства имен App\Controller

Я нашел этот ответ, и он помог мне на полпути: Как вы используете библиотека PHP OpenPGP?

Прежде всего, из-за зависимостей мне действительно не удалось правильно настроить его, просто загрузив его. Но поскольку Symfony у меня работает и установлен с помощью composer, я, наконец, установил pgp (но не работал) в Symfony, запустив composer require singpolyma/openpgp-php, который установил его и зависимости в папку поставщика.

Я могу использовать pgp в отдельном php-файле, если мне требуется следующее, но это не работает в контроллере (даже если я добавлю требования, он не выйдет из строя больше или меньше, чем без)

require("../vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php");
require("../vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php");
require("../vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php");
require("../vendor/singpolyma/openpgp-php/lib/openpgp_crypt_rsa.php");

В AbstractController Symfony это не работает. Я сломал свой мозг, какую команду я должен использовать, и у меня просто больше нет идей.

из composer.json имя

"name": "singpolyma/openpgp-php",

но минус не является допустимым именем в пространстве имен.

обычно получаю ошибку

Попытка загрузить класс OpenPGP_SecretKeyPacket из пространства имен App\Controller. Вы забыли оператор использования для другого пространства имен?

<?php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManagerInterface;

class PageApiController extends AbstractController
{
    /**
    @Route("/ApiTest", methods={"GET"})
    */
    public function ApiTest(EntityManagerInterface $entityManager)
    {
        $rsa = new \phpseclib\Crypt\RSA(); // HERE comes the ERROR
        $k = $rsa->createKey(512);
        $rsa->loadKey($k['privatekey']);

        $nkey = new OpenPGP_SecretKeyPacket(array(
        'n' => $rsa->modulus->toBytes(),
        'e' => $rsa->publicExponent->toBytes(),
        'd' => $rsa->exponent->toBytes(),
        'p' => $rsa->primes[2]->toBytes(),
        'q' => $rsa->primes[1]->toBytes(),
        'u' => $rsa->coefficients[2]->toBytes()
        ));

        $uid = new OpenPGP_UserIDPacket('Test <[email protected]>');

        $wkey = new OpenPGP_Crypt_RSA($nkey);
        $m = $wkey->sign_key_userid(array($nkey, $uid));

        // Serialize private key
        $Data = $m->to_bytes();

        return $this->json(['Test' => $Data]);
    }
}

Должен признаться, я не привык к пространствам имен в php, и я знаю, что еще не очень понимаю, что происходит в symfony. Я очень благодарен за любой намек на пространства имен в Symfony.


person René W.    schedule 11.01.2021    source источник
comment
Я предполагаю, что библиотека не использует пространства имен? Вы можете подтвердить, взглянув на исходный код. Исправление может быть таким же простым, как использование обратной косой черты в начале для указания глобального пространства имен: new \OpenPGP_UserIDPacket Если ничего другого, по крайней мере, вы получите другое сообщение об ошибке.   -  person Cerad    schedule 12.01.2021
comment
он не использует пространства имен...   -  person René W.    schedule 13.01.2021


Ответы (1)


На самом деле здесь задействованы две библиотеки. phpseclib имеет пространство имен, поэтому такие вещи, как класс RSA, можно использовать с простой новой RSA(). Однако материал OpenPGP не имеет пространства имен и, похоже, не поддерживает классическую автозагрузку. Лично я бы поискал другую, более современную библиотеку, однако вы можете использовать возможности файлов composer.json для загрузки необходимых включаемых файлов. В этот момент вы можете аккуратно создать класс пакета секретного ключа. Это то, на что я пошел с тестированием.

# create a new project
symfony new --full pgp
cd pgp
composer require singpolyma/openpgp-php

# Edit composer.json
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        },
        "files": [
            "vendor/singpolyma/openpgp-php/lib/openpgp.php",
            "vendor/singpolyma/openpgp-php/lib/openpgp_crypt_rsa.php"
        ]
    },
# refresh autoload.php
composer dump-autoload

# Add a test command
namespace App\Command;

use phpseclib\Crypt\RSA;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class PgpCommand extends Command
{
    protected static $defaultName = 'pgp:test';

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $rsa = new RSA();
        $k = $rsa->createKey(512);
        $rsa->loadKey($k['privatekey']);

        // Note the leading back slash
        $nkey = new \OpenPGP_SecretKeyPacket(array(
            'n' => $rsa->modulus->toBytes(),
            'e' => $rsa->publicExponent->toBytes(),
            'd' => $rsa->exponent->toBytes(),
            'p' => $rsa->primes[2]->toBytes(),
            'q' => $rsa->primes[1]->toBytes(),
            'u' => $rsa->coefficients[2]->toBytes()
        ));
        return Command::SUCCESS;
    }
}

# and test
bin/console pgp:test
person Cerad    schedule 12.01.2021
comment
вы гениальны.... я отредактировал часть автозагрузки, запустил команду композитора и добавил \ ко всем использованиям классов, не относящихся к пространству имен, таких как \OpenPGP_Crypt_RSA, я мог бы посмотреть, какие именно команды в symfony есть - может быть, было бы лучше добавить функциональность собственным командным классом, а не непосредственно в контроллере, верно? ($data были зашифрованы двоичными данными, поэтому возникла ошибка, когда был принят вызов. - person René W.; 13.01.2021
comment
Иногда проще протестировать код, выполнив консольную команду, а не обновляя браузер. Если бы я действительно собирался использовать PGP для чего-то, я бы создал какой-то сервисный класс PGP и обернул бы всю низкоуровневую функциональность. Затем такую ​​службу можно внедрить и использовать из контроллера, команды или чего-то еще, что в ней нуждается. - person Cerad; 13.01.2021