硬编码密钥存在什么风险?
密钥暴露面越多,风险就越大
密钥硬编码在代码中导致的直接结果就是代码在哪里,密钥就在哪里。研发人员电脑上存在密钥,如果电脑被攻击则密钥也会被泄漏。其次研发人员会因为没有安全意识,将代码上传至各类私有云盘或家里电脑又或是U盘中,导致风险面增大。更有甚者,将代码上传至GitHub,而忽略了代码中的硬编码密钥,从而被恶意着利用,比如我曾经发现的控制某云厂商全部管理权限。
攻击者拿到硬编码密钥后攻击成本较低
攻击者无论通过什么方式拿到你代码,首先就会去看硬编码密钥部分,尝试去利用这些代码中的明文密钥,比如存在邮箱密码则会去尝试登陆你的邮箱进一步渗透挖掘邮件中有价值的内容,有FTP账号密码则会尝试连接FTP挖掘FTP Server中有价值的文件。
硬编码意味着你不会去变更它
当密钥硬编码在代码中时,改动密钥的成本就会增大,每次改动密钥时你需要额外进行应用发布和测试。而密钥的安全策略中,定期更换是最重要的因素,因为你无法知道在何时何处密钥泄漏过,因此定期更换密钥能降低风险。
硬编码密钥解决方案
核心点在于密钥需要和代码分离,尽可能少的让密钥被人接触到。以下方案只是减缓因人导致的安全风险,无法杜绝研发人员恶意通过各种手段去获取到真实Key并利用。
业内一般做法是通过配置管理中心来管理配置,密钥不适合明文存储因此配置管理中心需要对密钥进行加密,而配置管理中心也有多种实现方案。
标记位替换,代码中是一个标记<access_key_id>,当代码进行发布时,由集成系统调用配置管理中心,将代码中的密钥标记替换为真实代码后再发布到服务器中。(此时要确保服务器的权限管控是最小化)
环境变量/配置文件,通过配置管理中心将应用所需要的密钥信息加密推送到对应服务器的环境变量(ENV)或专门配置文件中,配置中心提供统一的Jar包来读取解密环境变量或配置文件中的密钥。
动态配置下发,配置中心在每台服务器上有一个Agent,由Agent定期拉取最新配置并加密保存在对应服务器中,应用通过配置中心提供的Jar来读取解密本地储存的密钥。
除了代码中硬编码密钥外,也需要格外关心应用中的日志打印和请求包中传输明文密钥。