如何安全存储SMTP密码等常量 解决Constants.kt明文存储风险
安全存储SMTP密码的可行方案
你可以根据应用的部署场景选择对应方案:
场景1:Kotlin后端服务
- 环境变量注入
把敏感配置完全从代码中剥离,打包时不会写入二进制文件,服务启动时从运行环境的环境变量读取即可。修改后的代码示例:
const val SMTP_HOST = "smtp.gmail.com" const val SMTP_USER = "test@test.com" // 运行时从环境变量读取密码,无配置直接抛出异常避免运行出错 val SMTP_PASSWORD: String = System.getenv("SMTP_PASSWORD") ?: error("未配置SMTP密码环境变量")
部署时只需要在服务器/运行容器中配置对应环境变量即可,代码仓库、打包产物中都不会出现明文密码。
- 配置中心加密存储
如果是中大型项目,可以把敏感配置存入配置中心,配置本身提前做对称加密,只有服务启动拉取后在内存解密使用,不会出现明文落盘的情况。
场景2:安卓端Kotlin应用
特别提示:安卓端不存在绝对安全的本地存储方案,所有本地存储的敏感信息都有被逆向破解的可能,最优方案是把发邮件逻辑迁移到后端,APP仅调用后端接口完成邮件发送,从根源上避免SMTP密码泄露到客户端。如果必须在客户端实现发邮件逻辑,可以用以下方案降低风险:
- 编译时注入配置
把密码存入项目根目录的local.properties(该文件默认不会提交到Git仓库),通过BuildConfig在编译时注入到代码中:
- 在
local.properties中添加配置:smtp.password=你的实际密码 - 模块级
build.gradle.kts中添加配置,把密码写入BuildConfig:
android { defaultConfig { val properties = Properties() properties.load(rootProject.file("local.properties").inputStream()) buildConfigField("String", "SMTP_PASSWORD", "\"${properties.getProperty("smtp.password")}\"") } }
- 业务代码直接读取
BuildConfig.SMTP_PASSWORD使用即可,密码不会出现在业务常量文件中,也不会被提交到代码仓库。
- 对称加密存储
把加密后的密码字符串写入代码,运行时用密钥解密后使用,密钥可以拆成多段分散在不同类中,大幅提升逆向破解的门槛。 - 针对谷歌邮箱的优化:不要直接使用账号主密码,前往谷歌账号后台创建应用专用密码,即使密码泄露也可以单独吊销,不会影响主账号安全,同时开启两步验证降低账号被盗风险。
通用注意事项:任何场景下都不要把明文敏感信息提交到公开/内部代码仓库,哪怕是私有仓库也不建议存储明文敏感配置。
内容的提问来源于stack exchange,提问作者André Nogueira
相关产品推荐
相关产品推荐

