大家好,又见面了,我是你们的朋友全栈君。
Java Cryptography Extension(JCE)是一组包,它们提供用于加密、生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。
在JDK1.1-1.3版本期间,JCE属于扩展包,仅供美国和加拿大的用户下载,JDK1.4+版本后,随JDK核心包一起分发。
JCE的API都在 javax.crypto 包下,核心功能包括:加解密、密钥生成(对称)、MAC生成、密钥协商。
加解密功能由Cipher组件提供,其也是JCE中最核心的组件。 Cipher的几个知识点:
一般情况下,不要选择DES算法,推荐使用AES算法。一般认为128bits的密钥已足够安全,如果可以请选择256bits的密钥。
<1>密钥长度是在生成密钥时指定的。如:
<2>生成长度超128bits的密钥,需单独从Oracle官网下载对应JDK版本的Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files文件《详见:》,例如
Cipher可能用到算法参数(AlgorithmParameterSpec或AlgorithmParameters)的情形:
下面是采用PBE算法进行加解密的示例:
测试代码:
非对称密钥的生成请参考java.security.KeyPairGenerator,样例代码请参考中的示例,对称密钥生成的示例代码如下
MAC技术用于确认数据的完整性,Mac要求通讯双方共享一个secret key,示例代码如下:
MAC优于数据摘要的地方在于:MAC双方要共享一个密钥,所以其也有互相认证的功能,可有效防止数据摘要中明文和数据摘要被同时替换而无法发现的问题。
密钥协商就是在通讯多方间不直接交换通讯密钥的情况下而选择一个大家达成一致的密钥(session key),这个session key是对称密钥。
a. DH算法由PKCS#3定义,DH算法需在多方间交换公钥,大素数p,私钥的基数g,和私钥的长度l。设协商密钥的双方为Alice和Bob,则协商共涉及5个阶段:
b. 下面的代码演示了使用DH算法实现密钥协商,设通讯一方为Alice,另一方为Bob,分别由两个线程模拟,实际数据交换由共享内存模拟:
以上代码参考了Java Cryptography Extension (JCE) Reference Guide(JDK5.0)中Appendix F的例子。
数字信封的原理就是利用通讯对方的公钥加密目标密钥(session key,对称密钥),使用目标密钥对报文进行加密,然后将密钥密文与报文密文一起发送给接收方。接收方首先使用自己的私钥对密钥报文进行解密,这样就得到了协商后的密钥,再使用解密后的密钥解密报文,这样就得到了业务数据。过程图示如下:
代码示例如下,密钥协商双方由两个线程模拟:
KeyAgreement的DH与数字信封的RSA比较:
JCE中最常用和最核心的功能就是加解密,此功能由Cipher组件提供,在使用Cipher前需对加密算法及参数先做出选择:
对称算法一般速度较快,非对称算法速度较慢;对称算法的密钥管理比较困难,非对称算法密钥管理简单;非对称算法一般用于认证和加密会话密钥,通讯双方大部分也就是在开启会话时使用一次,对称算法一般用来加密双方之间的报文/交换的数据,使用频度较高。
块(Block)模式加密以块为基本单位,适用于明文长度已知的情形;流(Stream)模式以bit或byte为加解密单位, 适用于明文长度未知、内容较大的情形,如加密一个套接字管道或文件读写流等,一般仅适用于硬件实现。块模式下不同算法的块大小可能不一样,一般都是2的次方数,大部分长度为64bits,整个明文长度不是块长度整倍数时,需在最后一个Block进行补长(Padding)
使用块算法加密,如果明文有大量重复的内容,则对块加密后得到的密文也会存在大量的重复,这对密文分析、激活成功教程提供了极大的便利,为消除这方面的威胁,有个思路就是对不同块密文再进行运算,这样就极大去除了块密文与块明文几间的特征关联,这种做法称为块反馈模式。常见的反馈模式有:ECB、CBC、CFB、OFB等。对于第1个block,因没有其它块密文可供运算,有的模式引入了初始矢量(Initialization Vector,IV,由用户指定)作为第1个block内容,这样就进一步解决了第1个block密文的脆弱性。注意:尽量不要使用ECB模式。
下面是一些常见的补长(Padding)方案,以DES算法加密明文for为例,因for不足8bytes,所以需补长5bytes(for ?? ?? ?? ?? ??),则这5bytes可能选择(16进制):
JCE中支持的补长方案包括:NoPadding、PKCS5Padding、ISO10126Padding、OAEPWithAndPadding和SSL3Padding,NoPadding即不补长,其中最常用的就是PKCS5Padding和ISO10126Padding。
简单的说PKCS5Padding就2个规则:
如前述的明文for将补长为:66 6F 72 05 05 05 05 05ISO10126Padding,具体规范请参考。简单的说ISO10126Padding就是补长的长度作为补长内容的最后一个byte,之前的补长内容为随机数。
如前述的明文for可能补长为:66 6F 72 2A 75 EF F8 05
密钥可以使用KeyGenerator/KeyPairGenerator生成,也可以由外部导入,还可以有密钥参数构造KeySpec再转换为Key。
对于对称加密算法,128bits的密钥足够安全,条件许可请选择256bits,注意密钥长度大于128bits需单独下载并安装jurisdiction policy files;对于非对称加密算法,1024bits的密钥足够安全。
最后,如选用基于口令的算法或在用户输入密码时,请避免使用String来引用,使用char[],用完立刻置空char[],避免内存攻击,如heap dump分析等。
参考资料:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149236.html原文链接:https://javaforall.cn
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/8031.html