高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是目前对称密钥加密中比较通用的一种加密方式。

AES密钥有什么用

支付宝开放平台所有OpenAPI均支持对接口的请求内容和响应内容进行AES加密。加密后,在网络上传输的接口报文内容将会由明文内容变为密文内容,可以大大提升接口内容传输的安全性。

AES密钥与RSA密钥的关系

  • AES密钥是对接口请求和响应内容进行加密,密文无法被第三方识别,从而防止接口传输数据泄露。
  • RSA密钥是对接口请求和响应内容进行签名,开发者和支付宝开放平台分别加签验签,以确认接口传输的内容没有被篡改。不论接口内容是明文还是密文,RSA均可正常签名。
  • 开发者可对请求参数先做AES加密,然后对密文进行RSA签名。
  • AES密钥使用说明

    配置AES密钥

    AES密钥配置入口有以下3处:

    1. 登录支付宝开放平台创建任意类型应用并审核通过后在“应用详情-应用环境”页面可见。

    2. 在应用详情页

    3. 账户密钥管理页面点击配置AES密钥


    首次使用,点击“生成AES密钥”后即可查看并使用由开放平台自动生成的AES密钥。

    使用AES密钥加解密

    请求报文加密

    开放平台支持开发者自行对请求参数做AES加密然后再做RSA签名提交请求。 以下是AES加密java示例处理逻辑(注:若您使用PHP,可能需要自行安装用于加密的php扩展)。

  • AES密钥:即在支付宝页面上生成的AES密钥;
  • 原文:biz_content的值;
  • 字符集:加密原文会按该字符集转换为对应的编码(请保证和签名过程一致的字符集);
  • 加密算法:AES/CBC/PKCS5Padding
  • 其它语言基本的加密逻辑一样,需要注意的是对加密后得到字节数组需要先做base64编码,然后再新建字符串(由于base64后的字节一定是ASCII范围内,所以最后一步new String的时候无需指定字符集)。

    public static String encrypt() throws Exception {
            String key = "开发者自己的AES秘钥";
            String content = "需要加密的参数";
            String charset = "项目使用的字符编码集";
            String fullAlg = "AES/CBC/PKCS5Padding";
            Cipher cipher = Cipher.getInstance(fullAlg);
            IvParameterSpec iv = new IvParameterSpec(initIv(fullAlg));
            cipher.init(Cipher.ENCRYPT_MODE,
                    new SecretKeySpec(Base64.decodeBase64(key.getBytes()), "AES"),
            byte[] encryptBytes = cipher.doFinal(content.getBytes(charset));
            return new String(Base64.encodeBase64(encryptBytes));
         * 初始向量的方法, 全部为0. 这里的写法适合于其它算法,针对AES算法的话,IV值一定是128位的(16字节).
         * @param fullAlg
         * @return
         * @throws GeneralSecurityException
        private static byte[] initIv(String fullAlg) throws GeneralSecurityException {
            Cipher cipher = Cipher.getInstance(fullAlg);
            int blockSize = cipher.getBlockSize();
            byte[] iv = new byte[blockSize];
            for (int i = 0; i < blockSize; ++i) {
                iv[i] = 0;
            return iv;
    

    响应报文解密

    如开发者对请求参数做了AES加密,针对支付宝回复报文,开发者需要先验签,再解密。若支付宝对回复报文进行了加密,您得到的支付宝回复报文会和之前有细微差别。判断报文是否加密以及密文的获取和报文格式是xml还是json有关系,具体如下(以下报文为方便展示均做了格式化):

  • xml格式:
    若存在xml根节点的第一个子节点为response_encrypted,后面紧跟着sign节点,则该报文为加密的报文,密文存放在response_encrypted中。作为对比可以参考下图中“加密前”的内容。

    对验签的影响:验签取原文的逻辑和未加密时一致,取的是<XXX_response>和<sign>之间的内容。若之前取验签原文的逻辑不是通过这种方式取的话,可能会导致验证支付宝签名时失败。
  • json格式:
    识别该结果是密文的方式是response后的结果是字符串(双引号开头)而不是json对象(大括号开头),密文为引号内的内容。作为对比可以参考下图中“加密前”的内容。

    对验签的影响:验签的原文和原来一致,是"XXX_response":和"sign"之间的内容(包括双引号)。若之前取验签原文的逻辑不是通过这种方式取的话,可能会导致验证支付宝签名时失败。
  • 以下是AES解密java示例代码:

    * @param content 密文 * @param key aes密钥 * @param charset 字符集 * @return 原文 * @throws EncryptException public String decrypt(String content, String key, String charset) throws Exception { //反序列化AES密钥 SecretKeySpec keySpec = new SecretKeySpec(Base64.decodeBase64(key.getBytes()), "AES"); //128bit全零的IV向量 byte[] iv = new byte[16]; for (int i = 0; i < iv.length; i++) { iv[i] = 0; IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); //初始化加密器并加密 Cipher deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); deCipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); byte[] encryptedBytes = Base64.decodeBase64(content.getBytes()); byte[] bytes = deCipher.doFinal(encryptedBytes); return new String(bytes);

    更新AES密钥


    如果需要更新AES密钥,可以打开配置AES密钥浮层,并点击“重新生成AES密钥”按钮。

    注意:
    AES密钥一旦变更,新密钥立即启用,同时原密钥将立即失效。请确保在切换密钥过程中,涉及到的相关业务能够做容错处理。

    SDK加解密支持

    开发者要用AES加密方法,可参考示例自行编写。

    开发者如果用SDK调用接口,只需要做两件事:

    1、调用这个AlipayClient构造方法:com.alipay.api.DefaultAlipayClient#DefaultAlipayClient(String, String, String, String, String, String, String, String, String),最后两个参数分别传递openhome的aes密钥,和加密算法“AES”;

    2、对于每一个接口对应的请求类,调用它的setNeedEncrypt方法,设置为true就可以了。

    关于此文档暂时还没有FAQ