全部產品
Search
文件中心

Key Management Service:加密解密樣本

更新時間:Dec 26, 2024

初始化KMS執行個體SDK用戶端後,您可以通過用戶端調用Encrypt和Decrypt介面對資料進行加密解密。本文介紹加密解密的程式碼範例。

完整程式碼範例

整合KMS進行對稱式加密解密包含三個步驟:

  1. 初始化調用KMS介面的用戶端。

  2. 使用用戶端調用Encrypt介面對資料進行加密。

  3. 使用用戶端調用Decrypt介面對密文資料進行解密。

源碼github地址:AesEncryptDecrypt.php

加密解密完整程式碼範例

<?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傳參支援以下三種方式:
 * 1、通過指定ClientKey.json檔案路徑方式
 * 樣本:
 *      String clientKeyFile = "<your client key file path>";
 *      String password = "<your client key password>";
 *      Config cfg = new Config();
 *      cfg.setClientKeyFile(clientKeyFile);
 *      cfg.setPassword(password);
 *
 * 2、通過指定ClientKey內容方式
 * 樣本:
 *      String clientKeyContent = "<your client key content>";
 *      String password = "<your client key password>";
 *      Config cfg = new Config();
 *      cfg.setClientKeyContent(clientKeyContent);
 *      cfg.setPassword(password);
 *
 * 3、通過指定私密金鑰和AccessKeyId
 * 樣本:
 *      String accessKeyId = "<your client key KeyId>";
 *      String privateKey = "<parse from your client key PrivateKeyData>";
 *      Config cfg = new Config();
 *      cfg.setAccessKeyId(accessKeyId);
 *      cfg.setPrivateKey(privateKey);
 *
 */

// 填寫您在KMS應用管理擷取的ClientKey檔案路徑
// $clientKeyFile = '<your client key file path>';

// 或者,填寫您在KMS應用管理擷取的ClientKey檔案內容
$clientKeyContent = '<your client key content>';

// 填寫您在KMS應用管理建立ClientKey時輸入的加密口令
$password = getenv('CLIENT_KEY_PASSWORD');

// 填寫您的KMS執行個體VPC地址
$endpoint = '<your dkms instance service address>';

// 填寫您在KMS建立的主要金鑰Id
$keyId = '<your cmk id>';

// 加解密演算法
$algorithm = '<your encrypt algorithm>';

// 待加密明文
$plaintext = 'encrypt plaintext';

// KMS執行個體SDK Client對象
$client = getDkmsGcsSdkClient();
if (is_null($client)) exit(1);

//使用KMS進行對稱金鑰加解密樣本
aesEncryptDecryptSample();

/**
 * 使用KMS執行個體進行加解密樣本
 * @return void
 */
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;
        }
    }
}

/**
 * 加密樣本
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param string $keyId
 * @param string $plaintext
 * @param string $algorithm
 * @return AesEncryptContext
 */
function aesEncryptSample($client, $keyId, $plaintext, $algorithm)
{
    // 構建加密請求
    $encryptRequest = new EncryptRequest();
    $encryptRequest->keyId = $keyId;
    $encryptRequest->algorithm = $algorithm;
    $encryptRequest->plaintext = AlibabaCloudTeaUtils::toBytes($plaintext);
    $runtimeOptions = new RuntimeOptions();
    // 忽略服務端認證
    //$runtimeOptions->ignoreSSL = true;

    try {
        // 調用加密介面進行加密
        $encryptResponse = $client->encryptWithOptions($encryptRequest, $runtimeOptions);
        // 密鑰ID
        $keyId = $encryptResponse->keyId;
        // 主要金鑰是對稱金鑰時,decrypt介面需要加密返回的Iv
        $iv = $encryptResponse->iv;
        // 資料密文
        $cipher = $encryptResponse->ciphertextBlob;
        // 密碼編譯演算法
        $algorithm = $encryptResponse->algorithm;
        var_dump($encryptResponse->toMap());
        return new AesEncryptContext([
            'keyId' => $keyId,
            'iv' => $iv,
            'ciphertextBlob' => $cipher,
            'algorithm' => $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;
}

/**
 * 解密樣本
 * @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;
    $runtimeOptions = new RuntimeOptions();
    // 忽略認證
    //$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;
}

/**
 * 構建KMS執行個體SDK Client對象
 * @return AlibabaCloudDkmsGcsSdkClient
 */
function getDkmsGcsSdkClient()
{
    global $clientKeyContent, $password, $endpoint;

    // 構建KMS執行個體SDK Client配置
    $config = new AlibabaCloudDkmsGcsOpenApiConfig();
    //連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
    $config->protocol = 'https';
    //Client Key。
    $config->clientKeyContent = $clientKeyContent;
    //Client Key口令。
    $config->password = $password;
    //設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
    $config->endpoint = $endpoint;
    // 執行個體CA認證
    $config->caFilePath = 'path/to/caCert.pem';

    // 構建KMS執行個體SDK Client對象
    return new AlibabaCloudDkmsGcsSdkClient($config);
}


/**
 * The aes encrypt context may be stored
 */
class AesEncryptContext
{
    public function __construct($config = [])
    {
        if (!empty($config)) {
            foreach ($config as $k => $v) {
                $this->{$k} = $v;
            }
        }
    }
    /**
     * @var string
     */
    public $keyId;

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

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

    /**
     * @var string
     * Use default algorithm value, if the value is not set
     */
    public $algorithm;
}

程式碼範例解析

初始化用戶端

關於初始化用戶端的詳細介紹,請參見初始化用戶端

<?php

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


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

    // 構建KMS執行個體SDK Client配置
    $config = new AlibabaCloudDkmsGcsOpenApiConfig();
    //連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
    $config->protocol = 'https';
    //Client Key。
    $config->clientKeyContent = $clientKeyContent;
    //Client Key口令。
    $config->password = $password;
    //設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
    $config->endpoint = $endpoint;
    // 執行個體CA認證
    $config->caFilePath = 'path/to/caCert.pem';

    // 構建KMS執行個體SDK Client對象
    return new AlibabaCloudDkmsGcsSdkClient($config);
}

調用Encrypt介面使用對稱金鑰對資料加密

/**
 * 加密樣本
 * @param AlibabaCloudDkmsGcsSdkClient $client
 * @param string $keyId
 * @param string $plaintext
 * @param string $algorithm
 * @return AesEncryptContext
 */
function aesEncryptSample($client, $keyId, $plaintext, $algorithm)
{
    // 構建加密請求
    $encryptRequest = new EncryptRequest();
    $encryptRequest->keyId = $keyId;
    $encryptRequest->algorithm = $algorithm;
    $encryptRequest->plaintext = AlibabaCloudTeaUtils::toBytes($plaintext);
    $runtimeOptions = new RuntimeOptions();
    // 忽略服務端認證
    //$runtimeOptions->ignoreSSL = true;

    try {
        // 調用加密介面進行加密
        $encryptResponse = $client->encryptWithOptions($encryptRequest, $runtimeOptions);
        // 密鑰ID
        $keyId = $encryptResponse->keyId;
        // 主要金鑰是對稱金鑰時,decrypt介面需要加密返回的Iv
        $iv = $encryptResponse->iv;
        // 資料密文
        $cipher = $encryptResponse->ciphertextBlob;
        // 密碼編譯演算法
        $algorithm = $encryptResponse->algorithm;
        var_dump($encryptResponse->toMap());
        return new AesEncryptContext([
            'keyId' => $keyId,
            'iv' => $iv,
            'ciphertextBlob' => $cipher,
            'algorithm' => $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;
}

調用Decrypt介面使用對稱金鑰解密密文

/**
 * 解密樣本
 * @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;
    $runtimeOptions = new RuntimeOptions();
    // 忽略認證
    //$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;
}