1. Go to this page and download the library: Download vatsake/php-asic-e library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
vatsake / php-asic-e example snippets
use Vatsake\AsicE\AsiceConfig;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Monolog\Logger;
$logger = new Logger('test_log');
$logger->pushHandler(new StreamHandler(__DIR__ . '/log.log', Level::Debug));
AsiceConfig::setLogger($logger);
use Vatsake\AsicE\AsiceConfig;
use Vatsake\AsicE\Container\Container;
use Vatsake\AsicE\Container\UnsignedContainer;
use Vatsake\AsicE\Crypto\SignAlg;
// Configure TSA (and OCSP) endpoints
// If setting OCSP endpoint here, it will only use that endpoint
AsiceConfig::setOcspUrl(/* OCSP URL */)
->setTsaUrl(/* TSA URL */);
// 1a: Create a new ASiC-E container
$uc = new UnsignedContainer();
$uc->addFile('foo.txt', 'bar');
$container = $uc->build(__DIR__ . '/foobar.asice'); // Writes to disk
// 1b: Existing container
$container = Container::open(__DIR__ . '/foobar.asice');
// 2. Prepare a signature
$builder = $container->createSignature();
$dataToBeSigned = $builder
->setSigner($signingCert) // PEM certificate
->setSignatureAlg(SignAlg::ECDSA_SHA256) // (optional) Signing algorithm (default SHA-256)
->setSignatureProductionPlace('Tallinn', 'Harjumaa', 99999, 'EE') // (optional)
->setSignerRoles(['Agreed']) // (optional)
->getDataToBeSigned(true); // true → raw canonicalized bytes
// Typically $dataToBeSigned (not raw) is returned to the user to sign; so we have to save incomplete signature somewhere (preferably in user's session)
file_put_contents('temp', serialize($builder));
// 3. User signs data
// Typically $dataToBeSigned (not raw) is returned to the user to sign (if signing via ID-card)
// In php it could be something like this:
$pkeyid = openssl_pkey_get_private(/* Private key */);
openssl_sign($dataToBeSigned, $signatureValue, $pkeyid, OPENSSL_ALGO_SHA256); // PHP's openssl sign needs RAW sign data
// 4. Finalize and attach the signature
/** @var \Vatsake\AsicE\Container\Signature\SignatureBuilder */
$signature = unserialize(file_get_contents('temp'));
$finalizedSignature = $signature->finalize($signatureValue);
$container = Container::open(__DIR__ . '/foobar.asice');
$container->addSignature($finalizedSignature);
use Vatsake\AsicE\AsiceConfig;
use Vatsake\AsicE\Container\Container;
use Vatsake\AsicE\Container\UnsignedContainer;
use Vatsake\AsicE\Crypto\SignAlg;
use Sk\SmartId\Api\Data\SignatureHash;
use Sk\SmartId\Api\Data\SemanticsIdentifier;
use Sk\SmartId\Api\Data\Interaction;
use Sk\SmartId\Client;
AsiceConfig::setTsaUrl('http://tsa.demo.sk.ee/tsa');
# Smart ID client
$client = new Client();
$client->setRelyingPartyUUID('00000000-0000-0000-0000-000000000000')
->setRelyingPartyName('DEMO')
->setHostUrl('https://sid.demo.sk.ee/smart-id-rp/v2/');
# Create container and add file
$uc = new UnsignedContainer();
$uc->addFile('foo.txt', 'bar');
$container = $uc->build(__DIR__ . '/foobar.asice');
# Get the signing certificate
$semanticsIdentifier = SemanticsIdentifier::builder()
->withSemanticsIdentifierType('PNO')
->withCountryCode('LT')
->withIdentifier('30303039914')
->build();
try {
$resp = $client->signature()
->createCertificateChoice()
->withSemanticsIdentifier($semanticsIdentifier)
->chooseCertificate();
} catch (\Exception $e) {
var_dump($e);
exit;
// Check official documentation to catch all exceptions
}
# Get data to be signed
$builder = $container->createSignature();
$dataToBeSigned = $builder
->setSigner($resp->getCertificate()) // PEM certificate
->setSignatureAlg(SignAlg::RSA_SHA256) // SMART-ID uses RSA algorithm
->setSignatureProductionPlace('Tallinn', 'Harjumaa', 99999, 'EE') // (optional)
->setSignerRoles(['Agreed']) // (optional)
->getDataToBeSigned(true); // RAW - SignableData from Smart-id library gets digest
// Might need to save builder instance
file_put_contents('temp', serialize($builder));
# Sign data via Smart-id
$data = new SignatureHash($dataToBeSigned);
$data->setHashType('SHA256');
echo 'vccode ' . $data->calculateVerificationCode();
try {
$resp = $client->signature()->createSignature()
->withDocumentNumber($resp->getDocumentNumber())
->withSignableData($data)
->withAllowedInteractionsOrder([
Interaction::ofTypeVerificationCodeChoice('Sign?')
])
->sign();
} catch (\Exception $e) { // Use exceptions below
var_dump($e);
exit;
// Check official documentation to catch all exceptions
}
// Attach signature
/** @var \Vatsake\AsicE\Container\Signature\SignatureBuilder */
$signature = unserialize(file_get_contents('temp'));
$finalizedSignature = $signature->finalize($resp->getValueInBase64());
$container = Container::open(__DIR__ . '/foobar.asice');
$container->addSignature($finalizedSignature);
use Sk\Mid\DisplayTextFormat;
use Sk\Mid\Language\ENG;
use Sk\Mid\MobileIdClient;
use Sk\Mid\MobileIdSignatureHashToSign;
use Sk\Mid\Rest\Dao\Request\CertificateRequest;
use Sk\Mid\Rest\Dao\Request\SignatureRequest;
use Vatsake\AsicE\AsiceConfig;
use Vatsake\AsicE\Container\Container;
use Vatsake\AsicE\Container\UnsignedContainer;
use Vatsake\AsicE\Crypto\SignAlg;
AsiceConfig::setTsaUrl('http://tsa.demo.sk.ee/tsa');
# Mobile ID client
$client = MobileIdClient::newBuilder()
->withRelyingPartyUUID('00000000-0000-0000-0000-000000000000')
->withRelyingPartyName('DEMO')
->withLongPollingTimeoutSeconds(60)
->withHostUrl('https://tsp.demo.sk.ee/mid-api')
->build();
# Create container and add file
$uc = new UnsignedContainer();
$uc->addFile('foo.txt', 'bar');
$container = $uc->build(__DIR__ . '/foobar.asice');
# Get the signing certificate
$request = CertificateRequest::newBuilder()
->withPhoneNumber('+37200000766')
->withNationalIdentityNumber('60001019906')
->build();
try {
$resp = $client->getMobileIdConnector()->pullCertificate($request);
} catch (\Exception $e) {
var_dump($e);
exit;
// Check official documentation to catch all exceptions
}
# Get data to be signed
$builder = $container->createSignature();
$dataToBeSigned = $builder
->setSigner($resp->getCert()) // PEM certificate
->setSignatureAlg(SignAlg::ECDSA_SHA256) // MOBILE-ID uses ECDSA algorithm
->setSignatureProductionPlace('Tallinn', 'Harjumaa', 99999, 'EE') // (optional)
->setSignerRoles(['Agreed']) // (optional)
->getDataToBeSigned();
// Might need to save builder instance
file_put_contents('temp', serialize($builder));
$hash = MobileIdSignatureHashToSign::newBuilder()->withHashInBase64($dataToBeSigned)->withHashType('sha256')->build();
$verificationCode = $hash->calculateVerificationCode(); // Show this to user
# Sign data via Mobile-id
$request = SignatureRequest::newBuilder()
->withPhoneNumber('+37200000766')
->withNationalIdentityNumber('60001019906')
->withHashToSign($hash)
->withLanguage(ENG::asType())
->withDisplayText("Sign document?")
->withDisplayTextFormat(DisplayTextFormat::GSM7)
->build();
try {
$response = $client->getMobileIdConnector()->initSignature($request);
} catch (\Exception $e) { // Use exceptions below
var_dump($e);
exit;
// Check official documentation to catch all exceptions
}
# Poll until final result
$finalSessionStatus = $client
->getSessionStatusPoller()
->fetchFinalSignatureSessionStatus($response->getSessionID(), 60);
try {
$result = $client->createMobileIdSignature($finalSessionStatus, $hash);
} catch (\Exception $e) {
var_dump($e);
exit;
// Check official documentation to catch all exceptions
}
// Attach signature
/** @var \Vatsake\AsicE\Container\Signature\SignatureBuilder */
$signature = unserialize(file_get_contents('temp'));
$finalizedSignature = $signature->finalize($result->getSignatureValueInBase64());
$container = Container::open(__DIR__ . '/foobar.asice');
$container->addSignature($finalizedSignature);
use Vatsake\AsicE\Container\Container;
use Vatsake\AsicE\Validation\Lotl;
use Vatsake\AsicE\AsiceConfig;
AsiceConfig::setCountryCode('EE'); // Limit trust anchors to Estonia
$container = Container::open('/foobar.asice');
// Option 1 – validate all signatures
$container->validateSignatures(); // Returns array<array{index: int, valid: bool, errors: ValidationResult[]}>
// Option 2 – iterate manually
foreach ($container->getSignatures() as $i => $sig) {
$ok = $sig->isValid();
echo $i . ': ' . ($ok ? 'OK' : 'NOK') . PHP_EOL;
if (!$ok) var_dump($sig->getValidationErrors());
}
use Vatsake\AsicE\Validation\Lotl;
use Vatsake\AsicE\AsiceConfig;
// Bootstrap
Lotl::refresh(); // This force loads all trust anchors (without country code it's about 4.5k trust anchors)
$lotl = AsiceConfig::getLotl(); // Returns array of trust anchors
file_put_contents('foo', json_encode($lotl)); // Your application might have a cache server
// Later (from cache)
$lotl = json_decode(file_get_contents('foo'), true); // Again, you might have a cache server
AsiceConfig::setLotl($lotl)
->setOcspUrl(/* OCSP URL */)
->setTsaUrl(/* TSA URL */)
->setCountryCode('EE'); // If you filter trust anchors by country
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.