数据库配置信息安全问题

在 web 安全领域,黑客利用 web 应用的漏洞,将攻击脚本( webshell )上传至服务器,往往可以获得一个与 web 应用具有相同的控制权限,很多公司给 web 应用的权限是 ROOT,导致使黑客在渗透突破的第一步就获取到了最高权限,这是一种非常不安全的做法,当然权限管理不是本文主题,这里就不做过多的讨论了。

黑客在攻破一个 web 服务器后决不会就此罢手,会开展进行一步的渗透攻击,黑客的最终目的是获得数据,因此像 web 应用连接数据库的配置信息,就会成为黑客第一时间要收集的信息。

然而,很多公司的 web 配置文件几乎都采用明文的方式进行配置,使得数据库连接地址,账号密码等一览无余,具体配置如下:

遇到这样的系统,黑客一旦获取 web 权限,便可以不费吹灰之力得到 mysql 数据库的权限,我相信很多网站都是这样去进行数据库连接信息配置的,是极其不安全的。

那应该怎么办?

如果我们能将关键的配置信息进行加密处理,就能大大增加黑客直接获取到数据库连接信息的难度。

本文基于 Spring Boot 项目来介绍一个第三方的用于配置文件加密保护的项目 jasypt

初探 jayspt

首先我们先来看一下利用 jayspt 后,DataSource 的可以达到的配置效果,如下图所示:

相对于本文之前的配置,我们已经将 DataSource 的数据库连接的配置转成了密文的形式,并且采用了 base64 进行编码。

关于编码,这里说句题外话,作者在实际工作中很多程序员分不清编码,加密,哈希这三个概念,在系统设计描述时经常概念混用让人摸不着头脑,这里有必要科普一下相关概念:

加密( Encrypt ):

是将明文与秘钥通过加密算法进行运算后得出密文,一般分为对称与非对称加密,对称加密( AES,DES,BLowfish 等)采用同一秘钥进行加解密操作;

非对称加密( RSA、ECC 椭圆曲线加密算法):

又叫做公私钥加密,采用一对公私秘钥进行加解密,由于公钥加密的密文只有私钥可以解密,因此公钥可以在网络中传播,系统只要保护好私钥,密文就不会存在被破解的风险,而对称加密在实际应用中就需要考虑秘钥安全问题了。

虽然非对称加密更安全,但是其计算性能远不如对称加密,因此并不适用于大量数据的加密,在实际中,往往是在秘钥协商环节采用非对称加密来保护对称加密秘钥的传输,数据的加密依旧采用对称加密技术。

哈希(Hash):

首先说明一点 Hash 与加密最大的不同是 Hash 是不可逆的

Hash 又称之为信息摘要,可以唯一表示某一信息。在实际应用中,Hash 一般应用在密码与数据完整性校验的场景,一般来说 Hash 应该具有再其表示空间内的不可碰撞性,不可碰撞性是说 A 的 Hash 一定结果是 B,B 一定是 A 的 HASH 结果,不可能是 C 的 HASH 结果。

关于 Hash 这里有一个误区,很多同学发现网络上存在一些 Hash 破解的网站,就认为 Hash 是可以逆还原,这是错误的观点,网络中提供的 Hash 破解是通过彩虹表进行破解的(原理就是将大量常用的明文密码 Hash,构建彩虹表,如果需要破解的 Hash 在彩虹表中,那也就得知了 Hash 前的明文信息,从而实现了破解。一句话解释: Hash 可破解,但不可逆),常见的 Hash 算法有 MD4、MD5、SHA-1 等。

编码( Encoder ):

编码是一个复杂的概念,但所有编码的目的都是为了数据可以适应当前的环境下存储或传输的需求。

编码与加密不是一个概念,编码不具备信息保护的能力,编码是一种信息表述转换的技术。

例如在某些场景下,不可见字符的传输有可能会被截断,那就需要进行编码,在完成传输后再按照一定的规则进行解码,便可还原了原始的信息,不会造成数据的丢失。

好了,我们继续本文的主题,jayspt 正是使用了 Base64 对加密后的二进制密文进行编码,从而解决了配置文件无法配置二进制信息的问题。通过 jayspt 加密处理后的配置信息相对明文配置就安全多了,大大提高了黑客获取数据库连接信息的难度。

下面我们来看看项目中使用 jayspt 的具体方法。

jayspt 的使用

首先我们需要在工程中引用 jayspt 库,这里我们是使用 gradle 构建的 spring-boot 项目,相关引用如下:

然后就可以引用 jayspt 库,来生成加密字符串了,这里我们对数据库的连接信息进行加密,得到加密后的密文:

得到加密后的密文后就,就可以按照前文中加密的配置方式来进行 DataSource 的配置了。此外,还需要用加密用的秘钥配置给 jayspt,使得 jayspt 可以正确解密配置信息,jayspt 配置如下:

最后,不要忘记通过 @EnableEncryptableProperties 注解开启 Spring Boot 项目对于 jayspt 加密配置文件的支持。

jayspt 自定义加密策略

在配置文件中需要被解密的属性要被 ENC() 括住才能被 jayspt 识别,到目前为止虽然我们的配置信息可以不用明文的方式存储了,但是如果黑客熟悉 jasypt,在结合我们配置的 jasypt 解密密码,同样可以轻易的解密出我们加密的信息,因此 jasypt 支持配置我们自定义的加解密方式,从而提高了黑客解密配置信息的难度,我们需要提供一个 StringEncryptor 类型的 Bean,并命名为 jasyptStringEncryptor,此时我们就能在 Bean 中配置相对应的加解算法,密码,编码方式等信息,如下所示:

此时我们就可以将配置文件中 jasypt 的相关配置删除了。这里还需要注意一点,我们需要使用配置的 StringEncryptor 进行的加密,否则配置信息将无法被 jayspt 解密。

关于加密方式,jayspt 采用了 JCE(Java Cryptography Extension),默认采用 SunJCE 中的 PBEWithMD5AndDES 加密方式来加密,在项目中可以根据实际需要来配置 jayspt 的加密方式。

替换 ENC 标签

ENC()jayspt 默认的用于标记配置值需要解密的标签,如果我们使用 ENC,有经验的黑客还是很有可能一眼判断出我们使用了 jayspt 进行加密,jayspt 对于自定义解析标签的配置提供了支持,如下:

这样,在配置文件中就能使用 $JWTK{} 来代替 ENC() 进行密文的包裹了,使得我们的配置具有一定的迷惑性。但是如果直接在配置文件中设置 jayspt 的行为,还是过多暴露了配置文件所采用的加密技术,为了更加隐蔽,我们可以实现一个 EncryptablePropertyDetector 来进行解密标签的配置,如下:

同时需要为 jayspt 提供名为 encryptablePropertyDetector 的 Bean:

OK,这样在配置文件中就没有 jayspt 的踪迹了。

spring 框架下的通用配置加密技术

上文介绍了 jayspt 这一个专用于解决配置加密问题的第三方 java 包,已经可以大大的提高网站配置文件的安全性了,可以满足一般网站的配置文件安全的需求了。

介于目前 Spring Boot 在实际市场上的采用率还不是那么高的情况下,作者这里针对目前大多数 SSH 框架下依旧采用的通过 xml 来配置 Spring 的实情,给出一种简易的配置文件加密的解决思路。

Spring 框架最为强大之处就在于其 IOC模型,开发者可以可以根据实际情况来实现 java 对象的装配与管理,这也使得 java 的开发成为了面向接口开发的最佳实践。利用装配的思路,可以实现了一个 String 类型的 FactoryBean,用来做读取加密字符串和解密的操作,然后通过 Spring 依赖配置将其注入到 DataSource 对应的配置中,便实现了配置信息的解密与装配,实际配置文件如下:

在 Spring 的配置中 JwtkDecryptor 便是我们实现了 FactoryBean 接口的 String 类型对象工厂,在 Spring 对 DataSource 中的依赖注入进行装填时便会调用 JwtkDecryptor 的 getObject() 接口来获取一个 String 类型的对象,因此我们在该函数中实现了数据的解密就可以保证 Spring 将解密后的 String 对象注入到了 DataSource 对应的属性中。

相信读者可以通过结合上图 Spring Bean 的装配配置,不难理解整个依赖注入的整个流程,这里只给出 JwtkDecryptor 的关键代码:

更多的思考

采用上面的技术,web 配置信息就真的安全了吗,问题就都解决了吗?面对如今黑客的逆向技术的发展,java 的反编译技术早已不是什么难事(JD-GUI),黑客通过逆向分析项目采用的加密技术,便可以开发出对应解密工具,同样可以获取到 web 的相关配置。

但不要沮丧,因为从来没有绝对安全的系统,妄图通过一项技术就解决所有安全问题也是不可能的,这里作者想起来当年学习逆向技术时《加密解密》一书中所阐述反调试技术应用时的观点,没有一项反调试技术可以防止软件被调试,但是软件可以通过多种反调试技术相结合来增加软件被破解的难度

本文中提到的多种策略也是意在提高系统被破解的门槛,这个门槛越高,我们的系统相对来说就越安全。此外,关于加解密,我们可以将其放到更底层中去实现,例如在 C++ 中实现一个加解密的动态链接库,并通过 JNI 接口的方式在 java 中调用,这样就极大的提高了系统加密的安全性,但也同时提高了系统开发的难度与运行风险,一方面是大多 Java 程序员并不熟悉 C++ 开发,因此增加了系统代码开发的难度,另一方面是需要保证动态链接库的绝对稳定,因为动态链接库一旦崩溃,便会导致整个 java 进程的崩溃,从而增加了 java 项目的运行风险。

但即便如此,作者还是在最近的一个项目中采用了这样的技术来对配置文件与上层协议提供加解密的保护,因为为了系统安全,这些都是值得的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值