首页 > 解决方案 > 使用带有 Symfony 框架的 openpgp-php 尝试从命名空间“App\Controller”加载类“OpenPGP_SecretKeyPacket”

问题描述

我找到了这个答案,它帮助了我一半: 你如何使用 PHP OpenPGP 库?

首先,由于依赖关系,我真的无法通过下载它来正确设置它。但是当我使用 composer 运行并安装 Symfony 时,我最终通过运行composer require singpolyma/openpgp-phpwhich install pgp 并将依赖项安装到 vendor 文件夹中来在 Symfony 中安装(但不工作)。

如果我需要如下要求,我可以在独立的 php 文件中使用 pgp,但这在控制器中不起作用(即使我添加了要求,它也不会或多或少地失败)

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");

在 Symfony 的 AbstractController 中,它不是这样工作的。我压碎了我应该使用哪个“使用”命令的大脑,我只是没有更多的想法。

来自 composer.json 的名字是

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

但减号不是命名空间中的有效名称。

我通常会收到错误

尝试从命名空间“App\Controller”加载类“OpenPGP_SecretKeyPacket”。您是否忘记了另一个名称空间的“使用”语句?

<?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 <test@example.com>');

        $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 中命名空间的任何提示。

标签: phpsymfonynamespacesopenpgp

解决方案


这里实际上涉及两个库。phpseclib 是命名空间的,所以像 RSA 类这样的东西可以与一个简单的 new 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

推荐阅读