java jce-Cipher(加密、解密)
java jce-Cipher(加密、解密)
在开发时,总要涉及到数据的加密与解密,之前一直有些糊涂,最近看了 jce.jar的源码,来整理记录一下
1、概念
JCA(Java Cryptography Architecture): Java密码体系结构
JCE(Java Cryptography Extension):它是一组包,提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供了对称、不对称、块和流密码的加密支持,并且还支持安全流和密封的对象,不对外出口,开发完成封装后将无法调用。
在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。
在JDK1.1-1.3版本期间,JCE属于扩展包,仅供美国和加拿大的用户下载,JDK1.4+版本后,JCE已经捆绑在JDK中,即jdk中的 jce.jar 包
1.1 加密算法
数据加密的基本过程就是对原来为明文的 文件 或 数据 按某种 算法 进行处理,使其成为不可读的一段代码为“密文”,使其只能在输入相应的 密钥 之后才能显示出原容,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的,常见的加密算法,分为对称加密与非对称加密
1.1.1 对称式加密技术
加密和解密使用同一个密钥,通常称之为“Session Key ” ,如美国政府所采用的 DES 加密标准就是一种典型的 对称式加密法,它的Session Key长度为56bits
1.1.2 非对称式加密技术
加密和解密所使用的不是同一个密钥,通常有两个密钥,称为**“公钥”和“私钥”,它们两个必需配对使用**,否则不能打开加密文件
“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。它的优越性就在这里,因为对称式的加密方法如果是在网络上传输加密文件就很难不把密钥告诉对方,不管用什么方法都有可能被别人窃听到。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,也就不怕别人知道,收件人解密时只要用自己的私钥即可以,这样就很好地避免了密钥的传输安全性问题
1.1.3 常用的加密算法
算法名称 | 密钥长 | 块长 | 速度 | 说明 | 类型 |
---|---|---|---|---|---|
DES | 56 | 64 | 较快 | 适用于加密大量数据,不太安全 | 对称加密 |
3DES | 112/168 | 64 | 较慢 | 中等安全, 适合加密较小的数据 | 对称加密 |
AES | 128, 192, 256 | 128 | 快 | 安全 | 对称加密 |
Blowfish | (4至56)*8 | 64 | 快 | 应该安全, 在安全界尚未被充分分析、论证 | 对称加密 |
RC4 | 40-1024 | 64 | 很快 | 安全性不明确,变长密钥对大量数据进行加密 | 对称加密 |
RSA | 500-1024 | 很慢 | 512位被视为不安全的;768位不用担心受到危害;1024位几乎是安全的,用于少量数据加密 | 飞对称加密 | |
MD5 | 128 | 32 | 快 | 普遍、稳定广泛应用于普通数据,不可逆 | 散列算法 |
SHA1 | 160 | 快 | 安全散列算法,但安全性如今被密码学家严重质疑 | 散列算法 |
总结:
- 非对称加密普遍会比对称加密慢,取决于密码长度(长度长计算复杂度大)
- 非对称加密普遍使用RSA,对称加密普遍使用AES
- 对称加密的密钥管理较为重要,需要保证传输的安全性
- 散列算法的安全性不高,有被破解的可能
2、核心类与核心方法
以jdk 1.8 为例进行下面的说明
jce.jar 包的核心API都在 javax.crypto 包下,主要包括:加解密、密钥生成(对称)、MAC生成、密钥协商等核心功能
核心的一些类/接口如下:
- Cipher
- KeyGenerator
- SecretKeyFactory
这篇主要介绍Cipher,其他的会单独写一些博客来记录一下
Cipher
加解密功能在该类实现,是JCE中最核心的类
- 加密:是获取数据(称为明文)和 密钥,并生成对不知道密钥的第三方无意义的数据(密文)的过程
- 解密:加密逆过程,获取密文和密钥并生成明文
主要由以下方法:
- getInstance:创建一个Cipher对象
- init:Cipher对象初始化
- update:执行加密或解密数据(多步骤)如果事先不知道数据的长度,或者数据太长,无法一次存储在内存中,则使用该操作
- doFinal:执行加密或解密数据(单步骤)
下面详细说明:
1 getInstance:创建一个Cipher对象
根据以下三种重载方法获取到一个Cipher对象
// var0 是 transformation
public static final Cipher getInstance(String var0) throws NoSuchAlgorithmException, NoSuchPaddingException {}
// var1 是具体的 provider name java.security.Security根据name获取Prvider
public static final Cipher getInstance(String var0, String var1) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {}
// var1 是具体的provider
public static final Cipher getInstance(String var0, Provider var1) throws NoSuchAlgorithmException, NoSuchPaddingException {}
说明:
1)transformatior有以下两种形式: 具体细节与详情可查看 Java密体系结构标准算法文档 ,算法 algorithm必填,缺省的mode为ECB,缺省的padding为PKCS5Padding
- “algorithm/mode/padding” example:“AES/CBC/PKCS5Padding”
- “algorithm” example:“AES”
algorithm取值:
- AES / AESWrap
- ARCFOUR
- Blowfish
- RC2 / RC4 / RC5
- RSA
- DES / DESede / DESedeWrap / ECIES
mode取值:具体可查看 加密模式介绍(ECB、CBC、PCBC、CFB、OFB、CTR)
- NONE
- CBC
- CCM
- CFB, CFBx
- CTR / CTS
- ECB
- GCM
- OFB, OFBx
- PCBC
padding取值:(分组算法的时候若数据不是块的整数倍,需要进行填充)具体可查看 分组加密中的填充介绍
- NoPadding
- ISO10126Padding
- OAEPPadding / OAEPWithAndPadding
- PKCS1Padding / PKCS5Padding
- SSL3Padding
2 init:Cipher对象初始化
根据以下几种重载方法进行Cipher对象初始化
// opmode 操作模式,有四种
// key 密钥,Key 的子类很多,根据具体的加密算法来选择合适的密钥
public void init(int opmode, Key key);// certificate 身份(一个主体对另一个主体证明的公钥的绑定)
public void init(int opmode, Certificate certificate);// random 加密强随机数
public void init(int opmode, Key key, SecureRandom random);public void init(int opmode, Certificate certificate,SecureRandom random);// params 加密参数规范 用于加密的参数必须用于解密
public void init(int opmode, Key key,AlgorithmParameterSpec params);public void init(int opmode, Key key,AlgorithmParameterSpec params, SecureRandom random);public void init(int opmode, Key key,AlgorithmParameters params);public void init(int opmode, Key key,AlgorithmParameters params, SecureRandom random);
Cipher有4种操作模式(即var1有四种取值):
- ENCRYPT_MODE:加密
- DECRYPT_MODE:解密
- WRAP_MODE:将key包装成字节,以便可以安全地传输密钥,导出Key
- UNWRAP_MODE:将以前包装的密钥解包到key中,导入Key
3 update:执行加密或解密数据(多步骤)
根据以下四种重载方法执行加密/解密,一般用于不知道数据的长度,用该操作
// input:加密数据,返回处理后的byte数组
public byte[] update(byte[] input);
// inputOffset:数据开始位置
// inputLen:数据加密长度 返回处理后的byte数组
public byte[] update(byte[] input, int inputOffset, int inputLen);// output:处理后的数据存储,返回是否成功(0/1)
public int update(byte[] input, int inputOffset, int inputLen,byte[] output);
// output:处理后的数据存储
// outputOffset :处理后的数据存储起始位置,返回是否成功(0/1)
public int update(byte[] input, int inputOffset, int inputLen,byte[] output, int outputOffset)
4 doFinal:执行加密或解密数据(单步骤)
根据以下四种重载方法执行加密/解密
// input:加密数据,返回处理后的byte数组
public byte[] doFinal(byte[] input);
// inputOffset:数据开始位置
// inputLen:数据加密长度 返回处理后的byte数组
public byte[] doFinal(byte[] input, int inputOffset, int inputLen);
// output:处理后的数据存储,返回是否成功(0/1)
public int doFinal(byte[] input, int inputOffset,int inputLen, byte[] output);
// output:处理后的数据存储
// outputOffset :处理后的数据存储起始位置,返回是否成功(0/1)
public int doFinal(byte[] input, int inputOffset,int inputLen, byte[] output, int outputOffset)
5 举例
使用流程:
- 创建Cipher对象
- 初始化(指明具体操作)
- 加密/解密
加密 example:
// 用于加强的seed
private static String strKey = "diaxxxxoft@201Y10";
// 获取密钥key
private static Key getKey(String strKey) throws NoSuchAlgorithmException {KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128 ,new SecureRandom(strKey.getBytes()));SecretKey secretKey = keyGenerator.generateKey();byte[] enCodeFormat = secretKey.getEncoded();return new SecretKeySpec(enCodeFormat, "AES");
}
/**
* 根据密钥{@link #getKey()}对指定的明文 plainText进行加密.** @param plainText 明文* @return 加密后的密文.*/
public static void encryptData(String plaintext) {System.out.println("-------Encrypting data using AES algorithm-------");try {byte[] plaintTextByteArray = plaintext.getBytes("UTF8");// 定义Cipher cipher = Cipher.getInstance("AES");// 初始化cipher.init(Cipher.ENCRYPT_MODE, getKey(strKey));// 加密byte[] cipherText = cipher.doFinal(plaintTextByteArray);System.out.println("Original data: " + plaintext);System.out.println("Encrypted data:");for (int i = 0; i < cipherText.length; i++) {System.out.print(cipherText[i] + " ");}
// BASE64Encoder encoder = new BASE64Encoder();
// String encoded = encoder.encode(cipherText);
// decryptData(encoded);}catch(Exception ex){ex.printStackTrace();}
}
输出:
Original data: mlpan@019
Encrypted data:
96 -82 -108 -12 31 54 -24 69 94 -80 52 -93 -3 121 77 62
解密 example:
public static void decryptData(String cipherText) {System.out.println();System.out.println("-------Decrypting data using AES algorithm-------");try {BASE64Decoder decoder = new BASE64Decoder();byte[] c = decoder.decodeBuffer(cipherText);System.out.println("Encrypted data:" + cipherText);// 创建Cipher cipher = Cipher.getInstance("AES");// 初始化cipher.init(Cipher.DECRYPT_MODE, getKey(strKey));// 解密byte[] bytes = cipher.doFinal(c);System.out.println("Original data: " + new String(bytes));} catch (Exception ex) {ex.printStackTrace();}
}
输出:
Encrypted data:nEgCrS0YxLzCO+TO8ZO4ng==
Original data: mlpan@019
相关链接
1、JCA
java JCA参考指南
Java密体系结构标准算法文档
java jce-Cipher(加密、解密)相关推荐
- Java常见的加密解密
Java常见的加密解密 不可逆加密 介绍 应用场景 一致性验证 MD5 可以为文件传输场景中,提供文件的一致性验证. 例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法 ...
- 条理清晰的入门:使用Java实现RSA加密解密
条理清晰的入门:使用Java实现RSA加密解密 什么是RSA 使用Java 需要导入的头文件 生成公钥.私钥 进行加密解密 密钥的存储 密文的存储.读取 什么是RSA 翻一下以前的密码学笔记,找到了! ...
- php与java的des加密解密
与第三方接口对接des加密.解密,第三方提供java的des加密解密demo,特记录PHP与java加密解密. import javax.crypto.*; import javax.crypto.s ...
- java 文件进行加密解密,java 对文件加密解密,该如何解决
java 对文件加密解密 本帖最后由 Hong_1993 于 2014-09-03 10:51:35 编辑 我现在想做一个基于spring mvc 模式的 实现对 文件或目录文件 的加解密(de ...
- java 3des_如何用Java进行3DES加密解密 java实现3des加密解密教程
3des,全称为3DESede或TripleDES,中文解释为是三重数据加密,用户可以通过通过对DES算法进行改进,针对每个数据块进行三次DES加密,下面小编为你带来java实现3des加密解密教程! ...
- Java中3DES加密解密示例
在java中调用sun公司提供的3DES加密解密算法时,需要使用到$JAVA_HOME/jre/lib/目录下如下的4个jar包: jce.jar security/US_export_policy. ...
- java 实现 DES加密 解密算法
DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...
- 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )
文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...
- Java使用AES加密解密
AES加密机制: 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准. 这个标准用来替代原先的 ...
- Java使用RSA加密解密签名及校验
RSA加密解密类: import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; i ...
最新文章
- Docker之tomcat和nginx的部署
- CSS3特效之转化(transform)和过渡(transition)
- 分离图片中的隐藏文件方法总结
- 时间轴ui设计_我应该在UI设计上花更多时间吗?
- 基于TableStore的海量电商订单元数据管理
- CSS+JS实现兼容性很好的无限级下拉菜单
- opengl 图片处理 卷纸弯曲效果_神笔马良——基于 OpenGL 的涂鸦框架
- 华南理工大学 电力电子技术(王兆安) 期末复习笔记3 第五章第六章第七章
- Ubuntu串口驱动安装及串口权限设置
- Mac —— QuickTime录屏 声音小解决
- LINUX(CENTOS7.X)SVN部署文档+pycharmSvn
- 别人笑我太疯癫,我笑他人看不穿。
- 加入企业黄页有什么好处?
- 【解决】iptables -P INPUT DROP后无法联网
- 数字信号处理实验线性卷积与循环卷积计算
- 中国剩余定理(也叫孙子定理)
- 写了也不看之第一学期c语言总结
- Python制作某电商平台商品竞拍脚本,能自动定时、抢拍、购买!吊不吊?
- 阿乐卡特交换机配置手册
- 战地3皓月服务器win10系统,win10系统战地3打不开的方法