全部产品
Search
文档中心

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

更新时间:Feb 27, 2026

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

适用范围

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

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

说明

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

准备工作

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

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

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

步骤二:创建密钥

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

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

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

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

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

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

阿里云账号默认有所有资源的Administrator权限且不可修改,其AccessKey泄露会危及资源安全,因此强烈建议不要为主账号创建AccessKey,请创建专用于API访问的RAM用户并创建对应的AccessKey,并完成最小化授权。具体操作,请参见创建AccessKey

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

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

    image

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

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

      KMS内置了系统权限策略,可以直接绑定到RAM用户,详细介绍,请参见密钥管理服务系统权限策略参考。您也可以自定义权限策略。image

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

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

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

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

说明

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

特性

共享网关

专属网关

Endpoint

kms.<RegionId>.aliyuncs.com

<YOUR_KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com

CA证书

无需配置。

必须配置。

适用场景

公网访问、开发测试。

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

获取方式

具体请参见Endpoint

在实例的详情页面,下载实例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;
import java.nio.charset.StandardCharsets;

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>")
                // 设置待加密的明文。Plaintext需为字节数组,SDK会自动进行Base64编码。
                .setPlaintext(plaintext.getBytes(StandardCharsets.UTF_8));

        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;
import java.nio.charset.StandardCharsets;

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());
            
            // 从响应中获取解密后的明文字节数组。
            byte[] plaintextBytes = response.getBody().getPlaintext().getBytes();
            
            // 根据业务需要将字节数组转换为字符串。
            String plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);
            
            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"));
        }        
    }
}