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 举例

使用流程:

  1. 创建Cipher对象
  2. 初始化(指明具体操作)
  3. 加密/解密

加密 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(加密、解密)相关推荐

  1. Java常见的加密解密

    Java常见的加密解密 不可逆加密 介绍 应用场景 一致性验证 MD5 可以为文件传输场景中,提供文件的一致性验证. 例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法 ...

  2. 条理清晰的入门:使用Java实现RSA加密解密

    条理清晰的入门:使用Java实现RSA加密解密 什么是RSA 使用Java 需要导入的头文件 生成公钥.私钥 进行加密解密 密钥的存储 密文的存储.读取 什么是RSA 翻一下以前的密码学笔记,找到了! ...

  3. php与java的des加密解密

    与第三方接口对接des加密.解密,第三方提供java的des加密解密demo,特记录PHP与java加密解密. import javax.crypto.*; import javax.crypto.s ...

  4. java 文件进行加密解密,java 对文件加密解密,该如何解决

    java 对文件加密解密 本帖最后由 Hong_1993 于 2014-09-03 10:51:35 编辑 我现在想做一个基于spring mvc 模式的 实现对  文件或目录文件   的加解密(de ...

  5. java 3des_如何用Java进行3DES加密解密 java实现3des加密解密教程

    3des,全称为3DESede或TripleDES,中文解释为是三重数据加密,用户可以通过通过对DES算法进行改进,针对每个数据块进行三次DES加密,下面小编为你带来java实现3des加密解密教程! ...

  6. Java中3DES加密解密示例

    在java中调用sun公司提供的3DES加密解密算法时,需要使用到$JAVA_HOME/jre/lib/目录下如下的4个jar包: jce.jar security/US_export_policy. ...

  7. java 实现 DES加密 解密算法

    DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...

  8. 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )

    文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...

  9. Java使用AES加密解密

    AES加密机制: 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准. 这个标准用来替代原先的 ...

  10. Java使用RSA加密解密签名及校验

    RSA加密解密类: import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; i ...

最新文章

  1. 深入理解Python中的生成器
  2. 从零开始做一个SLG游戏(二):用mesh实现简单的地形
  3. 适用于android 4.0以上版本的子线程网络图片查看器
  4. python的代码有哪些_Python有哪些有趣的代码呢,这些代码让
  5. 关闭excel多余的addin,提供excel启动速度
  6. 64位CentOS6.2安装erlang及rabbitmqServer
  7. 前端学习(3345):设计模式之工厂模式2
  8. Sharepoint学习笔记—ECM系列--2 管理元数据服务应用Metadata Service Application
  9. Ubuntu 16.04 主题美化及常用软件安装
  10. Docker系列五~docker安装php-fpm
  11. 做老板的,首先要懂销售,销售什么?
  12. PyPDF2.utils.PdfReadError: Unexpected destination '/__WKANCHOR_2'
  13. Qt Creator子目录项目-类似VS解决方案
  14. WinForm如何输出中文星期几?
  15. 外星人电脑为什么那么贵_为什么系统门窗那么贵?
  16. Win8.1部署 .NET Framework 3.5 安装方式汇总
  17. 项目的webinf文件在哪_PMP章节练习(第四章:项目整合管理)
  18. NO.5 计算数组中三个数的最大乘积
  19. android 5.1 httpclient,【Android进阶学习】Http编程之HttpClient
  20. CactiEZ V10.1安装及配置

热门文章

  1. 打造最全皮肤,Python采集英雄联盟(LOL)官网数据!
  2. [昆仑叶哲华]房产的基本术语解读选房不愁
  3. conditional系列常用注解
  4. 大屏手机使用一个月有什么感觉?来看看它的魅力
  5. vcs产生code coverage与function coverage
  6. C# 使用数据库和MenuStrip动态生成菜单
  7. 如何在 Sony Playstation 3 安装 Fedora 9
  8. 工作五年后, 我离开腾讯!
  9. 我心中的坏男孩,愿你健康成长,早日闯出属于你自己的天地
  10. arcgis做dijkstra_改进的Dijkstra算法在GIS路径规划中的应用