网络游戏防沉迷实名认证系统提供的样例代码有误

解决办法,直接换成 “AES/GCM/NoPadding” 就可以
 private static String aesGcmEncrypt(String content, byte[] key) {
        try {
            // 根据指定算法ALGORITHM自成密码器
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            SecretKeySpec skey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            //获取向量
            byte[] ivb = cipher.getIV();
            byte[] encodedByteArray = cipher.doFinal(content.getBytes(UTF_8));
            byte[] message = new byte[ivb.length + encodedByteArray.length];
            System.arraycopy(ivb, 0, message, 0, ivb.length);
            System.arraycopy(encodedByteArray, 0, message, ivb.length, encodedByteArray.length);
            return Base64.getEncoder().encodeToString(message);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException
                | BadPaddingException e) {
            //建议自行调整为日志输出或抛出异常
            return null;
        }
    }

解释:

JDK 8 的宽松校验
JDK 8 的加密提供者(如 SunJCE)在解析算法名称时,对不兼容的参数(如 GCM 模式下的填充方式)可能采取以下行为:

自动忽略填充参数:即使指定了 PKCS5Padding,实际仍按 NoPadding 处理。

静默默认行为:不抛出异常,但实际未应用填充(因为 GCM 不需要填充)。

这意味着以下代码在 JDK 8 中可能“看似可用”,但实际是错误写法:

java
复制
Cipher cipher = Cipher.getInstance(“AES/GCM/PKCS5Padding”); // JDK 8 可能不报错
JDK 17 的严格遵循标准
从 JDK 9 开始,Oracle 逐步加强了对加密算法的标准化校验。在 JDK 17 中:

严格校验算法名称:如果填充方式与模式不兼容(如 GCM + PKCS5Padding),直接抛出 NoSuchPaddingException。

强制规范使用:要求开发者明确使用 NoPadding,因为 GCM 是流密码模式,不需要填充。

Logo

网易易盾是国内领先的数字内容风控服务商,依托网易二十余年的先进技术和一线实践经验沉淀,为客户提供专业可靠的安全服务,涵盖内容安全、业务安全、应用安全、安全专家服务四大领域,全方位保障客户业务合规、稳健和安全运营。

更多推荐