Skip to content

PHP Password encryption example

Encryption and Decryption functions

<?php

//$key is provided as hex string
function encrypt($plainText, $key)
{
    //key need to be converted to bytes array
    $key = hex2bin($key);
    //algorithm that we use here is connected with key length
    //in example we use 256bit key for different length please use proper cipher for example aes-256-gcm
    //more information about possible values https://www.php.net/manual/en/function.openssl-get-cipher-methods.php
    $cipher = "aes-256-gcm";
    //discover length of Initialization Vector that should be use with selected cipher method
    $ivlen = openssl_cipher_iv_length($cipher);
    //random iv
    $iv = openssl_random_pseudo_bytes($ivlen);
    //encryption
    //we instruct openssl to use NO_PADDING
    $ciphertext_raw = openssl_encrypt($plainText, $cipher, $key, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA, $iv, $tag);
    //output is base64 encoded iv and cipher with tag
    return array(base64_encode($iv), base64_encode($ciphertext_raw . $tag));
}

//$key is provided as hex string
function decrypt($cipherBase64Encoded, $ivBase64Encoded, $key)
{
    //key need to be converted to bytes array
    $key = hex2bin($key);
    //algorithm that we use here is connected with key length
    //in example we use 256bit key for different length please use proper cipher for example aes-256-gcm
    //more information about possible values https://www.php.net/manual/en/function.openssl-get-cipher-methods.php
    $cipher = "aes-256-gcm";
    //decode iv from base64
    $iv = base64_decode($ivBase64Encoded);
    //encryption
    $cipherText = base64_decode($cipherBase64Encoded);
    //cipher without tag
    $tagLength = 16;
    $cipherWithoutTag = substr($cipherText, 0, strlen($cipherText) - $tagLength);
    //extracting tag from cipher
    $tag = substr($cipherText, strlen($cipherText) - $tagLength);
    //we instruct openssl to use NO_PADDING
    $plainText = openssl_decrypt($cipherWithoutTag, $cipher, $key, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA, $iv, $tag);
    return $plainText;
}

//Text that should be encrypted
$plainText = "Password!1";
//encryption key 256bit
$hexKey = "C45B3B4E5CF954C50A654CA66190188E65305C514AF00934BCFDD965412338B4";

//Encryption
$encrypted = encrypt($plainText, $hexKey);

echo "\n===========\n";
echo "Plain Text: " . $plainText;
echo "\nKey: " . $hexKey;
echo "\nCipher Text: " . $encrypted[1];
echo "\nIV: " . $encrypted[0];
echo "\n===========\n";

//Decryption
$decryptedData = decrypt($encrypted[1], $encrypted[0], $hexKey);
echo "Decrypted Text: " . $decryptedData;
echo "\n===========\n";

?>

Example to update a password via our PersonAPI

The example below requires PHP composer with the following composer.json file.

{
    "require": {
        "guzzlehttp/guzzle": "^7.0"
    }
}

For the script below to work you need to set the API credentials, and the user information.

<?php

// Using PHP Composer
require '../html/vendor/autoload.php';

echo '<html><body>';
echo '<h1>Test Timestamp</h1>';
echo '<p>The current date and time is ' . date('F jS, Y H:i:s') . '</p>';

$CIM_BASE_URL = "https://[CIM instance].onegini.com/";
$CIM_API_USER = "XXXX";
$CIM_API_PASSWD = "YYYY";
// Needs to be 256bit, 32 bytes, so 64 hexadecimal characters
$CIM_ENCRYPTION_HEXKEY = "ZZZZ";

function encrypt_password_change($curPassword, $newPassword, $key)
{
    //key need to be converted to bytes array
    $key = hex2bin($key);
    //algorithm that we use here is connected with key length
    //in example we use 256bit key for different length please use proper cipher for example aes-256-gcm
    //more information about possible values https://www.php.net/manual/en/function.openssl-get-cipher-methods.php
    $cipher = "aes-256-gcm";
    //discover length of Initialization Vector that should be use with selected cipher method
    $ivlen = openssl_cipher_iv_length($cipher);
    //random iv
    $iv = openssl_random_pseudo_bytes($ivlen);
    //encryption
    //we instruct openssl to use NO_PADDING
    $cur_ciphertext_raw = openssl_encrypt($curPassword, $cipher, $key, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA, $iv, $cur_tag);
    $new_ciphertext_raw = openssl_encrypt($newPassword, $cipher, $key, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA, $iv, $new_tag);
    //output is base64 encoded iv and cipher with tag for both old and new password
    return array(base64_encode($iv), base64_encode($cur_ciphertext_raw . $cur_tag), base64_encode($new_ciphertext_raw . $new_tag));
}

//Person to change password for
$personId = "AAAA";
//Text that should be encrypted
$curPassword = "BBBB";
$newPassword = "CCCC";

$client = new GuzzleHttp\Client([
    'base_uri' => $CIM_BASE_URL,
    'auth' => [$CIM_API_USER, $CIM_API_PASSWD],
    'headers' => [
        'User-Agent' => 'Superior Demo Agent',
        'Accept' => 'application/json',
    ]
]);

$encrypted = encrypt_password_change($curPassword, $newPassword, $CIM_ENCRYPTION_HEXKEY);

echo '<h1>Cipher Details</h1>';
echo "<pre>";
echo "\nKey: " . $CIM_ENCRYPTION_HEXKEY;
echo "\nIV: " . $encrypted[0];
echo "\nold_pw: " . $encrypted[1];
echo "\nnew_pw: " . $encrypted[2];
echo "</pre>";

try {
    $response = $client->post("/api/persons/".$personId."/password-change", [
        'json' => [
            'encryption_parameter' => $encrypted[0],
            'new_password' => $encrypted[2],
            'password' => $encrypted[1],
        ]
    ]);

    echo '<h1>CIM API Query</h1>';
    echo "<pre>";
    echo "\nStatus: " . $response->getStatusCode();
    echo "\nResponse Body: " . json_encode(json_decode($response->getBody(), true), JSON_PRETTY_PRINT);
    echo "</pre>";
}
catch(\GuzzleHttp\Exception\RequestException $e) {
    echo '<h1>CIM API Exception</h1>';
    echo "<pre>";
    echo "\nError: " . $e->getMessage();
    if ($e->hasResponse()) {
        $response = $e->getResponse();
        echo "\nStatus: " . $response->getStatusCode();
        echo "\nResponse Body: " . json_encode(json_decode($response->getBody(), true), JSON_PRETTY_PRINT);
    }
    echo "</pre>";
}

echo '</body></html>';

?>