这两天在跟友商对接接口,在对外暴露接口的时候,因为友商不需要登录即可访问对于系统来说存在安全隐患,所以需要友商在调用接口的时候需要将数据加密,系统解密验证后才执行业务。所有的加密方式并不是万能的,只是增加了破解的成本高低而已~~

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom; public class DesEncryptUtils { public static final String KEY = "marklogzhu202306111454"; /**
* 加密
*
* @param content
* 需要加密的内容
* @param password
* 加密密码
* @return
*/
public static byte[] encrypt(String content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
kgen.init(128, random);
// kgen.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 解密
*
* @param content
* 待解密内容
* @param password
* 解密密钥
* @return
*/
public static byte[] decrypt(byte[] content, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
kgen.init(128, random);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return result; // 加密
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
} /**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
} /**
* 加密
*
* @param content
* 需要加密的内容
* @param password
* 加密密码
* @return
*/
public static byte[] encrypt2(String content, String password) {
try {
SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return result; // 加密
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static String getDecryptResult(String bizData) throws UnsupportedEncodingException {
byte[] decode = DesEncryptUtils.parseHexStr2Byte(bizData);
byte[] decryptResult = DesEncryptUtils.decrypt(decode, DesEncryptUtils.KEY);
String decryptStr = new String(decryptResult, "UTF-8");
return decryptStr;
} public static void main(String[] args) throws UnsupportedEncodingException {
String content = "hello 中国--2018";
// 加密
System.out.println("加密前:" + content);
byte[] encode = DesEncryptUtils.encrypt(content, DesEncryptUtils.KEY); //传输过程,不转成16进制的字符串,程序就会崩溃掉
String code = DesEncryptUtils.parseByte2HexStr(encode);
System.out.println("密文字符串:" + code);
byte[] decode = DesEncryptUtils.parseHexStr2Byte(code);
// 解密
byte[] decryptResult = DesEncryptUtils.decrypt(decode, DesEncryptUtils.KEY);
System.out.println("解密后:" + new String(decryptResult, "UTF-8")); //不转码会乱码 }
}

启动运行

加密前:hello 中国--2018
密文字符串:3461AA5F7D3434A58C47F4BFBE2AA9D4953E5E3D5717D2EF6ABAD1E421C82B7E
解密后:hello 中国--2018

遇到的问题

现象

在window 环境下加解密都可以,但是 Linux 下解密报空指针异常。

原因

SecureRandom 实现完全随操作系统本身的內部状态,除非调用方在调用 getInstance 方法,然后调用 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。关于SecureRandom类的详细介绍,见 http://yangzb.iteye.com/blog/325264

解决办法

将如下代码替换:

kgen.init(128, new SecureRandom(password.getBytes()));

替换为:

SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
kgen.init(128, random);

最新文章

  1. 读书笔记--SQL必知必会12--联结表
  2. c#小小总结(设计模式)
  3. C#的winform编程入门简单介绍
  4. SSL协议详解
  5. 获取客户端Ip地址方法
  6. php 计算代码行数
  7. Windows10 磁盘活动时间百分之百导致系统卡顿解决方法
  8. Selenium WebDriver java 简单实例
  9. [转载] OAuth2.0认证和授权原理
  10. [BZOJ2761] [JLOI2011] 不重复数字 (set)
  11. 生鲜配送管理系统_升鲜宝V2.0 小标签打印功能说明_15382353715
  12. ThreadLocal的一些总结
  13. HTML_CSS笔记
  14. 047、管理Docker Machine(2019-03012 周二)
  15. Python Kivy writes / read the file on the SD card
  16. js 锚点定位【转】
  17. bit,Byte,Word,DWORD(DOUBLE WORD,DW)
  18. 7zip命令行中文说明
  19. eclipse中导入dtd文件实现xml的自动提示功能
  20. java学习笔记6--类的继承、Object类

热门文章

  1. c语言进阶11-经典算法代码
  2. cesium 学习(四) Hello World
  3. HttpWebRequest的使用之Get和Post的差别(C#)
  4. Chrome离线安装包+谷歌访问助手
  5. 基础算法和数据结构高频题 II
  6. 【JS档案揭秘】第一集 内存泄漏与垃圾回收
  7. phpStudy 升级 MySQL 到 5.7.21
  8. centos7上搭建zookeeper集群
  9. 实用小工具推荐 OpenWrite
  10. Codeforces Round #192 (Div. 2) (330A) A. Cakeminator