不管啥系统,项目中总会有一些配置信息,用户名密码等等暴露出来, 而jasypt就是以简单的方式来解决java开发中的加密问题 , 不管你的系统中配置文件,敏感信息是否已经加密或者没有加密, jasypt都能够轻松的嵌入其中,开发人员就不用专门考虑加密算法和代码的编写。那么,到底怎么个简单呢?
下面主要说说如何在Spring框架中如何轻松使用jasypt。
方式:以配置XML和配置环境变量的形式将加密机与Spring集成,听着感觉很高级,其实用起来很简单
准备工作:
项目结构目录如下:
pom.xml配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.liugroupId>
<artifactId>jasyptDemoartifactId>
<packaging>warpackaging>
<version>0.0.1-SNAPSHOTversion>
<name>jasyptDemo Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>3.1.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>3.1.4.RELEASEversion>
<scope>testscope>
dependency>
<dependency>
<groupId>org.jasyptgroupId>
<artifactId>jasypt-spring31artifactId>
<version>1.9.2version>
dependency>
<dependency>
<groupId>org.bouncycastlegroupId>
<artifactId>bcprov-jdk15onartifactId>
<version>1.47version>
dependency>
dependencies>
<build>
<finalName>jasyptDemofinalName>
build>
project>
spring.xml 配置如下
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
xmlns:encryption="http://www.jasypt.org/schema/encryption"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
http://www.jasypt.org/schema/encryptionhttp://www.baozun.com/schema/encryption/jasypt-spring31-encryption-1.xsd">
<bean id="environmentVariablesConfiguration"
class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWITHSHA256AND256BITAES-CBC-BC" />
<property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD_TEST" />
bean>
<bean id="bouncyCastleProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider" />
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="provider" ref="bouncyCastleProvider" />
<property name="config" ref="environmentVariablesConfiguration" />
bean>
beans>
环境变量配置如下:
EncryptTest 代码如下:
package jasyptDemo;
import javax.annotation.Resource;
import org.jasypt.encryption.pbe.PBEStringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) //指定测试用例运行器
@ContextConfiguration(locations = { "classpath*:spring.xml" }) //指定加载某个加载文件
public class EncryptTest extends AbstractJUnit4SpringContextTests{
@SuppressWarnings("restriction")
@Resource(name = "configurationEncryptor") //注入加密器
PBEStringEncryptor pbeStringEncryptor;
@Test
public void encryptorTest(){
String dataSourceUrl = "gowild.baozun.test.com";
System.out.println("加密前:" + dataSourceUrl);
String afterEncryptorUrl = pbeStringEncryptor.encrypt(dataSourceUrl);
System.out.println("加密后:" + afterEncryptorUrl);
String decryptorUrl = pbeStringEncryptor.decrypt(afterEncryptorUrl);
System.out.println("解密后:"+decryptorUrl);
}
}
运行结果如下;
重要说明:
<property name="password" value="sa" />
passwordEnvName && passwordSysPropertyName && password 这三者的区别
这三种写法都可以,只是在不同的场景下使用
可以根据需求设定不同的值。在实际生产环境中建议使用这个属性
具体使用步骤如:配置环境变量APP_PASSWORD --> 启动应用程序 --> 应用程序启动完成 --> 删除环境变量APP_PASSWORD。
passwordSysPropertyName 的值就是用 System.getProperties() 获取的属性值,比如:value="${user.home}"
这三种配置方式各有需求,根据实际情况来选择。
以上的只是一个简单的加密解密测试案例,那么实际上到项目中,是怎么在系统加载文件时对各种已加密的资源进行解密的呢?看一下生产案例-----》
最新目录结构如下
pom.xml文件配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.liugroupId>
<artifactId>jasyptDemoartifactId>
<packaging>warpackaging>
<version>0.0.1-SNAPSHOTversion>
<name>jasyptDemo Maven Webappname>
<url>http://maven.apache.orgurl>
<properties>
<spring.version>4.1.1.RELEASEspring.version>
<slf4j.version>1.6.6slf4j.version>
<log4j.version>1.2.12log4j.version>
<mybatis.version>3.2.1mybatis.version>
<mysql.version>5.1.45mysql.version>
<junit.version>4.10junit.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-oxmartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>${mybatis.version}version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.2.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.jasyptgroupId>
<artifactId>jasypt-spring31artifactId>
<version>1.9.2version>
dependency>
<dependency>
<groupId>org.bouncycastlegroupId>
<artifactId>bcprov-jdk15onartifactId>
<version>1.47version>
dependency>
dependencies>
<build>
<finalName>jasyptDemofinalName>
build>
project>
application.xml
xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:encryption="http://www.jasypt.org/schema/encryption"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
http://www.jasypt.org/schema/encryptionhttp://www.baozun.com/schema/encryption/jasypt-spring31-encryption-1.xsd">
<bean id="environmentVariablesConfiguration"
class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWITHSHA256AND256BITAES-CBC-BC" />
<property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD_TEST" />
bean>
<bean id="bouncyCastleProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider" />
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="provider" ref="bouncyCastleProvider" />
<property name="config" ref="environmentVariablesConfiguration" />
bean>
<bean id="propertyConfigurer"
class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>classpath:jdbc.propertiesvalue>
list>
property>
bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${jdbc_driverClassName}value>
property>
<property name="url">
<value>${jdbc_url}value>
property>
<property name="username">
<value>${jdbc_username}value>
property>
<property name="password">
<value>${jdbc_password}value>
property>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="com.wei.dao" />
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/wei/mapper/**/*.xml"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
bean>
<context:component-scan base-package="com.wei.service" />
beans>
jdbc.properties
jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/db_student
#这里已加密,系统加载文件时会自动解密
jdbc_username=ENC(HNbdG56Kp8JUcqdkKNeLMDEimu7HU4CWDd8zq0vjChA=)
#jdbc_username=root
jdbc_password=root
log4j.properties
log4j.rootLogger=DEBUG,Console,Stdout
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.appender.Stdout = org.apache.log4j.DailyRollingFileAppender
log4j.appender.Stdout.File = D://logs/log.log
log4j.appender.Stdout.Append = true
log4j.appender.Stdout.Threshold = DEBUG
log4j.appender.Stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
mybaties-config.xml 这里配置暂时为空
xml version="1.0" encoding="UTF-8"?>
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
configuration>
SpringTestBase.java
package StudentDemo;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) //让该类以及子类运行在测试环境下
@ContextConfiguration(locations = { "classpath:application.xml" }) //加载应用文件
public abstract class SpringTestBase extends AbstractJUnit4SpringContextTests{
protected Logger logger = LoggerFactory.getLogger(StudentTest.class);
}
StudentTest.java
package StudentDemo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.wei.domain.Student;
import com.wei.service.StudentService;
public class StudentTest extends SpringTestBase{
@Autowired
StudentService studentService;
@Test
public void queryAllStudent(){
Student student = studentService.queryAllStudent(1);
logger.debug("查询结果:"+student);
}
}
说明:在jdbc.properties文件中jdbc_username已加密,但最后查询结果依然可以查询成功,说明系统启动时已成功解密。
以上两种第一种是简单的加密解密的应用测试。第二种是可应用于生产上的实际项目案例
将调用此方法来请求生成指定长度的新盐。public byte[] generateSalt(int lengthBytes);
jasypt加密规则:
以配置XML的形式将加密机与Spring集成, 托管一个StandardPBEStringEncryptor加密机,只要jce支持的算法都可以用,例如:SHA ,RSA,md5,DES
这个算法必须得到JCE提供者的支持
AES就属于对称加密,常见的对称加密方法还有DES、3DES、Blowfish、RC2以及国密的SM4。
破解加密的难度除了跟加密方法有关,还跟密钥长度以及加密模式有很大的关系,就拿AES来说,有AES128和AES256(代表密钥长度),显然AES256的安全性能比AES128更高,而AES又要四种模式:ECB、CBC、CFB、OFB(代表加密模式)。
主要优点是加密和解密速度快,加密强度高,
对称加密算法列表:
DES,3DES,AES
为什么采用对称加密中的AES而不使非对称加密?
1. 速度快,安全级别高。 AES高级加密标准
2.采用的SHA256AND256BITAES-CBC-BC算法,安全机制相当高的算法,是对称加密中的代表
3.跟采取的加密方式有关。我用的是在环境变量配key的形式,都是通过这个key值来加密解密的。
问题二:用的是可逆的算法还是不可逆的算法,以及为什么要用这个算法?
因为我既要加密,也需要在应用启动的时候,能够去其进行解密
什么是面向对象?面向对象是一种思想.
面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.
/**
2 * 构造函数模式
3 * 优点:解决对象识别的问题
4 * 缺点:每次创建实例的时候都要重新创建一次方法
5 * */
/**
* 原型模式
缺点:忽略了构造函数传递初始化参数这一环节
优点:可以让所有对象实例共享它所包含的属性和方法.
* */
混合模式: