0

0

使用反射实现基于标签的字段加密与解密处理

P粉602998670

P粉602998670

发布时间:2026-02-11 11:55:02

|

330人浏览过

|

来源于php中文网

原创

Java反射获取@Encrypt注解失败主因是ClassLoader不一致,需确认注解RetentionPolicy.RUNTIME、避免混淆打包、比对类加载器;JDK17+需--add-opens开放模块;加密后保持字段类型、加前缀幂等控制、禁用setter自动加密。

使用反射实现基于标签的字段加密与解密处理

Java 反射获取 @Encrypt 字段时 ClassLoader 不一致导致找不到注解

反射读不到自定义注解,大概率是注解类被不同 ClassLoader 加载了两次——比如你用 Spring Boot 打成 fat jar,而注解定义在某个被 spring-boot-loader 隔离的依赖里。此时 field.isAnnotationPresent(Encrypt.class) 永远返回 false,哪怕源码里明明写了。

实操建议:

  • 确认 @Encrypt 注解的 @Retention(RetentionPolicy.RUNTIME) 已声明,且没被 ProGuard 或 JVM 参数(如 -XX:+UseSplitVerifier)意外剥离
  • 检查注解类是否和目标字段类处于同一 classpath 路径;若注解在独立 module 中,确保它没被 shade、repackage 或多版本 JAR 冲突覆盖
  • 调试时打印 Encrypt.class.getClassLoader()targetObject.getClass().getClassLoader(),不相等就直接停在这一步——别往下写加密逻辑了

Field.setAccessible(true) 在 JDK 17+ 上被强限制,私有字段读写失败

JDK 17 默认启用强封装(--illegal-access=deny),setAccessible(true) 对非模块化代码会抛 InaccessibleObjectException,不是 SecurityException,老办法 catch 住没用。

实操建议:

  • 启动参数加 --add-opens java.base/java.lang=ALL-UNNAMED(如果操作的是 String 等基础类型字段)或对应包名,例如 --add-opens your.module/your.package=ALL-UNNAMED
  • 避免反射修改 final 字段:JDK 12+ 对 final 字段的 set() 会静默失败或抛异常,即使 setAccessible(true) 成功
  • 优先用 MethodHandles.privateLookupIn() 替代传统反射(JDK 9+),它更安全且绕过部分模块检查,但要求目标类必须可访问

加密逻辑嵌入反射调用后,JSON 序列化出现循环引用或空值跳过

你用反射把字段值加密后塞回对象,但后续用 ObjectMapper.writeValueAsString() 输出 JSON 时,发现加密字段没出现,或者整个对象序列化卡死——常见原因是加密后字段类型变了(比如 Stringbyte[]),而 Jackson 默认不序列化非标准类型,或加密过程意外触发了 getter/setter 的副作用。

Interior AI
Interior AI

AI室内设计,上传室内照片自动帮你生成多种风格的室内设计图

下载

实操建议:

  • 加密后保持字段原始类型:不要把 String password 改成 byte[] encryptedPassword,而是用 Base64 编码为 String 存回原字段
  • 给加密字段加 @JsonIgnore,改用 @JsonGetter/@JsonSetter 控制序列化行为,避免反射和序列化逻辑耦合
  • 别在反射加密时调用业务 getter:有些 getter 会懒加载关联对象,一触发就带出整棵树,JSON 序列化时直接栈溢出

同一个字段多次反射加密导致重复加盐或密文嵌套

没做幂等控制,比如 HTTP 请求重试、AOP 切面重复执行、或对象被多次传入加密工具类,结果一个 password 字段被 AES 加密了三次,解密时要套三层才能拿到明文,而且每次加盐不同,根本不可逆。

实操建议:

  • 在字段值上做简单标记,比如加密后追加固定前缀 "ENC_v1_",解密前先 value.startsWith("ENC_v1_") 判断是否已处理
  • 不依赖字段值判断?那就用 ThreadLocal> 记录当前线程已处理过的字段,适合单次请求生命周期内防重入
  • 绝对不要在实体类的 setter 里自动加密——这会让调用方完全无法感知数据状态,debug 时字段看着是密文,以为是初始化问题,其实是 setter 悄悄干的

反射本身不关心业务语义,它只忠实地执行你写的每行代码。字段是不是该加密、加几次、用什么密钥、密文要不要持久化……这些决策点全在反射调用之外,但最容易被当成“反射的事”甩锅给反射。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

233

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

345

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

212

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

401

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

322

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

196

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

762

2025.06.17

Rust异步编程与Tokio运行时实战
Rust异步编程与Tokio运行时实战

本专题聚焦 Rust 语言的异步编程模型,深入讲解 async/await 机制与 Tokio 运行时的核心原理。内容包括异步任务调度、Future 执行模型、并发安全、网络 IO 编程以及高并发场景下的性能优化。通过实战示例,帮助开发者使用 Rust 构建高性能、低延迟的后端服务与网络应用。

1

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号