Android Gson@SerializedName使用动态加密键避免反编译泄露方案问询
解决方案
由于Java/Kotlin注解的参数必须是编译期常量,@SerializedName 本身不支持直接传入运行时才能得到的动态值,我们可以通过以下两种合规方案实现反编译不泄露JSON键名的需求:
方案1:自定义Gson字段命名策略 + 原生层存储键名映射
放弃在实体类中通过@SerializedName写死明文键名,将所有JSON键名与类字段的映射关系加密后存储在JNI原生so库中,运行时调用native方法解密得到完整映射表。自定义实现Gson的FieldNamingStrategy接口,在解析时动态匹配字段对应的解密后JSON键名即可。
示例实现:
// 自定义字段命名策略 class DynamicKeyNamingStrategy : FieldNamingStrategy { override fun translateName(field: Field): String { // 调用原生方法获取对应字段的解密后JSON键名 return NativeKeyProvider.getJsonKey(field.declaringClass.name, field.name) } } // 初始化Gson时绑定自定义策略 val safeGson = GsonBuilder() .setFieldNamingStrategy(DynamicKeyNamingStrategy()) .create() // 实体类无需添加@SerializedName注解,字节码中无明文键名 data class SomeResponse( val header: String )
该方案无需改动原有实体类的结构,运行时解析逻辑完全由Gson自动完成,原生so的逆向难度远高于dex字节码,可有效避免键名泄露。可额外在原生层添加应用签名校验逻辑,只有签名匹配时才返回正确的键名映射,进一步提升安全性。
方案2:使用kotlinx.serialization自定义动态序列化逻辑
切换到kotlinx.serialization序列化库,通过自定义序列化器实现运行时动态读取解密后的键名映射,无需在注解中写死明文键名。该库为编译期生成序列化/反序列化代码,运行效率与Gson相当,完全不需要手动处理JSON解析逻辑。
内容的提问来源于stack exchange,提问作者Amir Raza
相关产品推荐
相关产品推荐

