PHPackages                             gamringer/pkcs11 - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. gamringer/pkcs11

ActivePhp-ext[Security](/categories/security)

gamringer/pkcs11
================

PHP extension for PKCS11

34115[1 issues](https://github.com/gamringer/php-pkcs11/issues)C

Since Mar 4Pushed 1mo ago8 watchersCompare

[ Source](https://github.com/gamringer/php-pkcs11)[ Packagist](https://packagist.org/packages/gamringer/pkcs11)[ RSS](/packages/gamringer-pkcs11/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)DependenciesVersions (1)Used By (0)

PKCS11 bindings for PHP
=======================

[](#pkcs11-bindings-for-php)

Tested with the following HSMs:

- SafeNET Luna SA 4
- SoftHSM 2.6
- Nitrokey HSM 2
- AWS CloudHSM

Supports PHP version &gt;= 7.4

Compile
-------

[](#compile)

```
phpize
./configure
make

```

Running tests
-------------

[](#running-tests)

To make tests, ensure that SoftHSM2 is installed, configured and initialized.

### Install SoftHSM2

[](#install-softhsm2)

#### From Source

[](#from-source)

1. Get the [source](https://github.com/opendnssec/SoftHSMv2)
2. Extract Archive
3. `cd /path/to/extracted/archive`
4. `./configure`
5. `make`
6. `make install`

Module will be located in `/usr/local/lib/softhsm/libsofthsm2.so`

#### From Ubuntu package repository

[](#from-ubuntu-package-repository)

*As of this writing, Ubuntu 20.04 provides v2.2 of SoftHSM2 in which not all mechanisms will be available*

1. `sudo apt install softhsm2`

Module will be located in `/usr/lib/softhsm/libsofthsm2.so`

### Configure and initialize SoftHSM2

[](#configure-and-initialize-softhsm2)

1. Create a directory where HSM files will be stored `/home/user/.softhsm`
2. Create a configuration file in your home directory `~/.config/softhsm2/softhsm2.conf`
3. Initialize token `softhsm2-util --init-token --slot 0 --label "My token 1" --pin 123456 --so-pin 12345678`
4. Grab the resulting slot ID `softhsm2-util --show-slots`

Example configuration file

```
directories.tokendir = /home/user/.softhsm
objectstore.backend = file
log.level = INFO
slots.removable = false
slots.mechanisms = ALL

```

### Run tests

[](#run-tests)

```
export PHP11_MODULE=/path/to/libsofthsm2.so
export PHP11_SLOT={SLOT_ID_FROM_INITIALIZATION}
export PHP11_PIN=123456

make test
```

How to use
----------

[](#how-to-use)

*All examples assume the use of a locally compiled installation of SoftHSM, but it will work with other modules as well.*

### Loading a module

[](#loading-a-module)

To load a PKCS11 module, create a new PKCS11\\Module object.

```
$modulePath = '/path/to/libsofthsm2.so';
$module = new Pkcs11\Module($modulePath);
```

From the PKCS11\\Module object, you can call most PKCS11 methods.

To get information the module:

```
$moduleInfo = $module->getInfo();
```

### Slot Information

[](#slot-information)

There are 2 methods to retrieve slots information. `getSlotList` can be used to retrieve a simple list of slots like `C_GetSlotList` would, while `getSlots` returns de result of `C_GetSlotInfo` for each available slot.

```
$slotList = $module->getSlotList();
$slots = $module->getSlots();

$slotId = $slotList[0];

$slotInfo = $module->getSlotInfo($slotId);
```

### Token Information

[](#token-information)

```
$tokenInfo = $module->getTokenInfo($slotId);
```

### Mechanisms

[](#mechanisms)

All mechanisms declared in PKCS11 version 3 are available under the Pkcs11 namespace.

```
$mechanismList = $module->getMechanismList($slotId);
$mechanismInfo = $module->getMechanismInfo($slotId, Pkcs11\CKM_AES_GCM);
```

### Initializing a token

[](#initializing-a-token)

This extension supports initializing simple tokens via the `C_InitToken` function.

```
$module->initToken($slotId, $label, $soPin);
```

### Opening a session

[](#opening-a-session)

You can open a session and login as either a Security Officer or user. From the returned `Pkcs11\Session` object, more methods are available.

```
$session = $module->openSession($slotId, Pkcs11\CKF_RW_SESSION);
$session->login(Pkcs11\CKU_SO, $soPin);
$sessionInfo = $session->getInfo();
```

```
$session = $module->openSession($slotId, Pkcs11\CKF_RW_SESSION);
$session->login(Pkcs11\CKU_USER, $userPin);
$sessionInfo = $session->getInfo();
```

### PIN Management

[](#pin-management)

As a Security Officer, the user PIN can be set to any value.

```
$session->login(Pkcs11\CKU_SO, $soPin);
$session->initPin($userPin);
$session->logout();
```

As either user, the current user PIN can be changed.

```
$session->login(Pkcs11\CKU_SO, $soPin);
$session->setPin($soPin, $newPin);
$session->logout();
```

```
$session->login(Pkcs11\CKU_USER, $userPin);
$session->setPin($userPin, $newPin);
$session->logout();
```

### Generating Keys

[](#generating-keys)

You can generate symmetric keys for any available mechanism.

```
$key = $session->generateKey(new Pkcs11\Mechanism(Pkcs11\CKM_AES_KEY_GEN), [
  Pkcs11\CKA_CLASS => Pkcs11\CKO_SECRET_KEY,
  Pkcs11\CKA_SENSITIVE => true,
  Pkcs11\CKA_ENCRYPT => true,
  Pkcs11\CKA_DECRYPT => true,
  Pkcs11\CKA_VALUE_LEN => 32,
  Pkcs11\CKA_KEY_TYPE => Pkcs11\CKK_AES,
  Pkcs11\CKA_LABEL => "Test AES",
  Pkcs11\CKA_PRIVATE => true,
]);
```

```
$keypair = $session->generateKeyPair(new Pkcs11\Mechanism(Pkcs11\CKM_EC_KEY_PAIR_GEN), [
  Pkcs11\CKA_VERIFY => true,
  Pkcs11\CKA_LABEL => "Test ECDSA Public",
  Pkcs11\CKA_EC_PARAMS => hex2bin('06082A8648CE3D030107'),
],[
  Pkcs11\CKA_TOKEN => false,
  Pkcs11\CKA_PRIVATE => true,
  Pkcs11\CKA_SENSITIVE => true,
  Pkcs11\CKA_SIGN => true,
  Pkcs11\CKA_LABEL => "Test ECDSA Private",
]);

$pkey = $keypair->pkey;
$skey = $keypair->skey;
```

### Encrypt/Decrypt

[](#encryptdecrypt)

Given a symmetric key, you can encrypt something. Certain encryption mechanisms require a special Parameters object. Currently, the following are available:

- Pkcs11\\GcmParams
- Pkcs11\\Salsa20Params
- Pkcs11\\ChaCha20Params
- Pkcs11\\Salsa20Chacha20Poly1305Params

```
$iv = random_bytes(16);
$aad = '';
$tagLength = 128;
$gcmParams = new Pkcs11\GcmParams($iv, $aad, $tagLength);

$data = 'Hello World!';
$mechanism = new Pkcs11\Mechanism(Pkcs11\CKM_AES_GCM, $gcmParams);
$ciphertext = $key->encrypt($mechanism, $data);
var_dump(bin2hex($ciphertext));
// string(56) "67940e19213d68c88d163b12d6cd565300f70d693309b5b744085b35"

$plaintext = $key->decrypt($mechanism, $ciphertext);
var_dump($plaintext);
// string(12) "Hello World!"
```

AWS CloudHSM does things in a particular way. The initialization vector is generated by the HSM for you and returned prepended to the ciphertext.

```
$aad = '';
$tagLength = 128;
// No need to specify the $iv
$gcmParams = new Pkcs11\GcmParams('', $aad, $tagLength);

$data = 'Hello World!';
$mechanism = new Pkcs11\Mechanism(Pkcs11\CKM_CLOUDHSM_AES_GCM, $gcmParams);
$ciphertext = $key->encrypt($mechanism, $data);
var_dump(bin2hex($ciphertext));
// string(88) "0000000000000000000000000000000067940e19213d68c88d163b12d6cd565300f70d693309b5b744085b35"

$plaintext = $key->decrypt($mechanism, $ciphertext);
var_dump($plaintext);
// string(12) "Hello World!"
```

Given an RSA public key, you can encrypt a symmetric key. Similarly to symmetric mechanisms, some asymmetric encryption mechanisms require a special Parameters object. Currently, the following are available:

- Pkcs11\\RsaOaepParams

```
$keypair = $session->generateKeyPair(new Pkcs11\Mechanism(Pkcs11\CKM_RSA_PKCS_KEY_PAIR_GEN), [
  Pkcs11\CKA_ENCRYPT => true,
  Pkcs11\CKA_MODULUS_BITS => 2048,
  Pkcs11\CKA_PUBLIC_EXPONENT => hex2bin('010001'),
  Pkcs11\CKA_LABEL => "Test RSA Encrypt Public",
],[
  Pkcs11\CKA_TOKEN => false,
  Pkcs11\CKA_PRIVATE => true,
  Pkcs11\CKA_SENSITIVE => true,
  Pkcs11\CKA_DECRYPT => true,
  Pkcs11\CKA_LABEL => "Test RSA Encrypt Private",
]);

// SoftHSM2 only supports CKG_MGF1_SHA1
$oaepParam = new Pkcs11\RsaOaepParams(Pkcs11\CKM_SHA_1, Pkcs11\CKG_MGF1_SHA1);
$mechanism = new Pkcs11\Mechanism(Pkcs11\CKM_RSA_PKCS_OAEP, $oaepParam);

$symkey = random_bytes(32);
$ciphertext = $keypair->pkey->encrypt($mechanism, $symkey);
var_dump($ciphertext);

$plaintext = $keypair->skey->decrypt($mechanism, $ciphertext);
var_dump($plaintext);
```

### Derivation

[](#derivation)

Given an EC public key, you can derive a shared secret.

```
// P-384
$domainParameters = hex2bin('06052B81040022');
$rawPublickeyOther = hex2bin('049f0a09e8a6fc87f4804642c782b2cd3e566b3e62262090d94e12933a00916f559b62ea33197706a302f0722b781a9349ea8f0f2bcea854cdcf5d9ff0e0a19c3c35d63578292307d1d83031c0134700c2990ed5b38f6c92245103c2c1352132a3');

$keypair = $session->generateKeyPair(new Pkcs11\Mechanism(Pkcs11\CKM_EC_KEY_PAIR_GEN), [
  Pkcs11\CKA_LABEL => "Test ECDH Public",
  Pkcs11\CKA_EC_PARAMS => $domainParameters,
],[
  Pkcs11\CKA_PRIVATE => true,
  Pkcs11\CKA_SENSITIVE => true,
  Pkcs11\CKA_DERIVE => true,
  Pkcs11\CKA_LABEL => "Test ECDH Private",
]);

$shared = '';

// SoftHSM2 only supports CKD_NULL
$params = new Pkcs11\Ecdh1DeriveParams(Pkcs11\CKD_NULL, $shared, $rawPublickeyOther);
$mechanism = new Pkcs11\Mechanism(Pkcs11\CKM_ECDH1_DERIVE, $params);
$secret = $keypair->skey->derive($mechanism, [
  Pkcs11\CKA_CLASS => Pkcs11\CKO_SECRET_KEY,
  Pkcs11\CKA_KEY_TYPE => Pkcs11\CKK_AES,
  Pkcs11\CKA_SENSITIVE => false,
  Pkcs11\CKA_EXTRACTABLE => true,
  Pkcs11\CKA_ENCRYPT => true,
  Pkcs11\CKA_DECRYPT => true,
]);

$rawSecret = $secret->getAttributeValue([Pkcs11\CKA_VALUE])[Pkcs11\CKA_VALUE];
```

### Retrieving object by URI

[](#retrieving-object-by-uri)

You have the ability to retrieve object using [RFC7512](https://datatracker.ietf.org/doc/html/rfc7512) URIs.

*Note:* Currently, only the following path attributes are supported:

- id
- object
- type

```
$session->generateKeyPair(new Pkcs11\Mechanism(Pkcs11\CKM_RSA_PKCS_KEY_PAIR_GEN), [
  Pkcs11\CKA_ENCRYPT => true,
  Pkcs11\CKA_MODULUS_BITS => 2048,
  Pkcs11\CKA_PUBLIC_EXPONENT => hex2bin('010001'),
  Pkcs11\CKA_LABEL => "testPkcs11Url",
  Pkcs11\CKA_ID => "testPkcs11UrlPublicId",
],[
  Pkcs11\CKA_TOKEN => false,
  Pkcs11\CKA_PRIVATE => true,
  Pkcs11\CKA_SENSITIVE => true,
  Pkcs11\CKA_DECRYPT => true,
  Pkcs11\CKA_LABEL => "testPkcs11Url",
  Pkcs11\CKA_ID => "testPkcs11UrlPrivateId",
]);

$privateKeySearchResult = $session->openUri("pkcs11:object=testPkcs11Url;type=private;");

$mechanism = new Pkcs11\Mechanism(Pkcs11\CKM_SHA256_RSA_PKCS);

$data = "Hello World!";
$signature = $privateKeySearchResult[0]->sign($mechanism, $data);
var_dump(bin2hex($signature));

$publicKeySearchResult = $session->openUri("pkcs11:id=testPkcs11UrlPublicId");
$valid = $publicKeySearchResult[0]->verify($mechanism, $data, $signature);
var_dump($valid);
```

### Retrieve object attributes

[](#retrieve-object-attributes)

Given an Object, you can retrieve it's readable attributes.

*Note:* the following attributes are not implemented and retrieving them throws an exception:

- CKA\_WRAP\_TEMPLATE
- CKA\_UNWRAP\_TEMPLATE
- CKA\_DERIVE\_TEMPLATE

*Note:* the following attributes internally provide a struct describing the date, but are here returned as a string:

- CKA\_START\_DATE
- CKA\_END\_DATE

```
$keypair = $session->generateKeyPair(new Pkcs11\Mechanism(Pkcs11\CKM_RSA_PKCS_KEY_PAIR_GEN), /* ... */);

$attributes = $keypair->skey->getAttributeValue([
  Pkcs11\CKA_TOKEN,
  Pkcs11\CKA_PRIVATE,
  Pkcs11\CKA_SENSITIVE,
  Pkcs11\CKA_EXTRACTABLE,
  Pkcs11\CKA_NEVER_EXTRACTABLE,
  Pkcs11\CKA_ALWAYS_SENSITIVE,
  Pkcs11\CKA_SIGN,
  Pkcs11\CKA_DECRYPT,
  Pkcs11\CKA_PUBLIC_EXPONENT,
  Pkcs11\CKA_LABEL,
]);

var_dump($attributes[Pkcs11\CKA_TOKEN]);
var_dump($attributes[Pkcs11\CKA_PRIVATE]);
var_dump($attributes[Pkcs11\CKA_SENSITIVE]);
var_dump($attributes[Pkcs11\CKA_EXTRACTABLE]);
var_dump($attributes[Pkcs11\CKA_NEVER_EXTRACTABLE]);
var_dump($attributes[Pkcs11\CKA_ALWAYS_SENSITIVE]);
var_dump($attributes[Pkcs11\CKA_SIGN]);
var_dump($attributes[Pkcs11\CKA_DECRYPT]);
var_dump(bin2hex($attributes[Pkcs11\CKA_PUBLIC_EXPONENT]));
var_dump($attributes[Pkcs11\CKA_LABEL]);

/* Outputs:
bool(false)
bool(true)
bool(true)
bool(false)
bool(true)
bool(true)
bool(true)
bool(false)
string(6) "010001"
string(16) "Test RSA Private"
*/
```

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance59

Moderate activity, may be stable

Popularity15

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 74.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1c5aec75f1c5985cebb506748224fded4aefe753e72632800054166a8955c633?d=identicon)[g.amringer](/maintainers/g.amringer)

---

Top Contributors

[![gamringer](https://avatars.githubusercontent.com/u/4048559?v=4)](https://github.com/gamringer "gamringer (232 commits)")[![vjardin](https://avatars.githubusercontent.com/u/8383368?v=4)](https://github.com/vjardin "vjardin (68 commits)")[![dcoombs](https://avatars.githubusercontent.com/u/44320?v=4)](https://github.com/dcoombs "dcoombs (4 commits)")[![remicollet](https://avatars.githubusercontent.com/u/270445?v=4)](https://github.com/remicollet "remicollet (3 commits)")[![JordyHeemskerk](https://avatars.githubusercontent.com/u/5947973?v=4)](https://github.com/JordyHeemskerk "JordyHeemskerk (1 commits)")[![JimmyHamel](https://avatars.githubusercontent.com/u/25286614?v=4)](https://github.com/JimmyHamel "JimmyHamel (1 commits)")[![Magentron](https://avatars.githubusercontent.com/u/853900?v=4)](https://github.com/Magentron "Magentron (1 commits)")

---

Tags

cryptographycryptokiphpphp-extensionpkcs11softhsm

### Embed Badge

![Health badge](/badges/gamringer-pkcs11/health.svg)

```
[![Health](https://phpackages.com/badges/gamringer-pkcs11/health.svg)](https://phpackages.com/packages/gamringer-pkcs11)
```

###  Alternatives

[defuse/php-encryption

Secure PHP Encryption Library

3.9k162.4M214](/packages/defuse-php-encryption)[roave/security-advisories

Prevents installation of composer packages with known security vulnerabilities: no API, simply require it

2.9k97.3M6.4k](/packages/roave-security-advisories)[mews/purifier

Laravel 5/6/7/8/9/10 HtmlPurifier Package

2.0k16.7M113](/packages/mews-purifier)[robrichards/xmlseclibs

A PHP library for XML Security

41278.1M118](/packages/robrichards-xmlseclibs)[bjeavons/zxcvbn-php

Realistic password strength estimation PHP library based on Zxcvbn JS

86917.5M63](/packages/bjeavons-zxcvbn-php)[enlightn/security-checker

A PHP dependency vulnerabilities scanner based on the Security Advisories Database.

33732.2M110](/packages/enlightn-security-checker)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
