SpringBoot集成Jasypt敏感信息加密的操作方法

目录
  • 前言
  • 哪些信息需要加密
  • 敏感信息加密的作用
  • 选择加密的组件
  • 项目集成Jasypt方式
    • 方式一
    • 方式二
    • 方式三
  • Springboot整合Jasypt实战
    • 一、引入依赖
    • 二、配置文件中添加Jasypt配置信息
    • 三、使用Jasypt对数据库账号和密码加密,并替换明文。
    • 四、查看执行结果
  • 使用中的一些坑
    • 1、使用jasypt3.0启动时报:Failed to bind properties under ‘xxx.xxx.xxx’ to java.lang.String
    • 2、加解密秘钥如何存储
  • 如何避免Git泄露
  • 问题探讨
  • 写在最后

前言

在互联网遍布社会各个角落的时代,伴随着的是安全问题总是层出不穷。 19年4月,根据深圳市人民检察院微信消息,深圳某知名无人机企业的工程师因为泄露公司源代码到开源社区Github上而造成了公司巨大的损失,最终被判处有期徒刑6个月,罚款20万元。

一般公司的核心业务代码中,都会存在与数据库、第三方通信的secret key等敏感信息,如果以明文的方式存储,一旦泄露,那将会给公司带来巨大的损失。 然而,许多中小型公司开发者对这方面的管理不够规范,所以很多敏感信息都是直接以明文形式存放到代码中,这样的项目存在的安全风险非常大。

本篇文章通过讲解:Springboot集成Jasypt对项目敏感信息进行加密,提高系统的安全性。

哪些信息需要加密

一个系统中,一般和数据库、第三方系统等交互的信息都会存在相应的配置文件中,在配置文件中,所有涉及到信息安全的配置项都不应该以明文的形式存储,否则,一旦配置文件泄露,则会引出巨大的安全问题,常见的需要加密的信息项如下:

  • 访问数据库、缓存等涉及到的账号密码
  • 与第三方系统交互的access key、秘钥
  • 其他涉及第三方通信的信息

敏感信息加密的作用

第一:是为了防止人为误操作将代码泄漏时,第三方能够简单获取到系统中的敏感信息,从而可能对系统、数据库等造成破坏。

其次是一般系统上线都会有代码安全检测的流程,像账号、密码等敏感数据以明文形式存储,一般都是审核不通过的,因此需要进行加密处理。

最后,作为一名开发者,应该对自我有更高的要求,在开发过程中应该要考虑到潜在的风险,提供相应的处理预案。

选择加密的组件

开源社区强大之处在于:有需求就有人奉献。Jasypt(全称:Java Simplified Encryption),它是一个Java类库,支持开发者无需深入 了解密码学相关工作原理,花费最小的代码在项目中添加基本的加密功能。

Jasypt官方使用文档:http://www.jasypt.org/

项目集成Jasypt方式

jasypt-spring-boot组件则是Jasypt提供对Springboot项目集成的依赖,刚好符合我们的需求,它支持以下3种方式集成到项目中。

方式一

在Springboot应用程序中,如果使用了@SpringBootApplication or @EnableAutoConfiguration注解,则可以直接在pom文件中添加jasypt-spring-boot依赖,然后就可以在整个Spring环境中使用jasypt对属性进行加解密操作(属性包括:系统属性、环境属性、命令行参数、properties、yml以及任何其他属性源)。

<dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>3.0.4</version>
</dependency>

方式二

如果项目中没有使用到@SpringBootApplication or @EnableAutoConfiguration注解,则可以通过以下两个步骤完成对Jasypt的集成。

步骤一:pom文件引入jasypt依赖

<dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot</artifactId>
        <version>3.0.4</version>
</dependency>

步骤二:在配置类中,添加@EnableEncryptableProperties注解,示例如下:

@Configuration
@EnableEncryptableProperties
public class MyApplication {
    ...
}

通过这种方式,你的项目一样可以集成Jasypt,并且可加密属性也可以在整个Spring环境中启用(属性包括:系统属性、环境属性、命令行参数、properties、yml以及任何其他属性源)。

方式三

如果项目中没有使用到@SpringBootApplication or @EnableAutoConfiguration注解,又不想在整个Spring环境中启用加密的属性,则可以使用该种方式,具体步骤如下:

步骤一:pom文件引入jasypt依赖

<dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot</artifactId>
        <version>3.0.4</version>
</dependency>

步骤二、在配置类中,使用@EncryptablePropertySource注解添加任意数量想要生效加密属性的配置文件路径,与Spring中@PropertySource注解的使用类似,示例如下:

@Configuration
@EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties")
public class MyApplication {
	...
}

同时,还可以使用@EncryptablePropertySources 注解对@EncryptablePropertySource配置进行分组,示例如下:

@Configuration
@EncryptablePropertySources({@EncryptablePropertySource("classpath:encrypted.properties"),                         @EncryptablePropertySource("classpath:encrypted2.properties")})
	public class MyApplication {
		...
	}

说明:从Jasypt 1.8版本开始,@EncryptablePropertySource注解支持配置YAML文件

Springboot整合Jasypt实战

一、引入依赖

说明,本项目使用技术栈是spring-boot+jasypt,故使用上面介绍的第一种方式来在项目中集成Jasypt,文章中只截取部分核心代码,全部代码会开发到Github和Gitee上。

<dependency>
	<groupId>com.github.ulisesbocchio</groupId>
	<artifactId>jasypt-spring-boot-starter</artifactId>
	<version>3.0.4</version>
</dependency>

二、配置文件中添加Jasypt配置信息

1、配置jasypt参数

jasypt:
  encryptor:
    # 配置加密算法
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    property:
      # 算法识别前缀(当算法发现配置文件中的值以这前缀开始,后缀结尾时,会使用指定算法解密)
      prefix: IT(
      # 算法识别后缀
      suffix: )

2、配置加密算法秘钥 (该秘钥不能直接放在配置文件中,下面会具体总结秘钥存放的方式,从而保证安全性)

三、使用Jasypt对数据库账号和密码加密,并替换明文。

替换后的配置信息:

spring:
  application:
    name: Jasypt-Learning
  datasource:
    url: jdbc:mysql://localhost:3306/user2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
    username: IT(MIJueAfnYWsKa2kiR8Qrrw==)
    password: IT(qH9m5vjj8RYULOASKdhlOw==)
server:
  port: 9090
# 配置jasypt相关信息
jasypt:
  encryptor:
    # 配置加密算法
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    property:
      # 算法识别前缀(当算法发现配置文件中的值以这前缀开始,后缀结尾时,会使用指定算法解密)
      prefix: IT(
      # 算法识别后缀
      suffix: )

Jasypt加密有3种方式,具体如下:

方式1、使用代码生成加密串,代码工具如下:

public static void main(String[] args) {
        String username = encrypt("root");
        String password = encrypt("123456");
        System.out.println(username);
        System.out.println(password);
    }
    /**
     * 加密
     * @param plaintext 明文密码     * @return
     */
    public static String encrypt(String plaintext) {
        //加密工具
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        //加密配置
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        // 算法类型
        config.setAlgorithm("PBEWithMD5AndDES");
        //生成秘钥的公钥
        config.setPassword("PEB123@321BEP");
        //应用配置
        encryptor.setConfig(config);
        //加密
        String ciphertext = encryptor.encrypt(plaintext);
        return ciphertext;
    }
    /**
     * 解密
     *
     * @param ciphertext 待解密秘钥
     * @return
     */
    public static String decrypt(String ciphertext) {
        //加密工具
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        //加密配置
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        config.setAlgorithm("PBEWithMD5AndDES");
        //生成秘钥的公钥
        config.setPassword("PEB123@321BEP");
        //应用配置
        encryptor.setConfig(config);
        //解密
        String pText = encryptor.decrypt(ciphertext);
        return pText;
    }

方式2、使用java cp命名对加密生成密文

参数说明:

  • org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI是jasypt提供的一个用于加密的实体类
  • org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI是jasypt提供的一个用于解密的实体类
  • input表示需要加密的字符串如:密码
  • password表示本次加密算法使用的秘钥
  • algorithm表示加密算法的名称。

特别说明: 通过该种方式获取密文,需要到maven仓库下jasypt-1.9.3.jar包所在的路径下执行,否则会报找不到对应的主类。

// 加密命令
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input='root' password=abcdef algorithm=PBEWithMD5AndDES

// 解密命令
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input='z4xP29fuY4wF2AJqp1NnoGJxj' password=abcdef algorithm=PBEWithMD5AndDES

方式3、使用jasypt-maven插件生成密文

该插件是jasypt官方提供,在pom中添加对应依赖,然后使用mvn命令即可执行加解密操作,具体如下:

// 1、在Pom中添加maven插件依赖
<plugin>
	<groupId>com.github.ulisesbocchio</groupId>
	<artifactId>jasypt-maven-plugin</artifactId>
	<version>3.0.4</version>
</plugin>

// 2、加密命令
mvn jasypt:encrypt-value -Djasypt.encryptor.password="秘钥的值" -Djasypt.plugin.value="需要加密的敏感信息"

// 解密命令
mvn jasypt:decrypt-value -Djasypt.encryptor.password="秘钥的值" -Djasypt.plugin.value="需要解密的密文"

四、查看执行结果

使用中的一些坑

使用过程中遇到了许多不可预估的问题,特意总结出来,方便读者参考。

1、使用jasypt3.0启动时报:Failed to bind properties under ‘xxx.xxx.xxx’ to java.lang.String

官方描述,3.0后默认支持的算法为PBEWITHHMACSHA512ANDAES_256 ,该种加密方式由sha512 加 AES 高级加密组成,需要JDK1.9以上支持或者添加JCE(Java Cryptography Extension无限强度权限策略文件)支持,否则运行会出现错误。

解决方式:

方式1、将加密算法替换成PBEWithMD5AndDES 算法,并配置iv-generator-classname: 为org.jasypt.iv.NoIvGenerator值

方式2、降低jasypt的版本 - 使用2.x的版本

2、加解密秘钥如何存储

如果秘钥写在代码或者配置文件,一旦代码泄露,那别人就可以使用秘钥解密我们的密文,这样对敏感信息加密的作用就不存在了,因此,秘钥不能以明文形式存储在代码或者配置文件中,下面就介绍一些安全的存储秘钥的形式。

方式1、把秘钥当做程序启动时的命令行参数(推荐),示例如下:

java -jar xxx.jar --jasypt.encryptor.password=秘钥

方式2、把秘钥当做程序启动时环境变量(推荐),示例如下:

java  -Djasypt.encryptor.password=秘钥 -jar xxx.jar

方式3、自定义加密、解密器逻辑(这个自定代码,本文不展开讲解,后续有需要重开一篇文章详细讲解)

如何避免Git泄露

因为开发者的疏漏,不小心将源码提交到开源仓库中的新闻不在少数,作为一个开发团队,如何采取一些有效的措施去最小程度防止出现这种情况呢? 除了本文介绍的对敏感信息加密,并合理保存秘钥外,还有以下的一些方式可以参考。

方式1、更规范的代码提交、推送制度、培养开发者的安全意识: 很多时候,代码的泄露除了故意为之外,大多数是因为不小心导致,因此在项目中可以通过合理管控权限的方式来防止代码泄露。

方式2、合理利用Git忽略文件(.gitignore): 通过gitignore文件配置匹配规则,最大程度避免敏感信息上传到Git仓库。

方式3、借助第三方工具,在提交、推送时检测代码是否有敏感数据: 常见的如git-secrets,在提交前会对变更内容做检测,如果检测到预期的提交内容可能包含敏感信息,那它们将会拒绝提交。

方式4、代码的Code Review: 团队leader和成员之间可以互相合作,在代码推送合并时检测是否存在敏感数据,这样不仅可以排查出敏感数据,还能够学习彼此之间的一些编码技巧。

问题探讨

在编写本篇文章内容时,无意中看到一个消息:Nginx之父被俄罗斯警方带走,起因是因为其老东家 Rambler举报Nginx是他在就职期间的业务时间进行开发的一个软件,Rambler认为其应该有该软件代码的所有权。

针对这一事件大家有什么看法呢?程序员在就职期间的业务时间开发或者编写的项目应该归属于公司?欢迎在文章下留言讨论。

写在最后

源代码安全在技术企业中意味着竞争力、生命线,一旦泄露,轻则造成项目失败,重则可能导致公司倒闭,这一关检测的重要性不言而喻,作为一名开发者,也应该时刻培养自己的安全意识,在编码时规避掉相应的风险。

到此这篇关于SpringBoot集成Jasypt加密敏感信息的文章就介绍到这了,更多相关SpringBoot加密敏感信息内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • jasypt 集成SpringBoot 数据库密码加密操作

    昨天看到一片文章,说是某某旗下酒店数据库因为程序员不小心,把数据库明文密码上传到了GitHub上,导致酒店数据注册资料.入住信息,开房记录被下载倒卖的消息. 作为程序员,开发的时候为了简单,账户明明都设置很简单,基本上数据库密码都是明文的,没做什么操作,至少我待过的公司都是这样,无论是测试环境还是线上环境,想想,这个也是一大安全隐患,在此,趁现在不忙,做些基于springboot的数据库密码加密. 1.pom.xml添加jar包(不同jdk选择不同的版本): <!-- jdk8 版本 整合jas

  • 使用Springboot对配置文件中的敏感信息加密

    Springboot对配置文件的敏感信息加密 前言 最近公司对软件的安全问题比较在意,要求对配置文件中的敏感信息如数据库密码等进行加密.但是Springboot是一款高度集成的框架,如果仅仅是简单的对数据库密码进行加密了,由于连接数据库的操作是框架自己完成的,这就会造成不小的麻烦. 经过调研,找到了如下方式还比较方便. 项目配置 该项目用到了jasypt库.原理很简单,通过该库提供的方法进行敏感信息加密,生成密文xxxxx,然后将密文使用ENC()包裹起来. 添加依赖 <!-- jasypt场景

  • Jasypt对SpringBoot配置文件加密

    引入maven <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> 生成加密串 将连接数据库的用户名和密码进行加密 public static void main(Str

  • 在SpringBoot中通过jasypt进行加密解密的方法

    1.用途 在SpringBoot中,通过jasypt可以进行加密解密. 这个是双向的, 且可以配置密钥. 2.使用: 2.1通过UT创建工具类,并认识jasypt import org.jasypt.util.text.BasicTextEncryptor; import org.junit.Test; public class UtilTests { @Test public void jasyptTest() { BasicTextEncryptor encryptor = new Basi

  • SpringBoot使用jasypt加解密密码的实现方法

    jasypt是一个通用的加解密库,我们可以使用它在配置文件中对数据库密码进行加密,以确保其安全性. 1.注入依赖 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> 2.

  • SpringBoot 集成 Jasypt 对数据库加密以及踩坑

    前言 密码安全是非常重要的,因此我们在代码中往往需要对密码进行加密,以此保证密码的安全 加依赖 <!-- jasypt --><dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version></depend

  • SpringBoot集成Jasypt敏感信息加密的操作方法

    目录 前言 哪些信息需要加密 敏感信息加密的作用 选择加密的组件 项目集成Jasypt方式 方式一 方式二 方式三 Springboot整合Jasypt实战 一.引入依赖 二.配置文件中添加Jasypt配置信息 三.使用Jasypt对数据库账号和密码加密,并替换明文. 四.查看执行结果 使用中的一些坑 1.使用jasypt3.0启动时报:Failed to bind properties under ‘xxx.xxx.xxx’ to java.lang.String 2.加解密秘钥如何存储 如何

  • SpringBoot 集成 Jasypt 对数据库加密以及踩坑的记录分享

    前言 密码安全是非常重要的,因此我们在代码中往往需要对密码进行加密,以此保证密码的安全 加依赖 <!-- jasypt --> <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.3</version> </depe

  • SpringBoot集成JWT实现token验证的流程

    JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github.com/jwtk/jjwt 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息.因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名. JWT请求流程 1. 用户使

  • SpringBoot集成Auth0 JWT的示例代码

    目录 前言 session认证与Token认证 session认证 Token认证 JWT简介 JWT定义 JWT的类库 具体实现 JWT配置 JWT工具类 测试接口 前言 说说JWT,先说下互联网服务常见的两种用户认证方式: session认证与Token认证 session认证 传统的Session认证的大体流程可以表示为用户提供用户名和密码登录后由服务器存储一份用户登录信息并传递给浏览器保存为Cookie,并在下次请求中根据Cookie来识别用户,但这种方式缺陷明显: Session都是保

  • 实战SpringBoot集成JWT实现token验证

    目录 环境搭建 1.新建一个SpringBoot项目Jwt-Demo,引入项目后面需要用到的jar包 2.数据库结构 3.配置文件application.properties 4.Entity包下新建一个User类 5.Dao包下新建一个UserDao 6.Service包下新建一个USerService 7.UseService的实现类UserServiceImp 8.controller包下新建一个UserController 9.在resource文件夹下新建一个Usermapper文件

  • springboot集成tkmapper及基本使用教程

    目录 一. 简介 二.集成mybatis&tkmapper 2.1.所需依赖 2.2.配置yml 2.3.主启动类上加注解扫描 三.基本使用 3.1.创建BaseMapper接口 3.2.entity实体层 3.3.mapper持久层 3.4.service服务层 四.测试 五.注意: 参考资料 SpringBoot使用tkmapper 1.加载依赖 2.引入逆向工程的插件 3.插件配置文件 4.错误 一. 简介 tkMapper是⼀个MyBatis插件,是在MyBatis的基础上提供了很多工具

  • 详解Spring-Boot集成Spring session并存入redis

    spring Session 提供了一套用于管理用户 session 信息的API和实现. Spring Session为企业级Java应用的session管理带来了革新,使得以下的功能更加容易实现: 编写可水平扩展的原生云应用. 将session所保存的状态卸载到特定的外部session存储中,如Redis或Apache Geode中,它们能够以独立于应用服务器的方式提供高质量的集群. 当用户使用WebSocket发送请求的时候,能够保持HttpSession处于活跃状态. 在非Web请求的处

  • SpringBoot集成Spring Data JPA及读写分离

    相关代码: github OSCchina JPA是什么 JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关联映射工具 来管理Java应用中的关系数据.它包括以下几方面的内容: 1.ORM映射 支持xml和注解方式建立实体与表之间的映射. 2.Java持久化API 定义了一些常用的CRUD接口,我们只需直接调用,而不需要考虑底层JDBC和SQL的细节. 3.JPQL查询语言 这是持久化操作中很重要的一个方面,通过面向对象

随机推荐