lab/cacme/app/command/Acme.php
2024-08-05 22:57:28 +08:00

134 lines
4.4 KiB
PHP

<?php
namespace app\command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use AcmePhp\Core\Http\Base64SafeEncoder;
use AcmePhp\Core\Http\SecureHttpClientFactory;
use AcmePhp\Core\Http\ServerErrorHandler;
use AcmePhp\Ssl\KeyPair;
use AcmePhp\Ssl\PrivateKey;
use AcmePhp\Ssl\PublicKey;
use AcmePhp\Ssl\Parser\KeyParser;
use AcmePhp\Ssl\Signer\DataSigner;
use GuzzleHttp\Client as GuzzleHttpClient;
use AcmePhp\Ssl\DistinguishedName;
use AcmePhp\Ssl\CertificateRequest;
use AcmePhp\Ssl\Generator\KeyPairGenerator;
use AcmePhp\Core\Challenge\Dns\DnsDataExtractor;
use AcmePhp\Core\AcmeClient;
class Acme extends Command
{
protected static $defaultName = 'acme';
protected static $defaultDescription = 'acme';
/**
* @return void
*/
protected function configure()
{
$this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$EMAIL='youremail@yourdomain.com';
$DOMAIN='yourdomain.com';
#$CA='https://acme-v02.api.letsencrypt.org/directory';
$CA='https://acme-staging-v02.api.letsencrypt.org/directory';
$secureHttpClientFactory = new SecureHttpClientFactory(
new GuzzleHttpClient(),
new Base64SafeEncoder(),
new KeyParser(),
new DataSigner(),
new ServerErrorHandler()
);
$publicKeyPath = base_path().'/keys/account.pub.pem';
$privateKeyPath = base_path().'/keys/account.pem';
if (!file_exists($privateKeyPath)) {
$keyPairGenerator = new KeyPairGenerator();
$keyPair = $keyPairGenerator->generateKeyPair();
file_put_contents($publicKeyPath, $keyPair->getPublicKey()->getPEM());
file_put_contents($privateKeyPath, $keyPair->getPrivateKey()->getPEM());
} else {
$publicKey = new PublicKey(file_get_contents($publicKeyPath));
$privateKey = new PrivateKey(file_get_contents($privateKeyPath));
$keyPair = new KeyPair($publicKey, $privateKey);
}
$secureHttpClient = $secureHttpClientFactory->createSecureHttpClient($keyPair);
#$acmeClient = new AcmeClient($secureHttpClient, 'https://acme-v02.api.letsencrypt.org/directory');
$acmeClient = new AcmeClient($secureHttpClient, $CA);
$acmeClient->registerAccount($EMAIL,null);
$authorizationChallenges = $acmeClient->requestAuthorization($DOMAIN);
foreach($authorizationChallenges as $id=>$cha){
$cha->id=$id;
$dde=new DnsDataExtractor;
$cha->value=$dde->getRecordValue($cha);
print_r($cha);
}
#print_r($authorizationChallenges);
#print_r($dde->getRecordValue($authorizationChallenges[1]));
#$output->writeln($authorizationChallenges);
$helper = $this->getHelper('question');
$question = new ChoiceQuestion(
'选择对应的ID',
array('0', '1', '2'),
0
);
$way = $helper->ask($input, $output, $question);
$acmeClient->challengeAuthorization($authorizationChallenges[$way]);
$dn = new DistinguishedName($DOMAIN);
$keyPairGenerator = new KeyPairGenerator();
// Make a new key pair. We'll keep the private key as our cert key
$domainKeyPair = $keyPairGenerator->generateKeyPair();
// This is the private key
var_dump($domainKeyPair->getPrivateKey()->getPem());
// Generate CSR
$csr = new CertificateRequest($dn, $domainKeyPair);
$certificateResponse = $acmeClient->requestCertificate($DOMAIN, $csr);
// This is the certificate (public key)
var_dump($certificateResponse->getCertificate()->getPem());
// For Let's Encrypt, you will need the intermediate too
var_dump($certificateResponse->getCertificate()->getIssuerCertificate()->getPEM());
return self::SUCCESS;
}
}