关于我们

项目简介

本项目包含两部分:

java安全编码规范和JAVA安全SDK,SDK介绍详见下述。

项目结构

├── LICENSE

├── README.md

├── pom.xml

└── src

├── main

│   ├── java

│   │   └── com

│   │   └── immomo

│   │   └── rhizobia

│   │   └── rhizobia_J

│   │   ├── base

│   │   │   ├── SqliSanitiser.java

│   │   │   └── WhiteChecker.java

│   │   ├── crypto

│   │   │   ├── AESUtils.java

│   │   │   ├── ECDSAUtils.java

│   │   │   └── RSAUtils.java

│   │   ├── csrf

│   │   │   └── CSRFTokenUtils.java

│   │   ├── deserialization

│   │   │   └── SecureObjectInputStream.java

│   │   ├── extra

│   │   │   ├── LICENSE

│   │   │   ├── LICENSE-CONTENT

│   │   │   ├── LICENSE-README

│   │   │   ├── codecs

│   │   │   │   ├── AbstractCharacterCodec.java

│   │   │   │   ├── AbstractCodec.java

│   │   │   │   ├── AbstractIntegerCodec.java

│   │   │   │   ├── AbstractPushbackSequence.java

│   │   │   │   ├── Codec.java

│   │   │   │   ├── DB2Codec.java

│   │   │   │   ├── HTMLEntityCodec.java

│   │   │   │   ├── HashTrie.java

│   │   │   │   ├── JavaScriptCodec.java

│   │   │   │   ├── MySQLCodec.java

│   │   │   │   ├── OracleCodec.java

│   │   │   │   ├── PushBackSequenceImpl.java

│   │   │   │   ├── PushbackSequence.java

│   │   │   │   ├── PushbackString.java

│   │   │   │   └── Trie.java

│   │   │   └── commons

│   │   │   ├── CollectionsUtil.java

│   │   │   ├── EncoderConstants.java

│   │   │   ├── NullSafe.java

│   │   │   ├── RandomCreater.java

│   │   │   └── StringUtilities.java

│   │   ├── sqli

│   │   │   ├── DB2Sanitiser.java

│   │   │   ├── MysqlSanitiser.java

│   │   │   └── OracleSanitiser.java

│   │   ├── ssrf

│   │   │   └── SSRFWhiteChecker.java

│   │   ├── urlredirection

│   │   │   └── UrlRedirectionWhiteChecher.java

│   │   ├── xss

│   │   │   └── XssSanitiser.java

│   │   └── xxe

│   │   └── XmlUtils.java

│   └── resources

│   └── log4j.properties

└── test

└── java

└── com

└── immomo

└── rhizobia

└── rhizobia_J

├── AESUtilsTest.java

├── CSRFTokenUtilsTest.java

├── DB2SanitiserTest.java

├── ECDSAUtilsTest.java

├── MysqlSanitiserTest.java

├── OracleSanitiserTest.java

├── RSAUtilsTest.java

├── SSRFWhiteCheckerTest.java

├── SafeClass.java

├── SecureObjectInputStreamTest.java

├── TestBean.java

├── UnsafeClass.java

├── UrlRedirectionWhiteChecherTest.java

├── XmlUtilsTest.java

└── XssEncoderTest.java

目录

1、引用java security library

环境需求

Java 8

Maven 3

a、编译jar包:

mvn -Dmaven.test.skip=true clean install

b、引入java security library:

在target目录中找到target/rhizobia_J-1.0.jar,导入工程中

需要在自己的maven工程pom.xml中加入如下依赖

log4j

log4j

1.2.17

commons-codec

commons-codec

1.11

2、SQL注入防护

a、确认是连接的是哪种数据库,选择对应的数据库编码,目前支持数据库包括:MySQL Oracle DB2:

import com.immomo.rhizobia.rhizobia_J.sqli.MysqlSanitiser;

//import com.immomo.rhizobia.rhizobia_J.sqli.OracleSanitiser;

//import com.immomo.rhizobia.rhizobia_J.sqli.DB2Sanitiser;

MysqlSanitiser sqlTool = MysqlSanitiser.getInstance();

b、对sql语句中拼接的参数进行转义:

String id = "1' or '1'='1' #";

String idEncode = sqlTool.mysqlSanitise(id);

String query = "SELECT NAME FROM users WHERE id = '" + idEncode + "'";

使用order by、group by等需要转换列名时,需使用带boolean参数

//保证列名中的下划线不被转义

String columnName = "user_name";

String columnNameEncode = sqlTool.mysqlSanitise(columnName, true);

query = "SELECT NAME FROM users order by " + columnNameEncode ;

c、转义前后对比:

转义前:SELECT NAME FROM users WHERE id = '1' or '1'='1' #'

转义后:SELECT NAME FROM users WHERE id = '1\' or \'1\'\=\'1\' \#'

d、表名列名转义前后对比:

转义前:SELECT NAME FROM users order by user_name

转义后:SELECT NAME FROM users order by user_name

转义前:SELECT NAME FROM users order by user-name

转义后:SELECT NAME FROM users order by user\-name

3、xss防护

a、调用XssSanitiser单例:

import com.immomo.rhizobia.rhizobia_J.xss.XssSanitiser;

XssSanitiser xssFilter = XssSanitiser.getInstance();

b、如果输出到html body:

String ret = xssFilter.encodeForHTML(oriString);

过滤前后对比:

过滤前:

过滤后:<script>alert('xss')</script>

c、如果输出到html标签的属性(多了对空字符的过滤):

String ret = xssFilter.encodeForHTMLAttribute(oriString);

过滤前后对比:

过滤前:

过滤后:<script> alert('xss') </script>

d、如果输出到JavaScript代码块中:

String ret = xssFilter.encodeForJavaScript(oriString);

过滤前后对比:

过滤前:alert('xss');

过滤后:alert\x28\x27xss\x27\x29\x3B

4、url重定向防护

a、调用UrlRedirectionWhiteChecher单例:

import com.immomo.rhizobia.rhizobia_J.urlredirection.UrlRedirectionWhiteChecher;

UrlRedirectionWhiteChecher urlChecker = UrlRedirectionWhiteChecher.getInstance();

b、自定义白名单:

List whitelist = new ArrayList();

String white1=".trust1.com";

String white2=".trust2.com";

//setWhiteList会先清空原有白名单列表

//在原有基础上新增白名单,使用addWhiteList(whitelist)

urlChecker.setWhiteList(whitelist);

c、校验url:

try{

boolean isWhite = urlChecker.verifyURL(url.trim());

} catch (Exception e) {

...

}

5、SSRF防护

a、调用SSRFWhiteChecker单例,与前面url重定向类似:

import com.immomo.rhizobia.rhizobia_J.ssrf.SSRFWhiteChecker;

SSRFWhiteChecker ssrfChecker = SSRFWhiteChecker.getInstance();

b、自定义白名单:

List whitelist = new ArrayList();

String white1=".trust1.com";

String white2=".trust2.com";

//setWhiteList会先清空原有白名单列表

//在原有基础上新增白名单,使用addWhiteList(whitelist)

ssrfChecker.setWhiteList(whitelist);

c、校验url:

try{

boolean isWhite = ssrfChecker.verifyURL(url.trim());

} catch (Exception e) {

...

}

6、CSRF防护

a、随机算出csrf token,并且每次生成随机值都不一样(实测结果连续生成1000亿次无重复):

import com.immomo.rhizobia.rhizobia_J.csrf.CSRFTokenUtils;

CSRFTokenUtils csrfInstance = CSRFTokenUtils.getInstance();

String token = csrfInstance.resetCsrfToken(32);

b、后端保存生成的token,以待校验(可以采用数据库、分布存储等任意存储手段)

c、前端页面加上hidden字段

form中加入csrf token的hidden字段:

ajax中加入csrf头

xhr.setRequestHeader("${_csrf.headerName}", "${_csrf.token}");

d、当前端向后端发送请求时,请求header中携带token,后端收到后与之前存储的token进行校验

7、readObject反序列化漏洞防护

a、选择适当的构造函数初始化,自定义白名单:

使用SecureObjectInputStream中适当的构造函数,增加自定义的白名单

import com.immomo.rhizobia.rhizobia_J.deserialization.SecureObjectInputStream;

SecureObjectInputStream(InputStream in, String[] classlist)

SecureObjectInputStream(InputStream in, List classlist)

b、使用安全的类SecureObjectInputStream,恢复非白名单中类的对象时会抛出异常:

List classlist = new ArrayList();

classlist.add(SafeClass.class.toString());

try{

//考虑如果白名单为空时会影响正常判断逻辑,所以此处会抛出异常

SecureObjectInputStream ois = new SecureObjectInputStream(fis, classlist);

//使用安全的SecureObjectInputStream恢复对象时会抛出exception

UnsafeClass objectFromDisk = (UnsafeClass)ois.readObject();

} catch (Exception e) {

...

}

8、xxe防护

8.1、解析xml内容为Document

a、初始化时注意xml编码格式:

import com.immomo.rhizobia.rhizobia_J.xxe.XmlUtils;

//如果xml格式包含外部实体,会抛异常

try{

Document doc = XmlUtils.getInstance().newDocument(xmlFile, "utf-8");

} catch (Exception e) {

...

}

b、使用生成的Document对象:

Node notifyNode = doc.getFirstChild();

NodeList list = notifyNode.getChildNodes();

for (int i = 0, length = list.getLength(); i < length; i++) {

Node n = list.item(i);

String nodeName = n.getNodeName();

String nodeContent = n.getTextContent();

System.out.println(nodeName.toString() + " " + nodeContent.toString());

}

8.2、解析xml内容为Bean

a、自定义TestBean,然后调用converyToJavaBean解析:

import com.immomo.rhizobia.rhizobia_J.xxe.XmlUtils;

//如果xml格式包含外部实体,会抛异常

XmlUtils xmlParser = XmlUtils.getInstance();

try {

TestBean testbean = (TestBean)xmlParser.converyToJavaBean(xmlFile, TestBean.class);

} catch (Exception e) {

...

}

b、使用生成的bean对象:

testbean.getTo()

testbean.getFrom()

testbean.getHeading()

testbean.getBody()

9、AES加解密

知识点1:oracle官方已经在如下版本去除了aes-256的限制,6u181,7u171,8u161,9 b148,openjdk7u

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157

知识点2:之所以AES、RSA没有封装base64或16进制编码处理,是因为在使用base64编码后的内容中,可能存在'+'字符,

'+'字符返回给前端后再返回给后端时,如果不经过处理,会变为' '空格字符,

所以请用户自行选择base64编码或16进制编码

并在对加密内容进行base64编码时,请注意'+'字符

a、调用AESUtils:

import com.immomo.rhizobia.rhizobia_J.crypto.AESUtils;

AESUtils aesInstance = AESUtils.getInstance(String aesKey, String secretKey, String aesMode);

/**

参数说明:

aesKey: 用于生成密钥的原始字符串,推荐使用session/id,具有唯一性

secretKey: 加解密双方约定的secret

aesMode: 值为null时,默认采用"AES/CBC/PKCS5Padding"

*/

AESUtils aesInstance = AESUtils.getInstance("843739488","TcmEqGzSpH5S2VgoUix7HJ9cwqCofoUD",null);

b、加密

String orginText = "10000";

byte[] ciphertext = aesInstance.Encrypt(orginText);

//由于返回是byte流,所以如果需要base64编码或转换成Hex,需另做处理

String encryptRet = new BASE64Encoder().encode(ciphertext);

c、解密

//同样,如果加密内容用base64编码或转换成Hex,解密时需另做处理

byte[] encrypted = new BASE64Decoder().decodeBuffer(encryptRet);

String DeString = aesInstance.Decrypt(encrypted);

10、RSA加解密 加签验签

知识点1:RSA加解密时,明文是有长度限制的,明文字符串限制长度 = 密钥长度(byte) - padding占用大小(byte)

padding大小如下:

RSA/ECB/PKCS1Padding or RSA : 11

RSA/ECB/OAEPWithSHA-1AndMGF1Padding : 42

RSA/ECB/OAEPWithSHA-256AndMGF1Padding : 66

例如:RSA密钥长度为1024(bit)/8 = 128(byte),keyPairGenerator.initialize(1024),

在RSA/ECB/OAEPWithSHA-1AndMGF1Padding模式下,

被加密的明文字符串长度不能超过 128-42 = 86

知识点2:同前一节aes的知识点2

知识点3:源码所用的signature类中,已经封装了摘要算法,所以可以不必再生成摘要,当然自已多生成摘要也没有问题

10.1、加解密

a、创建RSAUtils单例

如密钥在文件中:

import com.immomo.rhizobia.rhizobia_J.crypto.RSAUtils;

/**

参数说明:目前证书支持 PEM 格式

priKeyPath: openssl生成的私钥地址

pubKeyPath: openssl生成的公钥地址

*/

String priKeyPath = "/tmp/pri.key";

String pubKeyPath = "/tmp/pub.key";

RSAUtils rsaInstance = RSAUtils.getInstance(priKeyPath, pubKeyPath);

由于文件头尾格式有多种,根据需要调用set方法修改头尾后生成公私钥

RSAUtils rsaInstance = RSAUtils.getInstance();

rsaInstance.setPemPriHead("-----BEGIN PRIVATE KEY-----\n");

rsaInstance.setPemPriEnd("-----END PRIVATE KEY-----");

rsaInstance.setPemPubHead("-----BEGIN PUBLIC KEY-----\n");

rsaInstance.setPemPubEnd("-----END PUBLIC KEY-----");

rsaInstance.setPrivateKey(rsaInstance.getPrivateKey(priKeyPath));

rsaInstance.setPublicKey(rsaInstance.getPublicKey(pubKeyPath));

如果已有公私钥,也可直接用已有密钥生成单例

//如下为生成公私钥的例子,用户可任意选用其他方法生成公私钥

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

keyPairGenerator.initialize(512);

KeyPair keyPair = keyPairGenerator.generateKeyPair();

PublicKey rsaPublicKey = (PublicKey) keyPair.getPublic();

PrivateKey rsaPrivateKey = (PrivateKey) keyPair.getPrivate();

//生成单例

RSAUtils rsaInstance = RSAUtils.getInstance(rsaPrivateKey, rsaPublicKey);

b、加密

String plaintext = "123";

//如知识点1,如果明文长度超过最大长度,可以用rsaInstance.encryptWithouLimit

//或者自行将明文字符串拆分成对应的限制长度的块

byte[] ciphertext = rsaInstance.encrypt(plaintext);

//与aes一样返回是byte流,所以如果需要base64编码或转换成Hex,需另做处理

String encryptRet = new BASE64Encoder().encode(ciphertext);

c、解密

//同样,如果加密内容用base64编码或转换成Hex,解密时需另做处理

byte[] encrypted = new BASE64Decoder().decodeBuffer(encryptRet);

//如知识点1,如果使用了encryptWithouLimit加密,对应使用rsaInstance.decryptWithoutLimit进行解密

String plaintext = rsaInstance.decrypt(ciphertext);

10.2、加签验签(更推荐使用ECDSA来实现加签验签,参考)

a、加签

//原文

String plaintext = "123";

byte[] sigintext = rsaInstance.sign(plaintext);

//与aes一样返回是byte流,所以如果需要base64编码或转换成Hex,需另做处理

String signtRet = new BASE64Encoder().encode(sigintext);

b、验签

//同样,如果加密内容用base64编码或转换成Hex,解密时需另做处理

byte[] verified = new BASE64Decoder().decodeBuffer(signtRet);

boolean ifPass = rsaInstance.verify(verified, plaintext);

11、ECDSA 加签验签

a、创建ECDSAUtils单例

与前面一节RSA类似,也有三种获取单例的方法

import com.immomo.rhizobia.rhizobia_J.crypto.ECDSAUtils;

String priKeyPath = "/tmp/ECDSAPrivateKey.key";

String pubKeyPath = "/tmp/ECDSAPublicKey.key";

ECDSAUtils ecInstance = ECDSAUtils.getInstance(priKeyPath, pubKeyPath);

//ECDSAUtils.getInstance()或ECDSAUtils.getInstance(ecPrivateKey, ecPublicKey)参照前面RSA章节

b、加签

String plaintext = "123";

byte[] sigintext = ecInstance.sign(plaintext);

//与aes一样返回是byte流,所以如果需要base64编码或转换成Hex,需另做处理

String signtRet = new BASE64Encoder().encode(sigintext);

c、验签

//同样,如果加密内容用base64编码或转换成Hex,解密时需另做处理

byte[] verified = new BASE64Decoder().decodeBuffer(signtRet);

boolean ifPass = ecInstance.verify(verified, plaintext);

java sdk加密_rhizobia_J相关推荐

  1. java ase 加密_java实现ase加密解密

    展开全部 这个算法java SDK自带的额 参考代码如下: /**解密 * @param content  待解密内容 * @param password 解密密钥 * @return */ publ ...

  2. java aws_AWS学习笔记(八)--S3 JAVA SDK

    Amazon Simple Storage Service (Amazon S3)是面向 Internet 的存储服务,具有高扩展性.可靠性.安全性和快速价廉的特点,提供 99.999999999% ...

  3. 海康威视摄像机Java SDK拉流(二)开启关闭实时预览

    上一篇:海康威视Java SDK拉流(一)初始化SDK 本篇介绍海康威视摄像机通过SDK开启关闭实时预览接口 下篇介绍实时预览的回调函数及解码库 测试环境: 系统:Centos 7 SDK:设备网络S ...

  4. centos java yum_CentOS7 使用yum命令安装Java SDK

    CentOS 6.X 和 7.X 自带有OpenJDK runtime environment  (openjdk).它是一个在linux上实现开源的Java 平台. 安装方式: 1.输入以下命令,以 ...

  5. 表格存储的Java SDK性能优化经验

    原文发布于阿里云论坛,在圈子内重发. 问题背景 用户通过Java SDK来访问表格存储,在SDK内部也是有开销的,在高并发的场景下这些开销尤其突出.如果SDK的性能很差,用户为了达到更高的QPS,可能 ...

  6. 修改Intellij IDEA中工程对应的Java SDK、Scala SDK

    如果编译Scala工程时,遇到如下异常: can't expand macros compiled by previous versions of Scala 很可能是工程的scala版本,和依赖的包 ...

  7. 解决Please ensure that adb is correctly located at 'D:\java\sdk\platform-tools\adb.exe' and can be exe

    遇到问题描述: 运行android程序控制台输出 [2012-07-18 16:18:26 - ] The connection to adb is down, and a severe error ...

  8. SpringMVC 整合新浪微博登录 Java SDK

    为什么80%的码农都做不了架构师?>>>    现在很多网站都整合了便捷的第三方登录,如QQ登录.新浪微博.搜狐.网易等,为用户提供不少方便和节约时间.我们可以选择使用JS或SDK实 ...

  9. 使用MaxCompute Java SDK 执行任务卡住了,怎么办?

    场景一 用户A A: "亲,用 MaxCompute Java SDK 跑作业,为什么卡住不动了?" me: "有 Logview 吗?发来看下" A: &qu ...

最新文章

  1. 采购审批专题总结--bob
  2. svn Web管理svnadmin
  3. 利用全局数据实现数据通信
  4. Vue提供操作DOM的方法
  5. Windows上搭建EMQTT服务器
  6. 大气校正后的ndvi_Sentinel2 L1C下载、大气校正、重采样
  7. kafka学习_Kafka 学习笔记01
  8. shell 判断字符串最后一个字符
  9. EF连接ORACLE
  10. 如何控制表格的宽度_利用Word制作表格,这些实用技巧一定要知道!制作表格更加快捷...
  11. windows中使用mysql配置my.ini时的坑
  12. 查看局域网内所有ip 和 mac
  13. CentOs6.5安装使用数据恢复软件extundelete
  14. 月日加四位尾数编号生成 VB方式
  15. MVC-Chart_WebGrid 显示漂亮chart
  16. 博弈论之:威胁与承诺
  17. 如何使用 Firebase 建立短網址?
  18. ​​【​观察】萨提亚为微软中国定下主基调 平台价值释放与生态伙伴共赢
  19. anacoda里面安装包显示失败_Premiere2020安装包下载及安装教程(附pr2020配置要求)...
  20. 回车符,换行符与'\0'

热门文章

  1. 虎牙与斗鱼联合宣布达成合并协议
  2. TIPTOP ERP 调试debug时如何查看临时表中的数据
  3. 计算机专业 拒绝清华,2次拒绝北大邀请,获清华保送生资格,网友:清华计算机全球第一...
  4. 【最强大脑】全球脑王的极客挑战赛之路:1413876分夺冠如何炼成?
  5. #99-【桶排序】摩天楼
  6. 玩抖音短视频,注重这4个套路
  7. 设置Tomcat的UTF-8编码
  8. Java的poi导出的excel不能超过256列的解决办法
  9. 如何选择好的IB课程学校?
  10. Java面试题视频讲解汇总