juanchosl/certificates

Little tools collection in order to create and manage keys and certificates

dev-master 2025-10-02 09:53 UTC

This package is auto-updated.

Last update: 2025-10-02 09:53:40 UTC


README

Description

This library, is a full tool collections in order to create, read, parse, export, use... all the openssl (and few more) certificates/keys, in order to use for sign/verify and decryp/encrypt emails and documents, connect to SFTP/SSH servers, enable secure sockets and encrypt communications with web, ftp, webocket servers, and more.

The native PHP openssl functions, works from distincts key entry points, some functions require an object, the key contents, file path starting with an file://, other do not need it, this library remove the differences, unifying the container instantiation, any one drive the conversion internally, on order to avoid the user adaptations.

Install

This public package, is available from composer and from GitHub for zip download

composer require juanchosl/certificates
composer update

Containers (Repositories)

These are immutable objects that contain credentials, data, and information associated and linked together, ensuring proper operation and preventing unwanted manipulations that could cause loss or undesired effects.

They only have getters to read and extract parts of the element, which may vary depending on the container, although generically the following would be available:

  • Export method (export), which normally extracts the original information, in binary, text, array, etc., depending on the container

  • Reading details (getDetails), the details of the contained element or getDetail($name) for a knowed detail

  • Conversion to string (__tostring -> Stringable), converts the content to a PER or DEM string depending on the contained element, always in a supported standard format

  • Saving to file (save), after converting to a string, saves the data in a local file located in the path passed as a parameter. If not specified, the file will be created in the system's temporary directory, and the path will be returned by reference in the same parameter for later use.

  • Conversion to the standard Openssl-compatible object in PHP (__invoke) for use in encryption/decryption or signature/verification functions.

Private Key Container OpenSSL Private Asymmetric Key

The basic container of the package, a private key, allows us to use OPENSSL actions, sign and decrypt documents (using an asymmetric key), and connect to local systems such as computers or remote systems such as SFTP servers via SSH. It does not require personal data, and therefore does not need to be signed to generate a certificate with personal data. It never expires and must always be kept safe and protected, never sharing it with anyone; for this purpose, the public key is used.

$private_key = new PrivateKeyContainer($origin);

We can apply an encryption key, which will prevent it from being used if someone could gain access to it, requiring that the user know and provide it before it can be used.

$private_key = new PrivateKeyContainer($origin, $password);

If we have a non protected key, and we want protect it, can open the original non protected key, put a new password and export or save the key with the new protectin password

$private_key = new PrivateKeyContainer($unprotected_origin);
$private_key->setPassword($password);
$private_key = $private_key->export();

Public OPENSSL Key Container OpenSSL Public Asymmetric Key

It is the public key generated together with the private key, uniquely associated, and which must be shared with third parties in order to use the utilities described in the previous point.

$public_key = new PublicKeyContainer($origin);

or

$public_key = (new PrivateKeyContainer($origin))->getPublicKey();

Public OPENSSH Key Container OPENSSH

PHP does not have native support to create or convert keys in the OPENSSH format, but it is widely used, especially in SFTP or SSH systems, so we have seen fit to add the necessary functionality to be able to generate key pairs for this purpose and to be able to extract the SSL public key and convert it to the standard SSH format.

$openssh_key = new PublicSshKeyContainer($origin);

or

$openssh_key = (new PublicKeyContainer($origin))->getOpenSSH();

Certificate Signing Request Container @TODO

Equivalent to OpenSSLCertificateSigningRequest

x509 Certificate Container OpenSSLCertificate

The container for x509 certificates allows us to access the public information of the owner, as well as that of the certifier who issued the certificate, the uses for which it was created and the associated public key, which would allow it to be used to verify our digital signature or be used by third parties to encrypt documents or emails that only we can decrypt with our associated private key.

$certificate = new CertificateContainer($origin);

Certificate Chain Container

It is a collection that includes the list of certificates (x509) in our certification chain. It can be used to build PKCS7, PKCS8, and PKCS12 bundles and be added to the signature/verification and encryption/decryption systems.

It is not strictly a standard, but it allows for unified information and easy, quick, and simple use in the scenarios described above. It would be equivalent to the CA CHAIN ​​that our certificates provide, in an iterable, countable collection, exportable to a file or a chain, like the other containers provided with this library.

$chain = new ChainContainer($origin);

Pkcs12 Bundle Container OpenSSL-PKCS12

This is a signed package that includes all our information, our private key, certificate, public key, and optionally our certification chain, in a single file that must be password-protected, allowing the entire data package to be stored in a single standardized file. It can be added to our computer's repository, email program, or connection application, allowing us to use our credentials to sign or decrypt emails, sign documents such as PDFs, connect to remote services, etc.

$pkcs = new Pkcs12Container($origin, $password);
$private = $pkcs->getPrivateKey(?$private_credential);
$cert = $pkcs->getCertificate();
$public = $cert->getPublicKey();

you can use your pkcs12 bundle in order to export the public part (your certificate with public key and CA chain if is included) to file formatted standard pkcs7 with extension .p7b, and send to others

$pkcs = new Pkcs12Container($origin, $password);
$pkcs->getPublicBundle()->save($path_to_save);

In order to change the password of the bundle (or the private key password), actually do not provide a simple method to do it, due the internal dependency, in order to avoid missmatches. You needs to open with the actual credential, extract the containers, change the password and use the Pkcs12Creator

$pkcs = new Pkcs12Container($origin, $password);
$cert = $pkcs->getCertificate();
$chain = $pkcs->getChain();
$old_private = $pkcs->getPrivateKey(?$old_pass)->setPassword($new_password)->export();
$new_private = new PrivateKeyContainer($old_private);
$new_binary_pkcs = (new Pkcs12Creator($description, $can_be_new_password))->setPrivateKey($new_private)->setCertificate($cert)->setChain($chain);

Pkcs8 Signed Bundle Container OpenSSL-PKCS8

PKCS8 container is an intermediate between PKCS7 and PKCS12. It is a signed bundle that includes an information package (just like PKCS12) signed with the issuer private key (as PKCS7), used from the CA to send the signed certificates, chain, and, if is necessary, the user private key, but without requiring a password for read all the contents package. The private key can to be encrypted by applying an unique password using the PKCS5 protocol, as recommended by the PKCS8 standard, but not necesary the public certificates.

Pkcs7 Signed Bundle Container OpenSSL-PKCS7

This is a signed package that includes our public information, certificate, with the public key and optionally our certification chain, in a single file, so that it can be shared and used to verify our signatures or give third parties the possibility of encrypting content that only we, with our private key, can decrypt.

With PHP, we can export all certificates in a single array, with the library, we can put in separate the user certificate and the CA chain as a collection,

Pkcs7/Pkcs8/Pkcs12 PEM Container OpenSSL-PKCS-PEM

PEM PKCS containers is an all in one, multi purpose, with data encoded to base64 ASCII. It is a bundle that can includes the entire information package (just like PKCS12 for pkcs12 and pkcs8) but without requiring a password for the entire package. It allows the public part (all pkcs7/pkcs8/pkcs12) to be extracted without specifying it, but still allows the private key (not included for pkcs7) to be encrypted by applying an unique password using the PKCS5 protocol, as recommended by the PKCS standard.

Creators

PKCS12

Creates a standard PKCS12 container, in order to save all the credentials into an unique repository. The creator check for required files, private key and certificate, for an non empty password, check than the certificate are related and it has been created with the private key

$private = new PrivateKeyContainer($private_file_or_data);
$certificate = new CertificateContainer($certificate_file_or_data);
$chain = new ChainContainer($chain_file_or_data);
$pkcs12 = (new Pkcs12Creator($description, $password))->setPrivateKey($private)->setCertificate($certificate)->setChain($chain);

$binary = $pkcs12->export();

or save it into file, PKCS12 are alwways in binary format

$pkcs12->save($destiny_path); #returns true|false

PKCS8

Creates a PKCS8 container, in order to save all the credentials into an unique repository. The creator check for signer files, private key and certificate, for a non empty password, check than the certificate are related and it has been created with the private key, the, creates a message with the data user certificates to append at the message. If you do not add a message,the signer data has been included, ir order to usa as own repository.

$private = new PrivateKeyContainer($private_file_or_data);
$certificate = new CertificateContainer($certificate_file_or_data);
$chain = new ChainContainer($chain_file_or_data);
$pkcs8 = (new Pkcs8Creator)->setPrivateKey($private)->setCertificate($certificate)->setChain($chain);
$pkcs8->setMessage($user_data_to_append)->export();

PKCS7

Creates a standard PKCS7 container, in order to save all the public credentials signed into an unique repository. The creator check for required files, private key and certificate, check than the .certificate are related and it has been created with the private key.The Private key is required only for sign the bundle, it is not included.

$private = new PrivateKeyContainer($private_file_or_data);
$certificate = new CertificateContainer($certificate_file_or_data);
$chain = new ChainContainer($chain_file_or_data);
$pkcs7 = (new Pkcs7Creator)->setPrivateKey($private)->setCertificate($certificate)->setChain($chain);

then you can export it as binary data (DER)

$binary_pkcs7 = $pkcs7->export();

export it as ASCII Base64 data with headers BEGIN PKCS7 | END PKCS7

$b64_pkcs7 = (string) $pkcs7;

or save into a selected file

$pkcs7->save($desired_saving_path);

Readers and Factories

Using factories, you can instantiate containers from few origins and formats, dellegating to the library the container selection, usefull when you can receive distincts types and avoid the user check and control.

Container Factory

If you can receive data from files or strings and streams, don't needs open and check to select the right container, you can use someone factory that do this work.

All containers are auto callables except Pkcs12 or encrypted primary key, because its needs a password, the factory try to create a LockedContainer that need to be invoked passing the password por unlock it.

Actually you have available:

  • createFromUnknow -> Check the data and send to method file, contents or entity
  • createFromFile -> Check the file mimetype and send it to function mimetype if is available, or try to process using contents
  • createFromContents -> Check the contents and send to process as string or binary
  • createFromMimetype -> using the readed mimetype, create an compatible container for it if is available
  • createFromEntity -> if is an standard openssl php function, try to convert. It can use Stream objects using the user mimetype, uploaded path or the stream contents.
  • createFromBinary -> as last chance, try using binary data as Pkcs12 package
$stream = $psr15_server_request->getUploadedFiles()['file']->getStream();
$container = (new ContainerFactory)->createFromEntity($stream);

Interfaces

  • CertificateReadable -> Have a certificate accesible
  • ChainReadable -> Have a certificates collection accesible
  • Detailable -> Have readable details
  • Exportable -> can be exported
  • FingerprintReadable ->have a standard fingerprint calculation accesible
  • Formateable -> have a standar format, extension and mimetype, available por save or download
  • PasswordProtectable -> Is an element with a password required (Pkcs12)
  • PasswordUnprotectable -> Is an element that can be encrypted with a pasword, and can be removed too
  • PrivateKeyReadable -> Have a private key accesible
  • PublicKeyReadable -> Have a public key accesible
  • Saveable -> can be saved into a file
  • Standarizable -> can be converted to native php object
  • Verifyable -> can be verifyed with other key from other container
  • Stringable -> can be exported as string
Certificate Chain Pkcs12 Pkcs8 PEM Pkcs7 Priv key Pub key Pub SSH
CertificateReadable X X X
ChainReadable X X X X
Detailable X X X X X
Exportable X X X X X X
FingerprintReadable X X
Formateable X X X X X X X
PasswordProtectable X
PasswordUnprotectable X
PrivateKeyReadable X X
PublicKeyReadable X X
Saveable X X X X X X X X
Standarizable X X X
Verifyable X
Stringable X X X X X X
Countable X
Iterable X