Encryption and decryption

Updated at:

Use the KMS instance SDK client to call the Encrypt and Decrypt APIs for symmetric key encryption and decryption. This page provides a complete PHP example followed by a step-by-step walkthrough.

Prerequisites

Before you begin, ensure that you have:

  • A KMS instance with a symmetric master key (CMK) created

  • A ClientKey obtained from KMS application management

  • The KMS instance SDK for PHP installed

For client initialization details, see Initialize the client.

How it works

The encryption and decryption flow has three steps:

  1. Initialize the KMS instance SDK client with your ClientKey and instance endpoint.

  2. Call the Encrypt API with the plaintext. The response includes the ciphertext and an initialization vector (IV).

  3. Call the Decrypt API with the ciphertext, algorithm, and the IV from the encrypt response.

Important

Save the iv field from the encrypt response. The Decrypt API requires the exact IV used during encryption — without it, decryption will fail.

Complete example

The following example shows the full encrypt-then-decrypt flow, including client initialization and result verification.

<?php

if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}

use AlibabaCloud\Dkms\Gcs\OpenApi\Util\Models\RuntimeOptions;
use AlibabaCloud\Dkms\Gcs\Sdk\Client as AlibabaCloudDkmsGcsSdkClient;
use AlibabaCloud\Dkms\Gcs\OpenApi\Models\Config as AlibabaCloudDkmsGcsOpenApiConfig;
use AlibabaCloud\Dkms\Gcs\Sdk\Models\DecryptRequest;
use AlibabaCloud\Dkms\Gcs\Sdk\Models\EncryptRequest;
use AlibabaCloud\Tea\Utils\Utils as AlibabaCloudTeaUtils;

/*
 * ClientKey supports three authentication methods:
 *
 * 1. ClientKey file path:
 *      $cfg->clientKeyFile = '<CLIENT_KEY_FILE_PATH>';
 *      $cfg->password      = '<CLIENT_KEY_PASSWORD>';
 *
 * 2. ClientKey content (inline):
 *      $cfg->clientKeyContent = '<CLIENT_KEY_CONTENT>';
 *      $cfg->password         = '<CLIENT_KEY_PASSWORD>';
 *
 * 3. Private key and AccessKeyId:
 *      $cfg->accessKeyId = '<CLIENT_KEY_KEYID>';
 *      $cfg->privateKey  = '<PARSE_FROM_CLIENT_KEY_PRIVATEKEY_DATA>';
 */

// ClientKey content obtained from KMS application management.
$clientKeyContent = '<CLIENT_KEY_CONTENT>';

// ClientKey password. Load from an environment variable to avoid hardcoding credentials.
$password = getenv('CLIENT_KEY_PASSWORD');

// KMS instance VPC endpoint.
$endpoint = '<DKMS_INSTANCE_SERVICE_ADDRESS>';

// CMK ID of the master key created in KMS.
$keyId = '<CMK_ID>';

// Encryption algorithm (for example, AES_256/CBC/NoPadding).
$algorithm = '<ENCRYPT_ALGORITHM>';

// Plaintext to encrypt.
$plaintext = '<ENCRYPT_PLAINTEXT>';

// Initialize the KMS instance SDK client.
$client = getDkmsGcsSdkClient();
if (is_null($client)) {
    exit(1);
}

// Run the encrypt-decrypt sample.
aesEncryptDecryptSample();

/**
 * Encrypts then decrypts the plaintext and verifies the round-trip result.
 */
function aesEncryptDecryptSample()
{
    global $client, $keyId, $plaintext, $algorithm;

    $cipherCtx = aesEncryptSample($client, $keyId, $plaintext, $algorithm);
    if ($cipherCtx !== null) {
        $decryptResult = AlibabaCloudTeaUtils::toString(aesDecryptSample($client, $cipherCtx));
        if ($plaintext !== $decryptResult) {
            echo 'decrypt result not match the plaintext' . PHP_EOL;
        } else {
            echo 'aesEncryptDecryptSample success' . PHP_EOL;
        }
    }
}

/**
 * Encrypts plaintext using a symmetric key and returns the encryption context.
 *
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param string $keyId
 * @param string $plaintext
 * @param string $algorithm
 * @return AesEncryptContext|null
 */
function aesEncryptSample($client, $keyId, $plaintext, $algorithm)
{
    $encryptRequest            = new EncryptRequest();
    $encryptRequest->keyId     = $keyId;
    $encryptRequest->algorithm = $algorithm;
    $encryptRequest->plaintext = AlibabaCloudTeaUtils::toBytes($plaintext);

    $runtimeOptions = new RuntimeOptions();
    // Uncomment the following line to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $encryptResponse = $client->encryptWithOptions($encryptRequest, $runtimeOptions);

        var_dump($encryptResponse->toMap());

        // Save all four fields — you need them to decrypt the ciphertext later.
        return new AesEncryptContext([
            'keyId'          => $encryptResponse->keyId,
            'iv'             => $encryptResponse->iv,          // Required by Decrypt
            'ciphertextBlob' => $encryptResponse->ciphertextBlob,
            'algorithm'      => $encryptResponse->algorithm,
        ]);
    } catch (\Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }

    return null;
}

/**
 * Decrypts ciphertext using the encryption context returned by aesEncryptSample.
 *
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param AesEncryptContext $ctx
 * @return int[]|null
 */
function aesDecryptSample($client, $ctx)
{
    $decryptRequest                = new DecryptRequest();
    $decryptRequest->keyId         = $ctx->keyId;
    $decryptRequest->ciphertextBlob = $ctx->ciphertextBlob;
    $decryptRequest->algorithm     = $ctx->algorithm;
    $decryptRequest->iv            = $ctx->iv;  // Must match the IV from encryption

    $runtimeOptions = new RuntimeOptions();
    // Uncomment the following line to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $decryptResponse = $client->decryptWithOptions($decryptRequest, $runtimeOptions);
        var_dump($decryptResponse->toMap());
        return $decryptResponse->plaintext;
    } catch (\Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }

    return null;
}

/**
 * Builds and returns the KMS instance SDK client.
 *
 * @return AlibabaCloudDkmsGcsSdkClient
 */
function getDkmsGcsSdkClient()
{
    global $clientKeyContent, $password, $endpoint;

    $config                   = new AlibabaCloudDkmsGcsOpenApiConfig();
    $config->protocol         = 'https';          // KMS instance only allows HTTPS
    $config->clientKeyContent = $clientKeyContent;
    $config->password         = $password;
    $config->endpoint         = $endpoint;        // Format: <instance-id>.cryptoservice.kms.aliyuncs.com
    $config->caFilePath       = 'path/to/caCert.pem';

    return new AlibabaCloudDkmsGcsSdkClient($config);
}

/**
 * Holds the output fields from an encrypt call.
 * Store this object if you need to decrypt the ciphertext later.
 */
class AesEncryptContext
{
    /** @var string */
    public $keyId;

    /** @var int[] */
    public $iv;

    /** @var int[] */
    public $ciphertextBlob;

    /** @var string Use the default algorithm value if not explicitly set. */
    public $algorithm;

    public function __construct($config = [])
    {
        foreach ($config as $k => $v) {
            $this->{$k} = $v;
        }
    }
}

Replace the following placeholders with actual values:

Placeholder

Description

<CLIENT_KEY_CONTENT>

ClientKey content obtained from KMS application management

<DKMS_INSTANCE_SERVICE_ADDRESS>

KMS instance VPC endpoint

<CMK_ID>

ID of the master key created in KMS

<ENCRYPT_ALGORITHM>

Encryption algorithm

<ENCRYPT_PLAINTEXT>

Plaintext string to encrypt

Example walkthrough

The following sections break down the complete example into three parts. The code snippets are extracted from the complete example above.

Initialize the client

See Initialize the client for full details. The relevant snippet from the complete example:

<?php

use AlibabaCloud\Dkms\Gcs\Sdk\Client as AlibabaCloudDkmsGcsSdkClient;
use AlibabaCloud\Dkms\Gcs\OpenApi\Models\Config as AlibabaCloudDkmsGcsOpenApiConfig;

function getDkmsGcsSdkClient()
{
    global $clientKeyContent, $password, $endpoint;

    $config                   = new AlibabaCloudDkmsGcsOpenApiConfig();
    $config->protocol         = 'https';          // KMS instance only allows HTTPS
    $config->clientKeyContent = $clientKeyContent;
    $config->password         = $password;        // ClientKey security token
    $config->endpoint         = $endpoint;        // Format: <instance-id>.cryptoservice.kms.aliyuncs.com
    $config->caFilePath       = 'path/to/caCert.pem';

    return new AlibabaCloudDkmsGcsSdkClient($config);
}

Call the Encrypt API to encrypt data using a symmetric key

function aesEncryptSample($client, $keyId, $plaintext, $algorithm)
{
    $encryptRequest            = new EncryptRequest();
    $encryptRequest->keyId     = $keyId;
    $encryptRequest->algorithm = $algorithm;
    $encryptRequest->plaintext = AlibabaCloudTeaUtils::toBytes($plaintext);

    $runtimeOptions = new RuntimeOptions();
    // Uncomment the following line to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $encryptResponse = $client->encryptWithOptions($encryptRequest, $runtimeOptions);

        var_dump($encryptResponse->toMap());

        // Save all four fields — you need them to decrypt the ciphertext later.
        return new AesEncryptContext([
            'keyId'          => $encryptResponse->keyId,
            'iv'             => $encryptResponse->iv,          // Required by Decrypt
            'ciphertextBlob' => $encryptResponse->ciphertextBlob,
            'algorithm'      => $encryptResponse->algorithm,
        ]);
    } catch (\Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }

    return null;
}

Call the Decrypt API to decrypt ciphertext using a symmetric key

function aesDecryptSample($client, $ctx)
{
    $decryptRequest                = new DecryptRequest();
    $decryptRequest->keyId         = $ctx->keyId;
    $decryptRequest->ciphertextBlob = $ctx->ciphertextBlob;
    $decryptRequest->algorithm     = $ctx->algorithm;
    $decryptRequest->iv            = $ctx->iv;  // Must match the IV from encryption

    $runtimeOptions = new RuntimeOptions();
    // Uncomment the following line to skip SSL certificate verification (not recommended for production).
    // $runtimeOptions->ignoreSSL = true;

    try {
        $decryptResponse = $client->decryptWithOptions($decryptRequest, $runtimeOptions);
        var_dump($decryptResponse->toMap());
        return $decryptResponse->plaintext;
    } catch (\Exception $error) {
        if ($error instanceof \AlibabaCloud\Tea\Exception\TeaError) {
            var_dump($error->getErrorInfo());
        }
        var_dump($error->getMessage());
        var_dump($error->getTraceAsString());
    }

    return null;
}