本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
【腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
市面上有不少围绕 AI 给微信搞出一些花样的开源项目,不少都是通过从内存中获取 SQLite 加密密钥获得破解的。
以前 Java 的一些密码框也可能被黑客通过内存数据读取获得破解,虽然后来做了加强。但 JFR 进程内数据脱敏方面始终是 Java 中长期被忽视的安全隐患。
JFR(JDK Flight Recorder)是 Java 生产环境诊断的“瑞士军刀”,但它存在一个严重的数据安全问题,像密码、Token、API Key 等敏感信息会以明文形式记录在 .jfr 文件中。为了解决这类问题,JDK 27 的 JEP 536 终于决定从源头解决这个问题了。所以,接下来,我就通过本文带领大家全面了解这个新特性的来龙去脉吧。
JEP 536 是什么?
全称是,JEP 536: JFR In-Process Data Redaction,翻译过来就是 JFR 进程内数据脱敏。
它能增强 JDK Flight Recorder,使其在数据离开进程之前就对命令行参数、环境变量和系统属性的初始值进行脱敏处理,防止敏感信息泄露。
简单来说,以前的 JFR 记录文件里密码是明文,现在默认变成 [REDACTED] 了。
文章配图参见 https://mp.weixin.qq.com/s/Lcp9pvGe74eaWlUBAqHiew。
JEP 536 的时间线
JEP 536 这个特性从提出到正式 GA,不到 1 年时间,是 Java 里进展比较快的特性之一。上一次这么快落地的特性当属 Jdk 26 中 Comparator 新增的 min(T, T) 和 max(T, T) 默认方法,具体可以参考我的这篇文章《https://mp.weixin.qq.com/s/6JVvQQZdWoQlYQhSYQEFtA》。
下面这个表格是 JEP 536 的时间线。
| 时间节点 | 事件 |
|---|---|
| 2025 年 11 月 30 日 | JEP 536 草案(Draft)首次提交,JBS Issue: JDK-8372760 |
| 2026 年 5 月 20 日 | Mark Reinhold 在 jdk-dev 邮件列表正式提议将 JEP 536 Target 到 JDK 27 |
| 2026 年 5 月 26 日 | JEP 536 正式被 Target 到 JDK 27(review 无异议通过) |
| 2026 年 6 月 4 日 | JDK 27 进入 Rampdown Phase One(主分支冻结) |
| 2026 年 9 月 14 日 | JDK 27 GA(正式发布) |
截止目前,JEP 536 的状态为 Targeted,已确定随 JDK 27 一起发布。
为什么需要这个特性?
一切要从 JFR 的“安全隐患”说起。
密码正在 JFR 文件里裸奔
JFR 作为 HotSpot JVM 内置的低开销诊断框架,会记录大量运行时信息,包括下面几条。
jdk.InitialEnvironmentVariable—— 环境变量初始值jdk.InitialSystemProperty—— 系统属性初始值jdk.JVMInformation—— JVM 启动参数和命令行参数
这些信息对于排查问题非常有用,但它们往往包含敏感数据。
$ export ACCESS_TOKEN=SECRET_TOKEN
$ java -XX:StartFlightRecording:filename=dump.jfr \
-Xmx2G \
-Djavax.net.ssl.keyStorePassword=SECRET_PASSWORD \
-jar application.jar \
--dbpassword ANOTHER_SECRET_PASSWORD
在上面这个例子中,生成的 dump.jfr 文件会明文记录三个秘密值。
| 敏感信息 | 来源 | 记录位置 |
|---|---|---|
SECRET_TOKEN | 环境变量 ACCESS_TOKEN | jdk.InitialEnvironmentVariable |
SECRET_PASSWORD | 系统属性 javax.net.ssl.keyStorePassword | jdk.InitialSystemProperty |
ANOTHER_SECRET_PASSWORD | 命令行 --dbpassword | jdk.JVMInformation |
风险有多大?
主要体现在下面这 4 个方面。
- 共享诊断文件时泄露:将
.jfr文件发送给同事、上传到工单系统、或存档到共享网络驱动器时,敏感信息随之扩散 - GDPR 合规风险:欧洲的开发者对此深有体会——历史
.jfr日志中可能包含大量需要 GDPR 合规处理的敏感数据 - JVM 崩溃残留:事件数据在写入最终文件前会先写入临时目录,如果 JVM 崩溃,未脱敏的数据可能残留在临时目录中
- 流式传输风险:通过
FlightRecorderMXBean或RemoteRecordingStream流式传输时,未脱敏数据可能直接离开主机
正如 JVM Weekly 的评论:“For years, JFR has been an invaluable production profiling tool… But it carried a dirty secret”。多年来,JFR 一直是宝贵的生产环境分析工具 …… 但它藏着一个肮脏的秘密。
JEP 536 是如何解决的?
进程内脱敏(In-Process Redaction)
核心的关键原则是,在数据离开 JVM 进程之前完成脱敏,而不是事后处理。
这意味着:
- 临时文件中的数据也是脱敏后的
- 流式传输的数据也是脱敏后的
- 不需要事后手动运行
jfr scrub命令
默认脱敏规则
JEP 536 引入了默认脱敏过滤器,无需任何配置即可保护大部分常见敏感字段,开箱即用。
默认 redact-key 过滤器(环境变量 & 系统属性)举例如下。
*api*key*
*auth*
*client*secret*
*credential*
*jaas*config*
*jwt*
*passphrase*
*passwd*
*password*
*private*key*
*pwd*
*secret*
*token*
默认 redact-argument 过滤器(命令行参数)如下。
-*api*key *
-*client*secret *
-*credential *
...(类似 redact-key,但支持多参数匹配)
具体的匹配规则有如下 3 条。
- 不区分大小写
- 使用
Glob 模式(*和?作为通配符) - 匹配到的值替换为
[REDACTED]
使用方式
使用起来非常简单。通过 -XX:FlightRecorderOptions 的两个新子选项控制。
# 自定义脱敏规则
java -XX:FlightRecorderOptions:'redact-key=confidential,redact-argument=https://*:*@*' \
-XX:StartFlightRecording:filename=dump.jfr \
-jar application.jar
# 从文件加载过滤器
java '-XX:FlightRecorderOptions:redact-argument=@args.txt,redact-key=@keys.txt' ...
# 在默认规则基础上追加
java -XX:FlightRecorderOptions:'redact-key=+confidential;secret;@keys.txt' ...
# 完全禁用脱敏(恢复旧行为)
java -XX:FlightRecorderOptions:'redact-argument=none,redact-key=none' ...
多参数匹配
支持匹配参数序列,例如 --password SECRET 等。
# 匹配 --password 及其下一个参数
java -XX:FlightRecorderOptions:'redact-argument=--password *' ...
# 匹配 --password 及其后两个参数
java -XX:FlightRecorderOptions:'redact-argument=--password * *' ...
调试脱敏效果
可以执行下面的命令,查看输出结果。
# 开启调试日志,查看哪些参数被脱敏
java -Xlog:jfr+redact=debug ...
# 验证脱敏结果
jfr print --events InitialSystemProperty,JVMInformation,StringFlag,InitialEnvironmentVariable dump.jfr
输出示例。
jdk.InitialSystemProperty {
key = "confidential"
value = "[REDACTED]"
}
jdk.JVMInformation {
jvmArguments = "-Dconfidential=[REDACTED]"
javaArguments = "-jar application.jar [REDACTED] --verbose"
}
社区反响
JVM Weekly 在报道 JDK 27 特性时用了一个词评价 JEP 536,finally 终于。这代表了社区对这个长期存在问题的共同心声。
当然,在 JEP 536 之前,社区里也已经有了一些 临时解决方案 workaround。
| 方案 | 缺点 |
|---|---|
jfr scrub 命令事后处理 | 重复且容易出错;无法处理 JVM 崩溃残留 |
禁用特定事件(如 InitialEnvironmentVariable#enabled=false) | 配置繁琐;可能误删非敏感数据 |
第三方工具 jfr-redact | 需要额外依赖;仍是事后处理 |
JEP 536 的设计者明确拒绝了这些替代方案,选择从源头解决问题。
为什么不用正则表达式?
JEP 文档中解释了为什么选用 Glob 模式而非正则表达式,给出了下面 3 个解释。
- HotSpot 的 C++ 正则库可能抛出异常,而 HotSpot 中禁止异常
- 使用
java.util.regex会增加启动时间,且在某些场景下无法从 JVM upcall 到 Java - 实践经验表明,正则表达式的表达能力很少是真正必需的
总结
JEP 536 是一个看似“较小”但影响深远的特性。它解决了 JFR 在生产环境使用中长期存在的安全隐患,体现了 Java 平台对安全默认(Secure by Default)原则的坚持。
它也带来了零配置安全、诊断能力不损失、透明可验证、安全共享、合规友好、降低人为失误、缩小攻击面、覆盖崩溃场景等方面的安全性。
当然,如果大家在某些场景下需要用到明文信息,或遇到技术问题,也可以选择回退到旧行为,只需添加下面的参数即可。
java -XX:FlightRecorderOptions:'redact-argument=none,redact-key=none' ...
控制,JDK 27 将于 2026 年 9 月 14 日正式发布。如果大家的生产环境大量使用 JFR 进行诊断,这个特性就非常值得大家的关注和升级了。

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » JDK 27 增强 JFR,JEP 536 让密码等敏感数据不再裸奔