4、阿里云 KMS 入门:开通、创建密钥、API 与 SDK 集成、权限策略

好,咱们开始动手了。这一章我们直接进阿里云控制台,把 KMS 用起来。说白了,就是搞清楚三件事:怎么把密钥建出来、怎么用代码去调它、以及怎么控制谁有权限调它。

我自己的习惯是,先不要急着写代码。先把云上的东西搭好,把权限理清,后面集成起来才不会被卡住。嗯,咱们一步一步来。

4.1 开通 KMS 服务

这一步其实最简单,但很多人会忽略一个点——区域选择。

  • 登录阿里云控制台,搜索“密钥管理服务”。
  • 选择区域:我个人建议选离你的应用服务器最近的区域,比如你在华东就选上海。原因很简单:API 延迟会低一些,而且跨区域调用可能要额外加公网流量费用。
  • 开通服务:点“立即开通”。KMS 按调用量和存储量计费,自己测试的话,花不了几个钱。
小提示:开通后先别急着创建密钥。先去 RAM 里看一眼,给你的主账号或者子账号授权一个叫“AliyunKMSFullAccess”的权限。不然你可能会遇到“Forbidden”或者“没有权限”的问题。我在项目里就被这个卡了十几分钟,后来发现是 RAM 策略没挂上。

4.2 创建密钥(对称与非对称)

服务开通了,接下来创建密钥。阿里云 KMS 的密钥分为两类:对称密钥和非对称密钥。怎么选?

特性 对称密钥(Aliyun_AES_256) 非对称密钥(Aliyun_RSA_2048 / EC_P256)
适用场景本地加密、大数据块加密、数据库加密数字签名、密钥交换、小报文加密
性能快,适合大量数据慢,通常只加密对称密钥或签名
使用方式直接调用 Encrypt / Decrypt调用 Sign / Verify 或 AsymmetricEncrypt
我个人的选择90% 场景选它,特别是做迁移的时候只有需要签名或跨域互认时才用

怎么做?在 KMS 控制台里找到“密钥管理”,然后点“创建密钥”。

  • 密钥类型:选“对称密钥”或“非对称密钥”。
  • 密钥规格:对称默认 AES_256,非对称看你业务需要,RSA_2048 足够用。
  • 别名:给个容易记的名字,比如 my-app-key。这个别名以后在代码里会用到。
  • 描述:写清楚这是给什么服务用的。等三个月回来,你会感谢自己写了描述。
注意事项:创建好的密钥默认是“已启用”状态。如果你不小心禁用了它,所有依赖这个密钥的解密请求都会失败。我曾经在计划停机维护时误操作禁用了密钥,结果线上应用全挂了,赶紧恢复。嗯,这个教训很深。

4.3 基本使用流程:API 调用与 SDK 集成

密钥有了,怎么用?两个路径:直接调 API,或者用阿里云的 SDK。咱们先看 API 调用,再讲 SDK 集成。

4.3.1 直接调用 KMS API

先看一个最常见的场景:加密一段数据。你需要构造一个 HTTPS 请求,到 KMS 的 Endpoint。

# 示例:调用 KMS Encrypt API(使用 Aliyun CLI)
# 前提:你已经配置好了 AccessKey 和 SecretKey

aliyun kms Encrypt \
  --KeyId "your-key-id" \
  --Plaintext "base64编码的明文数据" \
  --RegionId "cn-shanghai"

返回的结果里会包含 CiphertextBlob,这就是密文。你可以存到数据库或者文件里。

解密更简单:

# 解密 API
aliyun kms Decrypt \
  --CiphertextBlob "base64编码的密文数据" \
  --RegionId "cn-shanghai"

说白了,API 调用就是 HTTP 请求加签名。但真实生产环境里,谁愿意直接拼 HTTP 请求?一般都用 SDK。

4.3.2 集成阿里云 SDK(重点)

我个人强烈推荐用 Aliyun SDK for Java 或 Python。我自己在微服务项目里一直用 Java SDK,少写很多样板代码。

咱们拿 Java 举例,看一下怎么用 SDK 完成一次加解密:

// 1. 初始化 KMS Client(在应用启动时做一次)
import com.aliyuncs.kms.KmsClient;
import com.aliyuncs.kms.model.v20160120.*;

public class KmsHelper {
    private static KmsClient client = new KmsClient("cn-shanghai");

    // 2. 加密
    public static String encrypt(String plainText) {
        EncryptRequest request = new EncryptRequest();
        request.setKeyId("your-key-id");
        request.setPlaintext(Base64.getEncoder().encodeToString(plainText.getBytes()));
        EncryptResponse response = client.getAcsResponse(request);
        return response.getCiphertextBlob();
    }

    // 3. 解密
    public static String decrypt(String cipherText) {
        DecryptRequest request = new DecryptRequest();
        request.setCiphertextBlob(cipherText);
        DecryptResponse response = client.getAcsResponse(request);
        return new String(Base64.getDecoder().decode(response.getPlaintext()));
    }
}

这是最核心的用法。记好了,你从本地库迁移到 KMS,就是在原来调用加密库的地方,换成调用这个 KmsHelper。

关键配置:SDK 初始化时,需要设置 AccessKey 和 SecretKey。我建议你不要硬编码在代码里,而是用环境变量或者阿里云的凭据管家来管理,安全很多。

4.4 权限策略配置(RAM 策略)

这一步容易踩坑。KMS 使用的时候,如果你的程序或者子账号权限不够,会直接返回 AccessDenied。

权限控制的原理就是:给某个 RAM 用户或角色绑定一个策略,说明它能做什么。

4.4.1 最小权限原则

我不建议直接给“KMSFullAccess”。举个例子,你有一个微服务只需要解密,那就只给它解密的权限,不要给它创建密钥的权限。

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt"
            ],
            "Resource": "acs:kms:cn-shanghai:*:key/your-key-id"
        }
    ]
}

注意这里指定了具体的密钥 ARN。这样可以精确控制哪些密钥能被访问。

4.4.2 跨账户授权

如果你有多套环境(开发/测试/生产),建议不同环境用不同的 RAM 角色,并分别授权。我见过有人用一个密钥做所有环境,结果开发环境误删了密钥,生产也歇菜了。

这是 KMS 权限策略的核心模型:

KMS 访问控制链路 用户 / 应用 RAM 角色 / 策略 KMS 密钥 授权逻辑说明 RAM 策略控制“谁可以访问”——指定具体密钥 ARN 实现最小权限 API 调用通过 AccessKey 自动携带身份信息 ⚠️ 避坑:不要直接硬编码 AccessKey 建议通过环境变量或阿里云 RAM Role 自动获取临时凭证
避坑提醒:我曾经给一个服务只配了 Encrypt 权限,没配 Decrypt。结果上线后数据能写进去但读出来全失败。幸好是在灰度环境,不然后果严重。所以测试的时候一定把加密和解密的权限都验证一遍。

4.5 本章小结

这一章咱们完成了阿里云 KMS 的入门操作。从开通服务到创建密钥,再到用 API 和 SDK 加解密,最后用 RAM 策略锁死权限。这套流程,你在后面的章节里会反复用到。

记住我强调的三点:区域选对、权限给最小、AccessKey 别硬编码。做到这三点,后面的迁移就会顺畅很多。