java jce-KeyGenerator(密钥生成)
在开发时,总要涉及到数据的加密与解密,之前一直有些糊涂,最近看了 jce.jar的源码,来整理记录一下
接着上篇 java jce-Cipher(加密、解密) 来介绍一下 关于密钥生成的KeyGenerator
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 java jce-Cipher(加密、解密)
- KeyGenerator
- SecretKeyFactory
这篇介绍KeyGenerator
KeyGenerator
该类主要用于生成密钥
- 在Cipher 初始化的时候,可以指定密钥 Key,而该Key的具体生成可由该类实现
主要由以下方法:
- getInstance:创建一个KeyGenerator对象
- init:KeyGenerator对象初始化
- generateKey:生成密钥
下面详细说明:
1 getInstance:创建一个KeyGenerator对象
根据以下三种重载方法获取到一个KeyGenerator对象(与Cipher的创建雷同)
// algorithm 是 算法名称
public static final Cipher getInstance(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {
}
// provider 是具体的 provider name java.security.Security 根据name获取Prvider
public static final Cipher getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
}
// provider 是具体的provider
public static final Cipher getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException, NoSuchPaddingException {
}
说明:
1)这里的算法名称与Cipher有些不同,其只有一种表示方式,就是算法名称,而不像Cipher有 “algorithm/mode/padding” 的形式表示
algorithm取值:
- AES / AESWrap
- ARCFOUR
- Blowfish
- RC2 / RC4 / RC5
- RSA
- DES / DESede / DESedeWrap / ECIES
2 init:KeyGenerator对象初始化
根据以下几种重载方法进行KeyGenerator对象初始化
// random :随机数发生器
public void init(SecureRandom random);
// keysize:密钥长度
public void init(int keysize);
public void init(int keysize, SecureRandom random);
// params:加密参数
public void init(AlgorithmParameterSpec params);
public void init(AlgorithmParameterSpec params, SecureRandom random);
说明:
SecureRandom
:随机数发生器,它产生加密强随机数。如果生成器中的随机性不足,则更容易破坏保护机制,一般可使用相同的种子来生成相同的随机数,保证密钥是相同的,如果不指定,默认每次都是不带随机种子的 new SecureRandom()- keySize:这个根据使用的加密算法,来指定密钥的长度
AlgorithmParameterSpec
:加密参数透明规范的接口,一般 像有些加密算法,第一个消息加密的时候是需要 初始化向量IV,那么就可以借助 IvParameterSpec来定义一个初始化向量,以这个参数传入
Cipher有4种操作模式(即var1有四种取值):
- ENCRYPT_MODE:加密
- DECRYPT_MODE:解密
- WRAP_MODE:将key包装成字节,以便可以安全地传输密钥,导出Key
- UNWRAP_MODE:将以前包装的密钥解包到key中,导入Key
3 generateKey:生成密钥
通过上述创建好并且初始化好的KeyGenerator对象进行密钥的创建
// 生成密钥
public SecretKey generateKey();
4 举例
使用流程:
- 创建
- 初始化
- 生成密钥
example:
private static Key getKey(String strKey) throws NoSuchAlgorithmException {
// 1.创建
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
// 2. 初始化
keyGenerator.init(128 ,new SecureRandom(strKey.getBytes()));
// 3、生成密钥
SecretKey secretKey = keyGenerator.generateKey();
return secretKey;
}
相关链接
1、JCA