全部产品
Search
文档中心

密钥管理服务:使用KMS密钥在线加密和解密数据

更新时间:Aug 25, 2026

在部署于阿里云或其他云环境的公网IP资产中,敏感数据需要安全存储与传输以降低泄露风险并满足合规要求。针对体量较小的敏感数据对象,可直接通过密钥管理服务(KMS)在线执行加密与解密操作。本文介绍在线加解密的使用场景、前置条件及具体操作步骤。

适用范围

  • 单次使用对称密钥加解密的数据不超过6 KB。

  • 单次使用非对称密钥加解密的数据不超过1KB。

说明

单次加密的数据量越大,网络传输失败可能性越大,网络传输所需时间越长,KMS实例对数据进行加解密所需时间也越长。

密钥安全须知

警告

请勿在前端代码中存储加密密钥。前端 JavaScript 代码会完整下发到用户浏览器,通过浏览器开发者工具可直接查看并提取代码中的密钥值。无论是对称密钥非对称密钥的私钥,还是用于访问 KMS 的 AccessKey,一旦嵌入前端代码即视为已泄露。密钥泄露后,攻击者可解密全部历史密文,加密保护随之失效。

推荐做法是前端不持有任何密钥材料,加解密操作全部收敛到后端完成:

  1. 前端通过 HTTPS 将敏感数据传输到后端服务器,传输过程由 TLS 保证机密性。

  2. 后端服务器调用 KMS 的 EncryptAsymmetricEncrypt 接口完成加密,并将密文写入数据库等存储。

  3. 需要还原明文时,同样由后端调用 DecryptAsymmetricDecrypt 接口解密,再按业务需要将结果返回前端。

采用该架构后,密钥材料始终托管在 KMS 实例内,不出 KMS 边界;后端只持有访问 KMS 的凭证,前端全程不接触密钥。

准备工作

在开始调用API进行加解密前,请完成以下准备工作。

步骤一:购买并启用KMS实例

请根据业务需求和安全合规要求,购买并启用一个KMS实例(软件密钥管理实例和硬件密钥管理实例)。具体操作,请参见购买和启用 KMS 实例

步骤二:创建密钥

根据加密场景,在已启用的KMS实例中创建相应的密钥。

  • 对称密钥:用于在信任环境内进行加解密。

  • 非对称密钥:用于跨信任环境的场景,例如客户端使用公钥加密,服务端使用私钥解密。

具体操作,请参见创建密钥

步骤三:准备访问凭证与权限

本文以AccessKey方式为例,更多访问凭证说明,请参见创建访问凭证

AccessKey

警告

阿里云账号默认有所有资源的 Administrator 权限且不可修改,为了确保资源安全,建议使用 RAM 用户创建 AccessKey,并根据需求进行最小化授权。

  1. 登录RAM 控制台,在页用户面,单击目标 RAM 用户名称。

  2. 认证管理页签下的AccessKey区域,单击创建 AccessKey,并按照指引完成创建。

  3. 授予 RAM 用户访问 KMS 的权限。

    • 方式一:设置基于身份的策略

      单击 RAM 用户操作列的新增授权,直接绑定 KMS 内置系统权限策略到 RAM 角色。KMS 内置系统权限策略,请参见密钥管理服务系统权限策略参考

      说明

      同时支持自定义权限策略,具体操作请参见创建自定义权限策略

    • 方式二:设置基于资源的策略

      KMS 支持基于资源的策略,即为单个密钥和凭据设置访问权限,用于控制哪些阿里云账号、RAM 用户、RAM 角色有权限来管理或使用 KMS 密钥、凭据。详细介绍,请参见密钥策略凭据策略

步骤四:获取连接信息和CA证书

调用API时,需要根据网络环境选择合适的网关地址(Endpoint)。

说明

本文示例默认使用专属网关

特性

共享网关

专属网关

Endpoint

kms.<RegionId>.aliyuncs.com

<YOUR_KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com

CA证书

无需配置。

必须配置。

适用场景

公网访问、开发测试。

VPC内网访问、生产环境、更高性能和隔离性。

获取方式

具体请参见阿里云SDK

在实例的详情页面,下载实例CA证书,并获取实例VPC地址

应用场景

场景一:应用部署在阿里云上

阿里云上部署的应用服务会产生或收到明文形式的敏感数据,敏感数据需要加密后再通过数据库等方式存储,该场景推荐使用对称加密算法。

相关API

API名称

说明

Encrypt

使用对称主密钥加密明文

Decrypt

使用对称密钥进行解密。

示例代码

加密数据 (Encrypt)

以下示例代码演示了如何调用 Encrypt 接口,使用对称密钥将明文加密成密文。

package com.aliyun.sample;

import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.EncryptRequest;
import com.aliyun.kms20160120.models.EncryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;

public class SymmetricEncryptSample {

    public static Client createClient() throws Exception {
        // 使用环境变量中获取的AccessKey ID和AccessKey Secret初始化Client。
        // 请确保代码运行环境已设置环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        Config config = new Config()
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        
        // 设置专属网关Endpoint。
        config.endpoint = "<Your-KMS-Instance-Endpoint>"; 
        // 设置KMS实例的CA证书内容。
        config.ca = "<Your-CA-Certificate-Content>";
        
        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        Client client = createClient();
        
        // 待加密的明文。
        String plaintext = "this is a test message.";
        
        EncryptRequest encryptRequest = new EncryptRequest()
                // 设置要使用的对称密钥ID。
                .setKeyId("<Your-Symmetric-Key-Id>")
                // 设置待加密的明文。
                .setPlaintext(plaintext);

        try {
            // 调用Encrypt接口。
            EncryptResponse response = client.encryptWithOptions(encryptRequest, new RuntimeOptions());
            
            // 从响应中获取Base64编码的密文。
            String ciphertextBlob = response.getBody().getCiphertextBlob();
            
            System.out.println("Plaintext: " + plaintext);
            System.out.println("Ciphertext (Base64): " + ciphertextBlob);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

解密数据 (Decrypt)

以下示例代码演示了如何调用 Decrypt 接口,将密文解密成明文。

package com.aliyun.sample;

import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.DecryptRequest;
import com.aliyun.kms20160120.models.DecryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;

public class SymmetricDecryptSample {

    public static Client createClient() throws Exception {
        // Client初始化逻辑同加密示例。
        Config config = new Config()
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "<Your-KMS-Instance-Endpoint>";
        config.ca = "<Your-CA-Certificate-Content>";
        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        Client client = createClient();
        
        // 待解密的密文,必须是来自Encrypt接口返回的Base64编码字符串。
        String ciphertextBlob = "<Ciphertext-From-Encryption-Step>";
        
        DecryptRequest decryptRequest = new DecryptRequest()
                // 设置待解密的密文。
                .setCiphertextBlob(ciphertextBlob);

        try {
            // 调用Decrypt接口。
            DecryptResponse response = client.decryptWithOptions(decryptRequest, new RuntimeOptions());
            
            // 从响应中获取解密后的明文。
            String plaintext = response.getBody().getPlaintext();
            
            System.out.println("Ciphertext (Base64): " + ciphertextBlob);
            System.out.println("Decrypted Plaintext: " + plaintext);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

场景二:应用部署在阿里云上和阿里云外

推荐使用非对称加密算法,实现云外加密、云上解密的业务场景。

  • 云外应用使用公钥加密数据,并将密文传输至云上应用。

  • 云上应用接收到密文后,调用KMS实例通过私钥完成解密。

相关API

API名称

说明

AsymmetricEncrypt

使用非对称密钥进行加密。

AsymmetricDecrypt

使用非对称密钥进行解密。

示例代码

加密

package com.aliyun.sample;

import com.aliyun.tea.*;

public class Sample {

    /**
     * <b>description</b> :
     * <p>使用凭据初始化账号Client</p>
     * @return Client
     * 
     * @throws Exception
     */
    public static com.aliyun.kms20160120.Client createClient() throws Exception {
        // 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://www.alibabacloud.com/help/document_detail/378657.html。
         com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
        //KMS实例CA证书
        config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
        return new com.aliyun.kms20160120.Client(config);
    }

    public static void main(String[] args) throws Exception {    
        com.aliyun.kms20160120.Client client = Sample.createClient();
         com.aliyun.kms20160120.models.AsymmetricEncryptRequest asymmetricEncryptRequest = new com.aliyun.kms20160120.models.AsymmetricEncryptRequest()
                .setPlaintext("test")
                .setKeyId("a06e2410-*****-330777ee1825")
                .setKeyVersionId("key-hzz65f17868e6cl0n****")
                .setAlgorithm("RSAES_OAEP_SHA_256");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.kms20160120.models.AsymmetricEncryptResponse resp = client.asymmetricEncryptWithOptions(asymmetricEncryptRequest, runtime);
            System.out.println(new com.google.gson.Gson().toJson(resp));
        } catch (TeaException error) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
        }        
    }
}

解密

public class Sample {
 
    /**
     * <b>description</b> :
     * <p>使用凭据初始化账号Client</p>
     * @return Client
     * 
     * @throws Exception
     */
    public static com.aliyun.kms20160120.Client createClient() throws Exception {
       // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        // 专属网关Endpoint 
        config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
        //KMS实例CA证书
        config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
        return new com.aliyun.kms20160120.Client(config);
    }
 
    public static void main(String[] args_) throws Exception {
        
       public static void main(String[] args_) throws Exception {
        
        com.aliyun.kms20160120.Client client = Sample.createClient();
        com.aliyun.kms20160120.models.AsymmetricDecryptRequest asymmetricDecryptRequest = new com.aliyun.kms20160120.models.AsymmetricDecryptRequest()
                .setKeyId("a06e2410-*****-330777ee1825")
                .setKeyVersionId("key-hzz65f17868e6cl0n****")
                .setAlgorithm("RSAES_OAEP_SHA_256")
                .setCiphertextBlob("FV9i23PQdpGPvc*********MA==");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.kms20160120.models.AsymmetricDecryptResponse resp = client.asymmetricDecryptWithOptions(asymmetricDecryptRequest, runtime);
            System.out.println(new com.google.gson.Gson().toJson(resp));
        } catch (TeaException error) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
        }        
    }
}