现在的springboot项目需要部署到客户的机器上,因为软件是绑定客户机器的,又不允许使用U口接加密狗,只能尝试在软件层面做一些限制,项目启动时抓取客户当前机器的序列号,和数据库中的已授权序列号作对比,对比通过则允许使用,不通过则会在打开系统时,拦截所有请求并提示机器未授权。
所以要做的重点就是保证数据库不让客户进入。一旦进入就可以轻松修改授权设备号。
查看了一些资料后,决定使用jasypt对配置文件中的数据库密码进行加密,从而阻止客户连接数据库。
开发环境
编码环境
eclipse,jdk,maven,都是基本的,不多说
maven依赖
这里我使用的2.0.0版本,据说3.0以上的版本有时会出问题,没用过那种高版本的所以不太了解,3.0以上版本出现问题的,可以尝试版本退到3.0以下。
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
使用这个依赖坐标下载后,本地的maven仓库下会出现两个版本的jar包, 一个是…\com\github\ulisesbocchio目录下的三个文件夹,分别是
- jssypt-spring-boot
- jasypt-spring-boot-parent
- jasypt-spring-boot-starter
三个都是2.0.0版本。
另一个是 …\org\jasypt\jasypt 目录下,只有一个文件夹1.9.2,是1.9.2版本。
Jasypt的使用
加密解密
加密有两种方式,一种是在cmd命令行里直接使用jar命令执行jar包内的方法进行加密,一种是通过代码进行加密。
命令行
使用命令行加密时,推荐使用1.9.2版本的jar包进行加密,使用2.0.0版本会提示ClassNotFound,可能版本不一样,有些类名改掉了,或者新版本的直接调用的老版本部分代码。感兴趣的同学可以扒一下源码。
- 进入本地maven仓库的文件夹,进入org\jasypt\jasypt\1.9.2文件夹,会看到有一个jasypt-1.9.2.jar的文件。
- 打开cmd命令行,使用cd命令进入刚才打开的文件夹
- 输入以下命令:
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=明文密码 password=加密秘钥 algorithm=PBEWithMD5AndDES
input后边跟明文密码,password后边跟密钥,加密解密都需要密钥,algorithm后边是加密方式。
例如输入:
C:>java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input=123456 password=salt algorithm=PBEWithMD5AndDES
OUTPUT标题下,会出现加密后的密码:LulaIangH2GCcvjTAAE1qA==
每次重复加密,出现的密码都不同。
解密命令:
java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input=密文密码 password=加密秘钥 algorithm=PBEWithMD5AndDES
单元测试
除了使用命令行,也可以在代码里使用单元测试的方式加密。
- 创建Junit测试类,引入junit包的方法不再详细说明。
@RunWith(SpringRunner.class)
@SpringBootTest
public class JasyptTest {
@Autowired
StringEncryptor stringEncryptor;
@Test
public void testMethod() {
StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
EnvironmentPBEConfig config = new EnvironmentPBEConfig();
//config.setAlgorithm 设置加密方式
config.setAlgorithm("PBEWithMD5AndDES");
//config.setPassword 设置密钥
config.setPassword("salt");
standardPBEStringEncryptor.setConfig(config);
//设置明文密码
String input = "123456";
//encrypt是加密方法,decrypt是解密方法
String encryptedText = standardPBEStringEncryptor.encrypt(input);
System.out.println("加密结果: " + encryptedText);
System.out.println("解密结果: " + standardPBEStringEncryptor.decrypt(encryptedText));
}
}
- 执行后,即可取得加密后的密码
Main方法执行
可以直接在Main方法内调用方法进行加密解密
public static void main(String[] args) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("salt");
//要加密的数据(数据库的用户名或密码)
//encrypt是加密方法,decrypt是解密方法
String password = textEncryptor.encrypt("123456");
System.out.println("password:"+password);
System.out.println(textEncryptor.decrypt(password));
}
配置文件
在使用加密解密方法之前,需要提前在配置文件中新增对应配置。
jasypt:
encryptor:
password: salt
数据库连接的密码部分,使用ENC()包裹起来
username: admin
password: ENC(LulaIangH2GCcvjTAAE1qA==)
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
此时启动项目,连接数据库时会自动对密码进行解密。
项目测试阶段可以把密钥直接写在配置文件中,上线时需要隐藏配置文件中对应的密钥信息,需要把密钥写到代码里。
在启动类中新增如下代码,将配置文件中的明文密钥删除即可。
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("salt");
config.setPoolSize("1");
encryptor.setConfig(config);
return encryptor;
}