SetaPDF Demos

There seems to be a problem loading the components. Please check your PHP error logs for details!

Common issues could be that you missed to install the trial license or that you are using a trial version on an unsupported PHP version.

openssl_private_encrypt() (individual module)

This demo uses the openssl_private_encrypt() function to create the signature value wrapped in an individual signature module.

The module makes use of the \setasign\SetaPDF2\Signer\Signature\Module\PadesProxyTrait trait.

PHP
<?php

use setasign\SetaPDF2\Demos\Signer\Module\Signature\OpenSslPrivateEncryptModule;
use setasign\SetaPDF2\Core\Document;
use setasign\SetaPDF2\Core\Writer\HttpWriter;
use setasign\SetaPDF2\Core\Writer\TempFileWriter;
use setasign\SetaPDF2\Signer\Digest;
use setasign\SetaPDF2\Signer\Signer;

// load and register the autoload function
require_once __DIR__ . '/../../../../../../bootstrap.php';
// load the module class
require_once __DIR__ . '/../../../../../../classes/Signer/Module/Signature/OpenSslPrivateEncryptModule.php';

// the file to sign
$fileToSign = $assetsDirectory . '/pdfs/tektown/Laboratory-Report.pdf';
// create a temporary path
$tempFile = TempFileWriter::createTempPath();

// create a writer instance
$writer = new HttpWriter('signed-with-php-openssl.pdf');
// create the document instance
$document = Document::loadByFilename($fileToSign, $writer);

// create the signer instance
$signer = new Signer($document);

// let's use the PAdES modul and configure it
$module = new OpenSslPrivateEncryptModule();
$module->setDigest(Digest::SHA_256);
$module->setCertificate('file://' . $assetsDirectory . '/certificates/setapdf-no-pw.pem');

$privateKey = \openssl_pkey_get_private('file://' . $assetsDirectory . '/certificates/setapdf-no-pw.pem', '');
$module->setPrivateKey($privateKey);

$signer->sign($module);
PHP
<?php

namespace setasign\SetaPDF2\Demos\Signer\Module\Signature;

use setasign\SetaPDF2\Core\Reader\FilePath;
use setasign\SetaPDF2\Signer\Asn1\Element as Asn1Element;
use setasign\SetaPDF2\Signer\Asn1\Oid as Asn1Oid;
use setasign\SetaPDF2\Signer\Digest;
use setasign\SetaPDF2\Signer\Exception;
use setasign\SetaPDF2\Signer\Signature\Module\DictionaryInterface;
use setasign\SetaPDF2\Signer\Signature\Module\DocumentInterface;
use setasign\SetaPDF2\Signer\Signature\Module\ModuleInterface;
use setasign\SetaPDF2\Signer\Signature\Module\PadesProxyTrait;

class OpenSslPrivateEncryptModule implements ModuleInterface, DictionaryInterface, DocumentInterface
{
    use PadesProxyTrait;

    /**
     * @var \OpenSSLAsymmetricKey|resource
     */
    protected $_privateKey;

    /**
     * @param \OpenSSLAsymmetricKey|resource $privateKey
     * @return void
     */
    public function setPrivateKey($privateKey)
    {
        $details = \openssl_pkey_get_details($privateKey);
        if (!is_array($details)) {
            throw new \InvalidArgumentException('Cannot get details from private key.');
        }

        if ($details['type'] !== \OPENSSL_KEYTYPE_RSA) {
            throw new \InvalidArgumentException('Only RSA keys are supported in this demo.');
        }

        $this->_privateKey = $privateKey;
    }

    /**
     * @param string $digest
     * @return void
     */
    public function setDigest($digest)
    {
        $this->_getPadesModule()->setDigest($digest);
    }

    /**
     * @param FilePath $tmpPath
     * @return string
     * @throws Exception
     */
    public function createSignature(FilePath $tmpPath)
    {
        $padesModule = $this->_getPadesModule();
        // get the hash data from the module
        $padesDigest = $padesModule->getDigest();

        $hashData = hash($padesDigest, $padesModule->getDataToSign($tmpPath), true);

        // let's sign only the hash, so we create the ASN.1 container manually
        $digestInfo = new Asn1Element(
            Asn1Element::SEQUENCE | Asn1Element::IS_CONSTRUCTED, '',
            [
                new Asn1Element(
                    Asn1Element::SEQUENCE | Asn1Element::IS_CONSTRUCTED, '',
                    [
                        new Asn1Element(
                            Asn1Element::OBJECT_IDENTIFIER,
                            Asn1Oid::encode(
                                Digest::getOid($padesModule->getDigest())
                            )
                        ),
                        new Asn1Element(Asn1Element::NULL)
                    ]
                ),
                new Asn1Element(
                    Asn1Element::OCTET_STRING,
                    $hashData
                )
            ]
        );

        if (@\openssl_private_encrypt($digestInfo, $signatureValue, $this->_privateKey) === false) {
            $lastError = \error_get_last();
            throw new Exception(
                'An OpenSSL error occurred during signature process' .
                (isset($lastError['message']) ? ': ' . $lastError['message'] : '') . '.'
            );
        }

        $padesModule->setSignatureValue($signatureValue);

        return (string)$padesModule->getCms();
    }
}