社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
(1)通过对同一段明文分别进行DES、3DES、AES、PBE、CBC、IDEA、RSA、Caesar 8 种加密、以及 MD5、SHA-1、SHA-256 3 种哈希算法的实现,从而比较不同的加密 / 哈希算法的消耗时间,进而对它们的运行效率进行对比;
(2)学习 Java 中 javax.crypto.Cipher 类的原理,深入理解 JCE 框架的核心;
(3)对各种对称、非对称以及哈希算法的原理进行巩固复习,掌握它们实现的基本原理、密钥长度、实现机制、算法流程、应用环境、优缺点、安全性等基础知识。
(1)处理器:Inter ® Pentium ® CPU 3825U @1.90 GHz;
(2)安装内存 (RAM):4.00 GB;
(3)系统类型:64 位操作系统;
(4)Windows 版本:Windows 7;
(5)运行平台:Eclipse Java EE IDE for Web Developers;
Version: Oxygen Release (4.7.0)。
算法公开、计算量小、加密速度快、效率高。
暴力破解、穷举。
普通数据加密。
低。
难度较大。
较高。
分组模式选择多,加密安全。
较高。
PBE(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数、杂凑、多重加密等方法保证数据的安全性。
PBE 算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由 PBE 算法中的 KDF 函数完成。
KDF 函数的实现过程为:
国际数据加密算法(IDEA)是上海交通大学教授来学嘉与瑞士学者 James Massey 联合提出的,它在 1990 年正式公布并得到增强。这种算法是在 DES 算法的基础上发展出来的,类似于三重 DES。发展 IDEA 也是因为 DES 密钥太短等缺点,IDEA 的密钥为 128 位,在今后若干年内应该是安全的。
类似于 DES,IDEA 算法也是一种分组加密算法,它设计了一系列加密轮次,每轮加密都使用从完整的加密密钥中生成的一个子密钥。与 DES 的不同之处在于,它在软件和硬件实现上同样快速。
由于 IDEA 是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制,因此,有关 IDEA 算法和实现技术的书籍都可以自由出版和交流,极大地促进了 IDEA 的发展和完善。
目前 IDEA 在工程中已有大量应用实例:
原理简单。
高。
作为一种最为古老的对称加密体制,凯撒密码在古罗马的时候就已经很流行了。它的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果字母的位数是 3,明文字母 B 就变成了密文的 E,依次类推,X 将变成 A,Y 变成 B,Z 变成 C……由此可见,位数就是凯撒密码加密和解密的密钥。
一般化的凯撒加密算法为: C=E(k,P)=(P+k)mod26;
一般化的凯撒解密算法为: P=D(k,C)=(C−k)mod26。
按照 512 位分组处理,每一个分组分为 16 个 32 位子分组,处理后输出 4 个 32 位分组,将这 4 个分组级联后生成 128 位散列值。
简单、难以伪造。
具有潜在的冲突;有破解的案例。
较高。
把原始信息变换成位(二进制)字符串,5 个步骤计算:
1)补位:消息满足长度在对 512 取模后余数是 448,否则补位;
2)补长度:原始数据长度补到补位操作的后面,如果大于 512,补成 512 的倍数;
3)使用常量和相关的函数;
4)计算消息摘要。
保密性强。
效率较低;难度大。
高。
基于 Java 中的 javax.crypto.Cipher 类,可以实现各种算法的加密和解密功能,该类是 JCE 框架的核心。
public static Cipher getInstance(String transformation,String provider);
参数 transformation 是一个字符串,它描述了由指定输入产生输出所进行的操作或操作集合。它包含密码学算法名称,比如 DES,也可以在后面包含模式和填充方式。如果没有指定模式或填充方式,就使用特定提供者指定的默认模式或默认填充方式。
当以流密码方式请求以块划分的 Cipher 时,可以在模式名后面跟上一次运算需要操作的 bit 数目。如果没有指定数目,则使用提供者指定的默认值。
通过 getInstance 得到的 Cipher 对象使用下列四个模式之一进行初始化,这四个模式在 Cipher 类中被定义为 final integer 常数,可以使用符号名来引用这些模式:
ENCRYPT_MODE, 加密数据;
DECRYPT_MODE, 解密数据;
WRAP_MODE, 将一个 Key 封装成字节,可以用来进行安全传输;
UNWRAP_MODE, 将前述已封装的密钥解开成 java.security.Key 对象。
每个 Cipher 初始化方法使用一个模式参数 opmod,并用此模式初始化 Cipher 对象。此外还有其他参数,包括密钥 key、包含密钥的证书 certificate、算法参数 params 和随机源 random。
加密和解密必须使用相同的参数。当 Cipher 对象被初始化时,它将失去以前得到的所有状态,即初始化 Cipher 对象与新建一个 Cipher 实例后将它初始化是等价的。
在多步加密或解密数据时,首先需要一次或多次调用 update 方法,用以提供加密或解密的所有数据。
如果还有输入数据,多步操作可以使用 doFinal 方法之一结束。如果没有数据,多步操作可以使用 doFinal 方法结束。
如果在 transformation 参数部分指定了 padding 或 unpadding 方式,则所有的 doFinal 方法都要注意所用的 padding 或 unpadding 方式。
调用 doFinal 方法将会重置 Cipher 对象到使用 init 进行初始化时的状态,也就是说,Cipher 对象被重置,使得可以进行更多数据的加密或解密。这两种模式可以在调用 init 时进行指定。
3、wrap 密钥必须先使用 WRAP_MODE 初始化 Cipher 对象,然后调用方法:
public final byte[] wrap(Key key);
如果将调用 wrap 方法后的密钥字节提供给 unwrap 的人使用,必须向接收者发送额外信息。
(1)密钥算法名称:
调用 Key 接口提供的 getAlgorithm 方法:
public String getAlgorithm();
(2)包裹密钥的类型:
(Cipher.SECRET_KEY,Cipher.PRIVATE_KEY,Cipher.PUBLIC_KEY)
(1)采用 CBC、CFB、OFB、PCBC 模式的 DES、DES-EDE 和 Blowfish算法使用初始化向量 IV 作为参数。可以使用 javax.crypto.spec.IvParameterSpec 类并使用给定的 IV 参数来初始化 Cipher 对象。
(2)PBEWithMD5AndDES 使用的参数是一个由盐值和迭代次数组成的参数集合。可以使用 javax.crypto.spec.PBEParameterSpec 类并利用给定盐值和迭代次数来初始化 Cipher 对象。
(3)Cipher 中的某些 update 和 doFinal 方法允许调用者指定加密或解密数据的输出缓存。此时,保证指定的缓存足够大以容纳加密或解密运算的结果是非常重要的,可以使用 Cipher 的以下方法来决定输出缓存应该有多大:
public int getOutputSize(int inputLen)。
对于待验证的所有 11 种加解密以及哈希算法,为保证时间效率计算的一致性,因此下面均使用相同的明文 “In doing we learn.” 对其进行加密,具体结果分析如下:
计算 10 次 DES 加密的时间消耗平均值,可以得出,在本系统平台上,DES 算法的平均时间消耗约为 1826 ms。
计算 10 次 3DES 加密的时间消耗平均值,可以得出,在本系统平台上,3DES 算法的平均时间消耗约为 2021 ms。
计算 10 次 AES 加密的时间消耗平均值,可以得出,在本系统平台上,AES 算法的平均时间消耗约为 1941 ms。
计算 10 次 PBE 加密的时间消耗平均值,可以得出,在本系统平台上,PBE 算法的平均时间消耗约为 1376 ms。
计算 10 次 CBC 加密的时间消耗平均值,可以得出,在本系统平台上,CBC 算法的平均时间消耗约为 1318 ms。
计算 10 次 IDEA 加密的时间消耗平均值,可以得出,在本系统平台上,IDEA 算法的平均时间消耗约为 2328 ms。
计算 10 次 RSA 加密的时间消耗平均值,可以得出,在本系统平台上,RSA 算法的平均时间消耗约为 2288 ms。
计算 10 次 MD5 哈希算法的时间消耗平均值,可以得出,在本系统平台上,MD5 算法的平均时间消耗约为 97 ms。
计算 10 次 SHA-1 哈希算法的时间消耗平均值,可以得出,在本系统平台上,SHA-1 算法的平均时间消耗约为 117 ms。
计算 10 次 SHA-256 哈希算法的时间消耗平均值,可以得出,在本系统平台上,SHA-256 算法的平均时间消耗约为 145 ms。
n = 5:
n = 8 :
n = 16:
n = 21:
计算 10 次 Caesar 加密的时间消耗平均值,可以得出,在本系统平台上,Caesar 算法的平均时间消耗约为 2 ms。
综合上述各种算法的运行时间,统计出它们分别的效率对比,如图所示:
通过上面的统计结果可以大致看出:
(1)针对各种加密算法,在本运行平台上的消耗时间为:
IDEA > RSA > 3DES > AES > DES > PBE > CBC > Caesar
(2)针对各种 Hash 算法,在本运行平台上的消耗时间为:
SHA-256 > SHA-1 > MD5
对称算法:
密钥管理:比较难,不适合互联网,一般用于内部系统;
安全性:中;
速度:快好几个数量级(软件加解密速度至少快 100 倍,每秒可以加解密几兆比特的数据),适合大数据量的加解密处理。
非对称算法:
密钥管理:密钥容易管理;
安全性:高;
速度:慢,适合小数据量加解密或数据签名。
Hash 算法:
MD5 输出 128 bit、SHA1 输出 160 bit、SHA256 输出 256 bit。
SHA-1 是 160 位的哈希值,而 SHA-2 是组合值,有不同的位数,其中最受欢迎的是 256 位。
因为 SHA-2 有多种不同的位数,导致这个名词有一些混乱。但无论是“SHA-2”、“SHA-256” 或 “SHA-256 位”,其实都是同一种加密算法。SHA-224、SHA-384 或 SHA-512 表示 SHA-2 的二进制长度。
SSL 行业选择 SHA 作为数字签名的散列算法,但随着互联网技术的提升,SHA-1 的缺点越来越突显。在 SHA-2 成为了新的标准之后,签发的 SSL 证书必须使用该算法签名。
安全性方面,SHA-256 的安全性最高,但是耗时要比其他两种多很多。MD5 相对较容易破解,因此,SHA-1 是这三种中性能较好的一款哈希算法。
一开始,我在编写加密函数时,由于对字节数组 byte[] 以及 String 对象之间的转化不当,导致了程序加密的输出结果呈现乱码,有许多问号 ? 等特殊字符,这显然不符合加密结果的要求,如图所示:
之后,我尝试在调用 toString 方法时,将输出结果用参数 “utf-8” 强制转换,但效果不佳。在查阅了相关的资料后,我发现可以编写一个函数,将结果用 Base64 编码来表示:
public static String encryptBase64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
}
这样一来,就可以将加密的编码方式转换为 Base64,此时的加密输出结果也更加易于表示、传输与解密。
报错内容:
Access restriction: The constructor SunJCE() is not accessible due to restriction on required library C:Program FilesJavajre7libextsunjce_provider.jar
查找相关文档的解释说明后,我发现该错误是由于
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!