一、先看一个简单加密,解密实现

1.1 加密

/*** content: 加密内容* slatKey: 加密的盐,16位字符串* vectorKey: 加密的向量,16位字符串*/
public String encrypt(String content, String slatKey, String vectorKey) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes());cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] encrypted = cipher.doFinal(content.getBytes());return Base64.encodeBase64String(encrypted);
}

1.2 解密

/*** content: 解密内容(base64编码格式)* slatKey: 加密时使用的盐,16位字符串* vectorKey: 加密时使用的向量,16位字符串*/
public String decrypt(String base64Content, String slatKey, String vectorKey) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes());cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);byte[] content = Base64.decodeBase64(base64Content);byte[] encrypted = cipher.doFinal(content);return new String(encrypted);
}

1.3 代码解释

上面简单实现了AES(“AES/CBC/PKCS5Padding”)的加密和解密。可以看到代码中主要的是cipher对象,并有以下调用

(1)新建Cipher对象时需要传入一个参数"AES/CBC/PKCS5Padding"

(2)cipher对象使用之前还需要初始化,共三个参数(“加密模式或者解密模式”,“密匙”,“向量”)

(3)调用数据转换:cipher.doFinal(content),其中content是一个byte数组

实际上Cipher类实现了多种加密算法,在创建Cipher对象时,传入不同的参数就可以进行不同的加密算法。而这些算法不同的地方只是创建密匙的方法不同而已。

如传入“AES/CBC/NoPadding”可进行AES加密,传入"DESede/CBC/NoPadding"可进行DES3加密。具体的后面会介绍到。

要参考Java自带的加密算法,可以参考JDK文档的附录:https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

二、Java的Cipher类

2.1 Cipher类提供了加密和解密的功能。

该项目使用Cipher类完成aes,des,des3和rsa加密.

获取Cipher类的对象:Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”); 参数按"算法/模式/填充模式",有以下的参数

  • AES/CBC/NoPadding (128)
  • AES/CBC/PKCS5Padding (128)
  • AES/ECB/NoPadding (128)
  • AES/ECB/PKCS5Padding (128)
  • DES/CBC/NoPadding (56)
  • DES/CBC/PKCS5Padding (56)
  • DES/ECB/NoPadding (56)
  • DES/ECB/PKCS5Padding (56)
  • DESede/CBC/NoPadding (168)
  • DESede/CBC/PKCS5Padding (168)
  • DESede/ECB/NoPadding (168)
  • DESede/ECB/PKCS5Padding (168)
  • RSA/ECB/PKCS1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

(1) 加密算法有:AES,DES,DESede(DES3)和RSA 四种
(2) 模式有CBC(有向量模式)和ECB(无向量模式),向量模式可以简单理解为偏移量,使用CBC模式需要定义一个IvParameterSpec对象
(3) 填充模式:

  • NoPadding: 加密内容不足8位用0补足8位, Cipher类不提供补位功能,需自己实现代码给加密内容添加0, 如{65,65,65,0,0,0,0,0}
  • PKCS5Padding: 加密内容不足8位用余位数补足8位, 如{65,65,65,5,5,5,5,5}或{97,97,97,97,97,97,2,2}; 刚好8位补8位8

2.2 Cipher对象需要初始化

init(int opmode, Key key, AlgorithmParameterSpec params)
(1)opmode :Cipher.ENCRYPT_MODE(加密模式)和 Cipher.DECRYPT_MODE(解密模式)
(2)key :密匙,使用传入的盐构造出一个密匙,可以使用SecretKeySpec、KeyGenerator和KeyPairGenerator创建密匙,其中
* SecretKeySpec和KeyGenerator支持AES,DES,DESede三种加密算法创建密匙
* KeyPairGenerator支持RSA加密算法创建密匙
(3)params :使用CBC模式时必须传入该参数,该项目使用IvParameterSpec创建iv 对象

2.3 加密或解密

byte[] b = cipher.doFinal(content);
返回结果为byte数组,如果直接使用 new String(b) 封装成字符串,则会出现乱码

三、创建密匙

创建密匙主要使用SecretKeySpec、KeyGenerator和KeyPairGenerator三个类来创建密匙。

3.1 SecretKeySpec类

SecretKeySpec类支持创建密匙的加密算法(ASE,DES,DES3)

SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");

但需要主要的是不同的加密算法的byte数组的长度是不同的,创建密匙前最好先检测下byte数组的长度。各加密算法的密匙长度如下

加密算法 密匙长度 向量长度
AES 16 16
DES 8 8
DES3 24 8

3.2 KeyGenerator类

KeyGenerator类支持创建密匙的加密算法(ASE,DES,DES3)

   /*** 获取加密的密匙,传入的slatKey可以是任意长度的,作为SecureRandom的随机种子,* 而在KeyGenerator初始化时设置密匙的长度128bit(16位byte)*/private static Key getSlatKey(String slatKey) throws Exception {KeyGenerator kgen = KeyGenerator.getInstance("AES");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(slatKey.getBytes());kgen.init(128, random);Key key = kgen.generateKey();return key;}
KeyGenerator对象在初始化需要传入一个随机源。一般使用的都是SecureRandom类来创建随机源,此时传入的盐只作为SecureRandom类的随机种子,种子相同,产生的随机数也相同;
盐的长度不再受限制了,但KeyGenerator对象则必须指定长度。

3.3KeyPairGenerator类

RSA加密算法使用的密匙是包含公匙和私匙两种,一般情况下,有使用公匙加密,则用私匙解密;使用私匙加密,则使用公匙解密。可以使用KeyPairGenerator类来创建RSA加密算法的密匙

KeyPairGenerator类支持创建密匙的加密算法(RSA)

/*** 根据slatKey获取公匙,传入的slatKey作为SecureRandom的随机种子* 若使用new SecureRandom()创建公匙,则需要记录下私匙,解密时使用*/private static byte[] getPublicKey(String slatKey) throws Exception {KeyPairGenerator keyPairGenerator  = KeyPairGenerator.getInstance("RSA");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(slatKey.getBytes());keyPairGenerator.initialize(1024, random);//or 2048KeyPair keyPair = keyPairGenerator.generateKeyPair();return keyPair.getPublic().getEncoded();}/*** 根据slatKey获取私匙,传入的slatKey作为SecureRandom的随机种子*/private static byte[] getPrivateKey(String slatKey) throws Exception {KeyPairGenerator keyPairGenerator  = KeyPairGenerator.getInstance("RSA");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(slatKey.getBytes());keyPairGenerator.initialize(1024, random);// or 2048KeyPair keyPair = keyPairGenerator.generateKeyPair();return keyPair.getPrivate().getEncoded();}
同上,传入的盐只作为SecureRandom类的随机种子,盐相同,产生的keyPair的公匙和私匙也是同一对。
也可以不设置SecureRandom类的随机种子,直接使用new SecureRandom()创建一个新对象,此时就必须记录下公匙和私匙,在解密时使用。

四、对加密结果进行一层包装

4.1 针对1.3返回结果返回字符串乱码的问题,一般对byte数组进行处理

有两种处理方式:转换为base64的字符串或转换为16进制的字符串

4.2 转换为base64

使用apache下的Base64类进行封装即可,Base64.encodeBase64String(result); 结果形如 qPba5V+b0Ox3Um…
jar包下载:https://mvnrepository.com/artifact/commons-codec/commons-codec

4.3 转换为16进制

编码实现,即编码实现将2进制转换为16进制

/*** 16进制工具类*/
public class HexUtil {private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };/*** 十六进制转化为二进制*/public static byte[] hexStrToByteArray(String hexString) {if (hexString == null) {return null;}if (hexString.length() == 0) {return new byte[0];}byte[] byteArray = new byte[hexString.length() / 2];for (int i = 0; i < byteArray.length; i++) {String subStr = hexString.substring(2 * i, 2 * i + 2);byteArray[i] = ((byte) Integer.parseInt(subStr, 16));}return byteArray;}/*** 二进制转化为十六进制*/public static String byteArrayToHexStr(byte[] byteArray) {if (byteArray == null) {return null;}char[] hexChars = new char[byteArray.length * 2];for (int j = 0; j < byteArray.length; j++) {int v = byteArray[j] & 0xFF;hexChars[j * 2] = HEX_CHARS[v >>> 4];hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];}return new String(hexChars);}
}

结果形如 04A2784A45234B…

五、Java加密的代码

代码我上传到github上了,欢迎下载~~

https://github.com/caizhaokai/Java_Cipher_Encrypt

Java使用Cipher类实现加密,包括DES,DES3,AES和RSA加密相关推荐

  1. Android DES,AES,RSA加密实现

    DES加密: DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位(每组的第8位作为奇偶校验位),产生最大 64 位的分组大小.这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将 ...

  2. 对称加密、非对称加密、DES、AES、RSA、OpenSSL、数字签名、防篡改

    本公众号分享的所有技术仅用于学习交流,请勿用于其他非法活动,如果错漏,欢迎留言指正 <加密与解密>第4版 加解密 安全领域的重要分支和基础设施 互联网重要数据的传输需要加解密 TCP/IP ...

  3. 常见加密工具类Base64、DES、AES、RSA、MD5汇总

    文章目录 引言 1.Base64加密 2.DES加密 3.AES加密 4.RSA加密 5.MD5加密 引言 项目中经常会用到Base64.DES.AES.RSA.MD5几种加解密方式,每次都要去网上搜 ...

  4. angular和JAVA实现aes、rsa加密解密,前后端交互,前端加解密和后端JAVA加解密实现

    今天实现了下AES和RSA加密解密,主要的功能是对前后端交互数据进行加密解密,为什么要用到两个算法呢,首先RSA默认的话加密长度是有限的100多个byte吧大约,并且需要公钥私钥,而AES加密没有限制 ...

  5. Crypto++入门学习笔记(DES、AES、RSA、SHA-256)

    Crypto++入门学习笔记(DES.AES.RSA.SHA-256) 背景(只是个人感想,技术上不对后面的内容构成知识性障碍,可以skip): 最近,基于某些原因和需要,笔者需要去了解一下Crypt ...

  6. AES和RSA加密解密(前后台交互)

    一.AES和RSA简单介绍 AES:对称加解密,加密解密使用同一个秘钥. RSA:非对称加解密,使用公钥加密数据,只有对应的私钥才能解密,加密方和解密方各自保存秘钥对中的一个.(这里推荐一个RSA密钥 ...

  7. Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(转)

    Crypto++入门学习笔记(DES.AES.RSA.SHA-256)(转) 2012-11-19 11:28:00|  分类: c++|举报|字号 订阅 背景(只是个人感想,技术上不对后面的内容构成 ...

  8. Java实现Base64、DES、AES、RSA加解密以及加密方式之间的区别

    Base64 加密, 这个其实不可以算作加密方法,它可以看作是一种编码方式,它的用途只是二进制数字和字符串进行相互转化. Base64是网络上最常见的用于传输 8Bit字节码的编码方式之一,是一种基于 ...

  9. Java DES、AES、RSA、DM5读取文件加密解密

    //下面代码是直接读取文件来进行加密解密,算法文件 package Test; import javax.crypto.KeyGenerator; import javax.crypto.Cipher ...

  10. java编码解码加密解密--md5、SHA-256、SHA-512、MAC、DES、AES、RSA

    md5 md5是一种散列算法,不可逆,是一种消息摘要算法,生成的字节数组的长度是128位,也就是等于16个字节,那么有的字节转化为字符之后,这些字符不一定是存在于ascii码之中,通常为了便于输出,我 ...

最新文章

  1. Cocos Creator 为Button添加事件的两种方法
  2. 查看源代码不方便?我有利器
  3. 盘点Kubernetes网络问题的4种解决方案
  4. [Oracle] UNIX与Windows 2000上Oracle的差异(II)
  5. S3C2440时钟体系
  6. 计算机主板 方便用户自己安装的是,电脑水冷安装教程步骤解析【图文】
  7. 标准 mysql 数据库 jdbc 的两种写法 懒汉式 和 饿汉式
  8. android 动态设置priority,Android属性之android:priority
  9. UC3842好坏的判断方法
  10. 计算机中函数的括号怎么输,Excel函数中括号的使用
  11. 修改Windows7启动画面与登录画面
  12. 抖音海外版tiktok404 amp; 简洁国际版apk
  13. VXLAN的广播域BD。
  14. MFC之对于文档类的DeleteContents和OnNewDocument说明29
  15. 2022化工自动化控制仪表考试题及答案
  16. css竖向箭头符号_如何用css实现三角形符号代码
  17. Python | OpenCV画图显示为一个全黑画布的情况
  18. 幼儿零基础学python_《幼》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
  19. 攻防世界高手区easytornado过关
  20. 【MME】Blood

热门文章

  1. 云计算大败局:基因与宿命
  2. 机器学习笔记(二十):逻辑回归(2)
  3. Kafka从上手到实践 - 实践真知:Kafka Java Consumer | 凌云时刻
  4. Golang 性能分析工具简要介绍
  5. 2050:技术未必会使我们摆脱愚昧,有时正相反(下)
  6. 【光学】基于matlab GUI带切趾的光线布拉格光栅滤波特性仿真【含Matlab源码 1505期】
  7. 【人脸识别】基于matlab PCA+LDA人脸识别【含Matlab源码 680期】
  8. 【车间调度】基于matlab粒子群算法求解生产调度问题【含Matlab源码 412期】
  9. Web服务器用户权限设置,Windows系统下WEB服务器权限的设置详解(四)
  10. tortoisesvn统计_TortoiseSVN使用教程——史上最全最易懂教程