11 种加密 哈希算法的原理及其 Java 实现
11 种加密 & 哈希算法的原理及其 Java 实现
- 一、目的
- 二、运行环境
- 三、基本原理及步骤
- (I)各种加密算法的原理:
- ① DES 数据加密标准(Data Encryption Standard):
- 算法介绍
- 算法流程
- 优点
- 缺点
- 破解方式
- 适用场景
- 安全性
- ② 3DES(DES ede)(或称为Triple DES)——是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)的通称 :
- 算法介绍
- 算法流程
- 破解方式
- 安全性
- ③ AES 高级加密标准(Advanced Encryption Standard,AES):
- 算法介绍
- 算法流程
- 优点
- 缺点
- 安全性
- ④ PBE(Password Based Encryption,基于口令加密):
- 算法原理
- 算法流程
- ⑤ IDEA(国际数据加密算法):
- 算法介绍
- 算法特点
- 应用领域
- ⑥ RSA:
- 算法介绍
- 算法流程
- 优点
- 缺点
- 应用场景
- 安全性
- ⑦ 凯撒密码:
- 算法介绍
- 算法流程
- (II)各种 Hash 算法的原理:
- ① MD5:
- 算法介绍
- 算法流程
- 优点
- 缺点
- 应用场景
- 安全性
- ② SHA1:
- 算法介绍
- 算法流程
- 优点
- 缺点
- 应用场景
- 安全性
- (III)javax.crypto.Cipher 类的原理
- 四、数据记录、仿真及设计
- (一)DES 算法的结果分析
- (二)3DES 算法的结果分析
- (三)AES 算法的结果分析
- (四)PBE 算法的结果分析
- (五)CBC 算法的结果分析
- (六)IDEA 算法的结果分析
- (七)RSA 算法的结果分析
- (八)MD5 算法的结果分析
- (九)SHA1 算法的结果分析
- (十)SHA256 算法的结果分析
- (十一)凯撒加密算法的结果分析
- 五、测试结果及分析
- ①结果分析
- ②总结
- ③遇到的问题及解决方法:
- i)字符串编码出现乱码
- ii)com.sun.crypto.provider.SunJCE() 报错
- 六、算法实现代码
- ① DES
- ② 3DES
- ③ AES
- ④ PBE
- ⑤ CBC
- ⑥ IDEA
- ⑦ RSA
- ⑧ MD5
- ⑨ SHA-1
- ⑩ SHA-256
- ⑪ Caesar
一、目的
(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)。
三、基本原理及步骤
(I)各种加密算法的原理:
① DES 数据加密标准(Data Encryption Standard):
算法介绍
- 属于对称加密算法;
- 数据分组(64 位)用密钥(64 位;其中 56 位有效位,8 位校验位)加密;
- 算法公开,对密钥保护。
算法流程
- 根据用户输入,取得一个 64 位的密钥,然后进行等分、移位、选取和迭代形成一套 16 个加密密钥,分别提供每轮运算使用;
- 对 64 位明文分组 MMM 进行操作,MMM 经过初期置换 IPIPIP,置换为 m0{m_{0}}m0,将 m0{m_{0}}m0 分为左右各 32 位长,并进行 16 轮相同的运算(迭代),每轮运算都和相应的密钥结合;
- 在每一轮中,密码位移位,从密钥的 56 位中选出 48 位,通过一个扩展置换将数据右半边扩展成 48 位,并通过异或操作替代成新的 48 位;然后压缩至 32 位,并通过一个异或与左半边结合,其结果为右半边,原来的右半边成为左半边,该操作执行 16 次;
- 经过 16 轮迭代,左右部分合在一起进行一个末置换(数据整理),完成加密过程;
- 解密时同样使用此算法。
优点
算法公开、计算量小、加密速度快、效率高。
缺点
- 如果双方都持有密钥,安全性无法保证;
- 密钥安全的保护成本高,管理困难。
破解方式
暴力破解、穷举。
适用场景
普通数据加密。
安全性
低。
② 3DES(DES ede)(或称为Triple DES)——是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)的通称 :
算法介绍
- 三重 DES 加密算法;
- 每个数据块用三次 DES 加密;
- 是 DES 向 AES 过渡的加密算法。
算法流程
- 加密过程:C=Ek3(Dk2(Ek1(P))){\rm{C = }}{{\rm{E}}_{{k_3}}}{\rm{(}}{{\rm{D}}_{{k_2}}}{\rm{(}}{{\rm{E}}_{{k_1}}}{\rm{(P)))}}C=Ek3(Dk2(Ek1(P)));
- 解密过程:P=Dk1(Ek2(Dk3(C))){\rm{P = }}{{\rm{D}}_{{k_1}}}{\rm{(}}{{\rm{E}}_{{k_2}}}{\rm{(}}{{\rm{D}}_{{k_3}}}{\rm{(C)))}}P=Dk1(Ek2(Dk3(C)))。
破解方式
难度较大。
安全性
较高。
③ AES 高级加密标准(Advanced Encryption Standard,AES):
算法介绍
- 属于对称加密算法;
- 基于排列置换算法;
- 易于软硬件实现;
- 属于分组密码体制;
- 用于取代原来的 DES。
算法流程
- 对数据进行 128 位(16 字节)的分组加密,每次对一组数据加密需要多轮;
- 输入密钥长度为:128、192 或 256,如果不够则补齐;
- 加密基本流程:
1)生成各轮的扩展密钥,存于 key 数组中,包含用户的输入密钥和扩展密钥;
2)将待加密数组与第一组密钥异或;
3)最后一轮前的变换操作:
SubBytes(state)——对数据进行 S 字节变换;
ShiftRows(state)——进行行变换;
MixColumns( state )——进行列混合变换;
AddRoundKey( state,Keys [当前轮密钥组] )——与当前轮密钥异或。
4)最后一轮变换操作
invShiftRows(state)——进行反行变换;
invSubBytes(state)——对数据进行反 S 字节变换;
AddRoundKey( state, Keys [第一组] )——与第一组密钥进行异或。 - 解密流程:与加密相反。
- 分组模式:
1)ECB(电码本模式):
优点:简单、并行计算、误差不会传递;
缺点:不能隐藏明文的模式、可能造成对明文的主动攻击。
2)CBC(密码分组链接):
优点:能抵抗主动攻击、安全性好于 ECB、适合传输较长报文、是 SSL,IPSec 的标准;
缺点:不利于并行计算、有误差传递、需要初始化向量;
3)CFB(密码反馈模式):
优点:隐藏明文的模式、将分组密码转化为流模式、可以及时加密传送分组的数据;
缺点:不利于并行计算、有误差传递、IVIVIV值唯一。
4)OFB(输出反馈模式):
优点:隐藏明文、将分组密码转化流模式、可以及时加密传送分组的数据;
缺点:不利于并行计算、可能对明文产生主动攻击、误差传递。
5)CTR(计数器模式):
优点:并行计算、仅要求实现加密算法而无需解密算法、无需填充、可以作为流进行高效加密。 - 常用填充方式:
NoPadding——不填充;
ZerosPadding——0 填充;
PKCS5Padding——每个填充都记录了填充的总数。
优点
分组模式选择多,加密安全。
缺点
- 同 DES 类似,存在密钥管理问题;
- 曾遭受线性密码攻击、差分密码攻击。
安全性
较高。
④ PBE(Password Based Encryption,基于口令加密):
算法原理
PBE(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数、杂凑、多重加密等方法保证数据的安全性。
PBE 算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由 PBE 算法中的 KDF 函数完成。
算法流程
KDF 函数的实现过程为:
- 将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥;
- 将准密钥经过散列函数,多次迭代后,生成最终的加密密钥;
- 密钥生成后,PBE 算法再使用对称加密算法对数据进行加密,可以选择 DES、3DES、RC5 等对称加密算法。
⑤ IDEA(国际数据加密算法):
算法介绍
国际数据加密算法(IDEA)是上海交通大学教授来学嘉与瑞士学者 James Massey 联合提出的,它在 1990 年正式公布并得到增强。这种算法是在 DES 算法的基础上发展出来的,类似于三重 DES。发展 IDEA 也是因为 DES 密钥太短等缺点,IDEA 的密钥为 128 位,在今后若干年内应该是安全的。
算法特点
类似于 DES,IDEA 算法也是一种分组加密算法,它设计了一系列加密轮次,每轮加密都使用从完整的加密密钥中生成的一个子密钥。与 DES 的不同之处在于,它在软件和硬件实现上同样快速。
由于 IDEA 是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制,因此,有关 IDEA 算法和实现技术的书籍都可以自由出版和交流,极大地促进了 IDEA 的发展和完善。
应用领域
目前 IDEA 在工程中已有大量应用实例:
- PGP ( Pretty Good Privacy)使用 IDEA 作为其分组加密算法;
- 安全套接字层 SSL(Secure Socket Layer)将 IDEA 包含在其加密算法库 SSLRef 中;
- 基于 IDEA 的 Exchange 安全插件;
- IDEA 加密芯片;
- IDEA 加密软件包等。
⑥ RSA:
算法介绍
- 非对称加密;
- 密钥长度决定了其复杂度;
- 简单原理:公钥加密、私钥解密;
私钥签名、公钥解密验证。
算法流程
- 随意选择两个大的质数 ppp 和 qqq,ppp 不等于 qqq,计算 N=p×qN = p × qN=p×q;
- 根据欧拉函数,求得 r=(p−1)(q−1)r = (p - 1)(q - 1)r=(p−1)(q−1);
- 选择一个小于 rrr 的整数 eee,求得 eee 关于模 rrr 的模反元素,命名为 ddd(模反元素存在,当且仅当 eee 与 rrr 互质);
- 将 ppp 和 qqq 的记录销毁;
- (N,e)(N,e)(N,e) 是公钥,(N,d)(N,d)(N,d) 是私钥。
优点
原理简单。
缺点
- 密钥生成较为麻烦,受到素数产生技术的限制,因此难以做到一次一密;
- 分组长度太大,不利于数据格式标准化;
- 加密难度大。
应用场景
- 数字签名;
- 公钥加密;
- 防止数据篡改;
- 用于通讯领域较多。
安全性
高。
⑦ 凯撒密码:
算法介绍
作为一种最为古老的对称加密体制,凯撒密码在古罗马的时候就已经很流行了。它的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果字母的位数是 3,明文字母 B 就变成了密文的 E,依次类推,X 将变成 A,Y 变成 B,Z 变成 C……由此可见,位数就是凯撒密码加密和解密的密钥。
算法流程
一般化的凯撒加密算法为: C=E(k,P)=(P+k)mod26C = E(k, P) = (P + k) mod 26C=E(k,P)=(P+k)mod26;
一般化的凯撒解密算法为: P=D(k,C)=(C−k)mod26P = D(k, C) = (C - k) mod 26P=D(k,C)=(C−k)mod26。
- 由于字母表中共有 26 个字符,因此移位前先将移动的位数 (keykeykey) 和 26 取模。将字符加上一个正整数即代表在字母表中右移多少位;
- 如果移动的位数是负值,则代表在字母表中左移多少位。尽管在移动之前已经将移动的位数和 26 取模,但通过这种方式实现右移或左移仍可能发生超界;
- 移位后进行判断,如果向左超界(c <‘a’)则增加 26;向右超界(c >‘z’)则减去 26。
(II)各种 Hash 算法的原理:
① MD5:
算法介绍
- 信息摘要算法;
- 压缩性:任意长度的数据,可以算出固定长度;
- 容易计算:从原数据计算 MD5 很容易;
- 抗修改性:对原数据修改 1 个字节,MD5 值的变化都很大;
- 强碰撞性:找一个具有相同 MD5 值的数据(伪造)比较困难;
- 具有不可逆性。
算法流程
按照 512 位分组处理,每一个分组分为 16 个 32 位子分组,处理后输出 4 个 32 位分组,将这 4 个分组级联后生成 128 位散列值。
优点
简单、难以伪造。
缺点
具有潜在的冲突;有破解的案例。
应用场景
- 登录密码保护;
- 防止文件篡改;
- HTTP 传输内容加密防篡改;
- 用于数字签名。
安全性
较高。
② SHA1:
算法介绍
- 属于消息摘要算法;
- 用于签名算法,保护数据的完整性;
- 算法不可逆;
- 消息算法:512 位。
算法流程
把原始信息变换成位(二进制)字符串,5 个步骤计算:
1)补位:消息满足长度在对 512 取模后余数是 448,否则补位;
2)补长度:原始数据长度补到补位操作的后面,如果大于 512,补成 512 的倍数;
3)使用常量和相关的函数;
4)计算消息摘要。
优点
保密性强。
缺点
效率较低;难度大。
应用场景
- 数字签名;
- 数据完整性保护。
安全性
高。
(III)javax.crypto.Cipher 类的原理
基于 Java 中的 javax.crypto.Cipher 类,可以实现各种算法的加密和解密功能,该类是 JCE 框架的核心。
- 与所有的引擎类一样,可以通过调用 Cipher 类中的 getInstance 静态工厂方法得到 Cipher 对象:
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 实例后将它初始化是等价的。
- 调用 doFinal()方法完成单步的加密或解密数据:
在多步加密或解密数据时,首先需要一次或多次调用 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)
- SunJCE 提供者实现的 Cipher 算法参数:
(1)采用 CBC、CFB、OFB、PCBC 模式的 DES、DES-EDE 和 Blowfish算法使用初始化向量 IVIVIV 作为参数。可以使用 javax.crypto.spec.IvParameterSpec 类并使用给定的 IVIVIV 参数来初始化 Cipher 对象。
(2)PBEWithMD5AndDES 使用的参数是一个由盐值和迭代次数组成的参数集合。可以使用 javax.crypto.spec.PBEParameterSpec 类并利用给定盐值和迭代次数来初始化 Cipher 对象。
(3)Cipher 中的某些 update 和 doFinal 方法允许调用者指定加密或解密数据的输出缓存。此时,保证指定的缓存足够大以容纳加密或解密运算的结果是非常重要的,可以使用 Cipher 的以下方法来决定输出缓存应该有多大:
public int getOutputSize(int inputLen)。
四、数据记录、仿真及设计
对于待验证的所有 11 种加解密以及哈希算法,为保证时间效率计算的一致性,因此下面均使用相同的明文 “In doing we learn.” 对其进行加密,具体结果分析如下:
(一)DES 算法的结果分析
计算 10 次 DES 加密的时间消耗平均值,可以得出,在本系统平台上,DES 算法的平均时间消耗约为 1826 ms。
(二)3DES 算法的结果分析
计算 10 次 3DES 加密的时间消耗平均值,可以得出,在本系统平台上,3DES 算法的平均时间消耗约为 2021 ms。
(三)AES 算法的结果分析
计算 10 次 AES 加密的时间消耗平均值,可以得出,在本系统平台上,AES 算法的平均时间消耗约为 1941 ms。
(四)PBE 算法的结果分析
计算 10 次 PBE 加密的时间消耗平均值,可以得出,在本系统平台上,PBE 算法的平均时间消耗约为 1376 ms。
(五)CBC 算法的结果分析
计算 10 次 CBC 加密的时间消耗平均值,可以得出,在本系统平台上,CBC 算法的平均时间消耗约为 1318 ms。
(六)IDEA 算法的结果分析
计算 10 次 IDEA 加密的时间消耗平均值,可以得出,在本系统平台上,IDEA 算法的平均时间消耗约为 2328 ms。
(七)RSA 算法的结果分析
计算 10 次 RSA 加密的时间消耗平均值,可以得出,在本系统平台上,RSA 算法的平均时间消耗约为 2288 ms。
(八)MD5 算法的结果分析
计算 10 次 MD5 哈希算法的时间消耗平均值,可以得出,在本系统平台上,MD5 算法的平均时间消耗约为 97 ms。
(九)SHA1 算法的结果分析
计算 10 次 SHA-1 哈希算法的时间消耗平均值,可以得出,在本系统平台上,SHA-1 算法的平均时间消耗约为 117 ms。
(十)SHA256 算法的结果分析
计算 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 是这三种中性能较好的一款哈希算法。
③遇到的问题及解决方法:
i)字符串编码出现乱码
一开始,我在编写加密函数时,由于对字节数组 byte[] 以及 String 对象之间的转化不当,导致了程序加密的输出结果呈现乱码,有许多问号 ??? 等特殊字符,这显然不符合加密结果的要求,如图所示:
之后,我尝试在调用 toString 方法时,将输出结果用参数 “utf-8” 强制转换,但效果不佳。在查阅了相关的资料后,我发现可以编写一个函数,将结果用 Base64 编码来表示:
public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}
这样一来,就可以将加密的编码方式转换为 Base64,此时的加密输出结果也更加易于表示、传输与解密。
ii)com.sun.crypto.provider.SunJCE() 报错
报错内容:
Access restriction: The constructor SunJCE() is not accessible due to restriction on required library C:\Program Files\Java\jre7\lib\ext\sunjce_provider.jar
查找相关文档的解释说明后,我发现该错误是由于对应的 jar 包版本较低所导致的,但可以选择忽视这个异常。
解决方法:
Window -> Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rules) -> Warnings
如图所示:
六、算法实现代码
① DES
package des;import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;import sun.misc.BASE64Encoder; public class des { //KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; //SecretKey 负责保存对称密钥 private SecretKey deskey; //Cipher负责完成加密或解密工作 private Cipher c; //该字节数组负责保存加密的结果 private byte [] cipherByte; public des() throws NoSuchAlgorithmException, NoSuchPaddingException{ Security.addProvider(new com.sun.crypto.provider.SunJCE()); //实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("DES"); //生成密钥 deskey = keygen.generateKey(); //生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("DES"); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte [] src = str.getBytes(); // 加密,结果保存在cipherByte中 cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Decryptor(byte [] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } public static String ByteToString(byte[] bytes) { StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i <bytes.length ; i++) { if (bytes[i]!=0){ strBuilder.append((char)bytes[i]); }else { break; } } return strBuilder.toString(); }/*** BASE64 加密** @param key 需要加密的字节数组* @return 字符串* @throws Exception*/public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { //获取开始时间的时间戳long startTime = System.currentTimeMillis(); des de1 = new des(); //源码文件是GBK格式,或者这个字符串是从GBK文件中读取出来的, 转换为string 变成unicode格式String msg1 = "In doing we learn."; //利用getBytes将unicode字符串转成UTF-8格式的字节数组byte[] utf8Bytes = msg1.getBytes("UTF-8"); //用utf-8 对这个字节数组解码成新的字符串String msg = new String(utf8Bytes, "UTF-8");byte [] encData = de1.Encrytor(msg); String encontent = null;encontent = encryptBase64(encData);byte [] decontent = de1.Decryptor(encData); System.out.println("----DES 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); //System.out.println("加密后:" + new String(encontent, "utf-8")); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + new String(decontent)); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("DES 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
② 3DES
package three_des;import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;import des.des;
import sun.misc.BASE64Encoder; public class three_des { // KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; // SecretKey 负责保存对称密钥 private SecretKey deskey; // Cipher负责完成加密或解密工作 private Cipher c; // 该字节数组负责保存加密的结果 private byte [] cipherByte; public three_des() throws NoSuchAlgorithmException, NoSuchPaddingException { Security.addProvider(new com.sun.crypto.provider.SunJCE()); // 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("DESede" ); // 生成密钥 deskey = keygen.generateKey(); // 生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("DESede" ); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte [] src = str.getBytes(); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Decryptor(byte [] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } public static String ByteToString(byte[] bytes) { StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i <bytes.length ; i++) { if (bytes[i]!=0){ strBuilder.append((char)bytes[i]); }else { break; } } return strBuilder.toString(); }public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { //获取开始时间的时间戳long startTime = System.currentTimeMillis(); three_des de1 = new three_des(); //源码文件是GBK格式,或者这个字符串是从GBK文件中读取出来的, 转换为string 变成unicode格式String msg1 = "In doing we learn."; //利用getBytes将unicode字符串转成UTF-8格式的字节数组byte[] utf8Bytes = msg1.getBytes("UTF-8"); //用utf-8 对这个字节数组解码成新的字符串String msg = new String(utf8Bytes, "UTF-8");byte [] encData = de1.Encrytor(msg); String encontent = null;encontent = encryptBase64(encData);byte [] decontent = de1.Decryptor(encData); System.out.println("----3DES 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); //System.out.println("加密后:" + new String(encontent, "utf-8")); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + new String(decontent)); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("3DES 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
③ AES
package aes;import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;import sun.misc.BASE64Encoder; public class aes { //KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; //SecretKey 负责保存对称密钥 private SecretKey deskey; //Cipher负责完成加密或解密工作 private Cipher c; //该字节数组负责保存加密的结果 private byte [] cipherByte; public aes() throws NoSuchAlgorithmException, NoSuchPaddingException{ Security.addProvider(new com.sun.crypto.provider.SunJCE()); //实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("AES"); //生成密钥 deskey = keygen.generateKey(); //生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("AES"); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte [] src = str.getBytes(); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte [] Decryptor(byte [] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } public static String ByteToString(byte[] bytes) { StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i <bytes.length ; i++) { if (bytes[i]!=0){ strBuilder.append((char)bytes[i]); }else { break; } } return strBuilder.toString(); }public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { //获取开始时间的时间戳long startTime = System.currentTimeMillis(); aes de1 = new aes(); //源码文件是 GBK 格式,或者这个字符串是从 GBK 文件中读取出来的, 转换为 string 变成 unicode 格式String msg1 = "In doing we learn."; //利用 getBytes 将 unicode 字符串转成 UTF-8 格式的字节数组byte[] utf8Bytes = msg1.getBytes("UTF-8"); //用 utf-8 对这个字节数组解码成新的字符串String msg = new String(utf8Bytes, "UTF-8");byte [] encData = de1.Encrytor(msg); byte [] decontent = de1.Decryptor(encData); String encontent = null;encontent = encryptBase64(encData);System.out.println("----AES 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); //System.out.println("加密后:" + new String(encontent, "utf-8")); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + new String(decontent)); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("AES 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
④ PBE
package pbe;import sun.misc.BASE64Encoder;import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;public class pbe {/*** 定义加密方式* 支持以下任意一种算法* PBEWithMD5AndDES* PBEWithMD5AndTripleDES* PBEWithSHA1AndDESede* PBEWithSHA1AndRC2_40*/private final static String KEY_PBE = "PBEWITHMD5andDES";private final static int SALT_COUNT = 100;/*** 初始化盐(salt)** @return*/public static byte[] init() {byte[] salt = new byte[8];Random random = new Random();random.nextBytes(salt);return salt;}/*** 转换密钥** @param key 字符串* @return*/public static Key stringToKey(String key) {SecretKey secretKey = null;try {PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray());SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_PBE);secretKey = factory.generateSecret(keySpec);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();}return secretKey;}/*** PBE 加密** @param data 需要加密的字节数组* @param key 密钥* @param salt 盐* @return*/public static byte[] encryptPBE(byte[] data, String key, byte[] salt) {byte[] bytes = null;try {// 获取密钥Key k = stringToKey(key);PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, SALT_COUNT);Cipher cipher = Cipher.getInstance(KEY_PBE);cipher.init(Cipher.ENCRYPT_MODE, k, parameterSpec);bytes = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidAlgorithmParameterException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}return bytes;}/*** PBE 解密** @param data 需要解密的字节数组* @param key 密钥* @param salt 盐* @return*/public static byte[] decryptPBE(byte[] data, String key, byte[] salt) {byte[] bytes = null;try {// 获取密钥Key k = stringToKey(key);PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, SALT_COUNT);Cipher cipher = Cipher.getInstance(KEY_PBE);cipher.init(Cipher.DECRYPT_MODE, k, parameterSpec);bytes = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidAlgorithmParameterException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}return bytes;}/*** BASE64 加密** @param key 需要加密的字节数组* @return 字符串* @throws Exception*/public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String[] args) {//获取开始时间的时间戳long startTime = System.currentTimeMillis(); // 加密前的原文String msg = "In doing we learn." ; // 口令String key = "qwert";// 初始化盐byte[] salt = init();// 采用PBE算法加密byte[] encData = encryptPBE(msg.getBytes(), key, salt);// 采用PBE算法解密byte[] decData = decryptPBE(encData, key, salt);String encontent = null;String decontent = null;try {encontent = encryptBase64(encData);decontent = new String(decData, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}System.out.println("----PBE 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + decontent); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("PBE 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑤ CBC
package cbc_aes;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;/**
* AES 是一种可逆加密算法,对用户的敏感信息加密处理
* 对原始数据进行AES加密后,进行Base64编码转化;
*/
public class cbc_aes {
/*
* 加密用的Key 用26个字母和数字组成
* 使用AES-128-CBC加密模式,key需要为16位。
*/private static String sKey="1234567800123656";private static String ivParameter="1236567890123456";private static cbc_aes instance=null;//private static private cbc_aes(){}public static cbc_aes getInstance(){if (instance==null)instance= new cbc_aes();return instance;}// 加密public String encrypt(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");byte[] raw = sKey.getBytes();SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());//使用CBC模式,需要一个向量iv,可增加加密算法的强度cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);byte[] encrypted = cipher.doFinal(sSrc.getBytes(encodingFormat));return new BASE64Encoder().encode(encrypted);//此处使用BASE64做转码。
}// 解密public String decrypt(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {try {byte[] raw = sKey.getBytes("ASCII");SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//先用base64解密byte[] original = cipher.doFinal(encrypted1);String originalString = new String(original,encodingFormat);return originalString;} catch (Exception ex) {return null;}
}public static void main(String[] args) throws Exception {//获取开始时间的时间戳long startTime = System.currentTimeMillis(); // 加密前的原文String msg = "In doing we learn.";// 加密String enString = cbc_aes.getInstance().encrypt(msg,"utf-8",sKey,ivParameter);// 解密String DeString = cbc_aes.getInstance().decrypt(enString,"utf-8",sKey,ivParameter);System.out.println("----CBC 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); System.out.println("加密的结果为: " + enString); System.out.println("解密的结果为: " + DeString); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("CBC 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑥ IDEA
package idea;import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Encoder;public class idea {public static final String ALGORITHM = "IDEA";public static final String CIPHER_ALGORITHM = "IDEA/ECB/ISO10126Padding";// 获取 IEDA Keypublic static byte[] getDesKey() throws NoSuchAlgorithmException, NoSuchPaddingException{try { // 1、创建密钥生成器KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);keyGenerator.init(128);// 2、产生密钥SecretKey secretKey = keyGenerator.generateKey();// 3、获取密钥byte[] key = secretKey.getEncoded();return key;} catch (Exception e) {throw new RuntimeException(e);}}// IDEA 解密public static byte[] encryptIdea(byte[] data, byte[] key) {try {SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);// 加工作模式和填充方式Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, keySpec);byte[] rsData = cipher.doFinal(data);return rsData;} catch (Exception e) {throw new RuntimeException(e);}}public static byte[] decryptIdea(byte[] data, byte[] key) {try {SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);// 加工作模式和填充方式Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, keySpec);byte[] rsData = cipher.doFinal(data);return rsData;} catch (Exception e) {throw new RuntimeException(e);}}public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String[] args) throws Exception {//获取开始时间的时间戳long startTime = System.currentTimeMillis();String msg = "In doing we learn.";byte[] data = msg.getBytes(Charset.forName("UTF-8"));byte[] key = getDesKey();String encontent = null;byte[] encData = encryptIdea(data, key);encontent = encryptBase64(encData);byte[] decData = decryptIdea(encData, key);System.out.println("----IDEA 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + new String(decData)); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("IDEA 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑦ RSA
package rsa;import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;import sun.misc.BASE64Encoder; public class rsa { /** * 加密 * @param publicKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte [] encrypt(RSAPublicKey publicKey, byte [] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if (publicKey != null ){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null ; } /** * 解密 * @param privateKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte [] decrypt(RSAPrivateKey privateKey, byte [] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if (privateKey != null ){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte [] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null ; } public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}/** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //获取开始时间的时间戳long startTime = System.currentTimeMillis(); rsa rsa = new rsa(); String msg = "In doing we learn."; //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器,密钥大小为1024位 keyPairGen.initialize(1024); //生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); //得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //得到公钥 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); //用公钥加密 byte [] srcBytes = msg.getBytes(); byte [] resultBytes = rsa.encrypt(publicKey, srcBytes); String encontent = null;encontent = encryptBase64(resultBytes);//用私钥解密 byte [] decBytes = rsa.decrypt(privateKey, resultBytes); System.out.println("----RSA 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + msg); System.out.printf("加密的结果为: " + encontent); System.out.println("解密的结果为: " + new String(decBytes, "utf-8")); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("RSA 加密的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑧ MD5
package md5;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import sun.misc.BASE64Encoder; public class md5 { public byte [] eccrypt(String info) throws NoSuchAlgorithmException{ //根据MD5算法生成MessageDigest对象 MessageDigest md5 = MessageDigest.getInstance("MD5"); byte [] srcBytes = info.getBytes(); //使用srcBytes更新摘要 sha.update(srcBytes); //完成哈希计算,得到result byte [] resultBytes = md5.digest(); return resultBytes; } public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String args[]) throws Exception{ //获取开始时间的时间戳long startTime = System.currentTimeMillis(); String msg = "In doing we learn." ; md5 md5 = new md5(); byte [] resultBytes = md5.eccrypt(msg); String encontent = null;encontent = encryptBase64(resultBytes);System.out.println("----MD5 哈希结果----"); System.out.println(); System.out.println("待 Hash 的明文: " + msg);System.out.printf("Hash 的结果为: " + encontent); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("MD5 哈希的时间消耗为:" + (endTime - startTime) + " ms");
⑨ SHA-1
package sha1;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import sun.misc.BASE64Encoder; public class sha1 { public byte [] eccrypt(String info) throws NoSuchAlgorithmException{ //根据SHA1算法生成MessageDigest对象 MessageDigest sha = MessageDigest.getInstance("SHA-1"); byte [] srcBytes = info.getBytes(); //使用srcBytes更新摘要 sha.update(srcBytes); //完成哈希计算,得到result byte [] resultBytes = sha.digest(); return resultBytes; } public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String args[]) throws Exception{ //获取开始时间的时间戳long startTime = System.currentTimeMillis(); String msg = "In doing we learn." ; sha1 sha = new sha1(); byte [] resultBytes = sha.eccrypt(msg); String encontent = null;encontent = encryptBase64(resultBytes);System.out.println("----SHA1 哈希结果----"); System.out.println(); System.out.println("待 Hash 的明文: " + msg);System.out.printf("Hash 的结果为: " + encontent); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("SHA1 哈希的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑩ SHA-256
package sha256;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder; public class sha256 { public byte [] eccrypt(String info) throws NoSuchAlgorithmException{ //根据SHA256算法生成MessageDigest对象 MessageDigest sha = MessageDigest.getInstance("SHA-256"); byte [] srcBytes = info.getBytes(); //使用srcBytes更新摘要 sha.update(srcBytes); //完成哈希计算,得到result byte [] resultBytes = sha.digest(); return resultBytes; } public static String encryptBase64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static void main(String args[]) throws Exception{ //获取开始时间的时间戳long startTime = System.currentTimeMillis(); String msg = "In doing we learn." ; sha256 sha = new sha256(); byte [] resultBytes = sha.eccrypt(msg); String encontent = null;encontent = encryptBase64(resultBytes);System.out.println("----SHA256 哈希结果----"); System.out.println(); System.out.println("待 Hash 的明文: " + msg);System.out.printf("Hash 的结果为: " + encontent); //获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println("SHA256 哈希的时间消耗为:" + (endTime - startTime) + " ms"); }
}
⑪ Caesar
package caesar;/*** 一般化的凯撒加密算法为: C = E(k, p) = (p + k) mod 26* 一般化的凯撒解密算法为: p = D(k, C) = (C - k) mod 26 */ public class caesar { /*** 对单个字母进行加密* @param ch 字母* @param n 密钥* @return 加密后的字母*/public static char encrypt(char ch,int n){int unicode;int c=ch-'a';if(c+n>'z') unicode=c+n-26;else unicode=c+n;return (char)(unicode%26+'a');}/*** 对明文进行加密* @param str 明文字符串* @param n 密钥* @return 对明文加密后的密文*/public static String encrypt(String str,int n){char[] ch=str.toCharArray();StringBuilder sb=new StringBuilder();for(char c: ch){sb.append(encrypt(c,n));}return sb.toString();} /*** 将加密后的字母解密* @param ch 加密后的字母* @param n 密钥* @return 解密后的字母*/public static char decrypt(char ch,int n){int unicode;int c=ch-'a';if(c-n<'a') unicode=c-n+26;else unicode=c-n;return (char)(unicode%26+'a');}/*** 将密文解密* @param str 密文* @param n 密钥* @return 解密后的明文*/public static String decrypt(String str,int n){char[] ch=str.toCharArray();StringBuilder sb=new StringBuilder();for(char c: ch){sb.append(decrypt(c,n));}return sb.toString();}public static void main(String args[]){//获取开始时间的时间戳long startTime = System.currentTimeMillis();String str="in doing we learn";String[] words=str.toLowerCase().split(" ");String result = "";for(String word: words){result = result + encrypt(word, 21) + " ";}System.out.println("----Caesar 加密结果----"); System.out.println(); System.out.println("待加密的明文: " + str); System.out.print("加密的结果为: "); System.out.print(result);System.out.println();String[] ws=result.split(" ");System.out.print("解密的结果为: ");for(String w: ws){System.out.print(decrypt(w, 21)+" ");}//获取结束时间的时间戳 long endTime = System.currentTimeMillis(); //输出程序运行时间System.out.println();System.out.println("Caesar 加密的时间消耗为:" + (endTime - startTime) + " ms"); }}
11 种加密 哈希算法的原理及其 Java 实现相关推荐
- 哪种一致性哈希算法才是解决分布式缓存问题的王者?
哪种一致性哈希算法才是解决分布式缓存问题的王者? 一致性哈希是由Karger等人于1997年提出的一种特殊的哈希算法,目的是解决分布式缓存的问题,现在在分布式系统中有着广泛的应用.本文将对ketama ...
- 哈希算法的原理和用途详解
什么是哈希算法?哈希是一种加密算法,也称为散列函数或杂凑函数.哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值.散列值(Hash Value ...
- 一致性哈希算法 mysql_一致性哈希算法 CARP 原理解析, 附 Golang 实现
一致性哈希算法 CARP 原理解析, 附 Golang 实现 在后端服务开发的过程中, 遇到了这样一个问题: 需要在 mysql 前面部署 redis 做一层缓存, 要求 redis 是集群部署, 并 ...
- 【数据结构与算法】哈希算法的原理和应用详解!
在程序员的实际开发中,哈希算法常常能用得到,本文以哈希算法的原理和应用为核心,和大家详细讲解一下哈希算法的概念.常见算法以及原理.在信息安全的应用等等. 一.概念 哈希表就是一种以 键-值(key-i ...
- 「数据结构与算法」哈希算法的原理和应用详解
在程序员的实际开发中,哈希算法常常能用得到,本文以哈希算法的原理和应用为核心,和大家详细讲解一下哈希算法的概念.常见算法以及原理.在信息安全的应用等等. 一.概念 哈希表就是一种以 键-值(key-i ...
- 13种加密与解密算法【一】
这15种加密解密算法分别是:散列哈希[MD5.SHA1.CRC32],对称[DES,3DES(TDEA.Triple DES),AES.,Blowfish,RC4.RC5,IDEA],Base64.R ...
- VBA和VBScript的SHA2加密哈希算法
介绍 安全哈希算法2是由美国国家安全局(NSA)设计并由美国国家标准技术研究院(NIST)作为政府标准发布的一系列密码哈希算法. NIST目前正在进行一项竞赛,目的是为SHA-3寻找新的算法系列. 这 ...
- python用tsne降维_哈工大硕士实现了 11 种经典数据降维算法,源代码库已开放
网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA.LDA.MDS.LLE. ...
- std中稳定排序算法_源代码库已开放 | 哈工大硕士生用 Python 实现了 11 种经典数据降维算法...
转自:AI开发者 网上关于各种降维算法的资料参差不齐,同时大部分不提供源代码.这里有个 GitHub 项目整理了使用 Python 实现了 11 种经典的数据抽取(数据降维)算法,包括:PCA.LDA ...
最新文章
- 丑数 Humble Numbers
- LeetCode 767. 重构字符串(堆)
- Try Redis : Redis 入门教程
- 设计模式1【续】:动态设定行为
- Tensor is not an element of this graph 解决方法
- 利用xposed自动获得微信个人收款二维码链接和收款记录
- 飞算(SoFlu)软件机器人——人人都是全栈架构师
- java pdf查看_Java检查PDF文件是否损坏
- iPhone5/5c 越狱破解联通4g
- 编程实践精华总结集锦系列1: SpringBoot/Maven/IDEA/Java/Kotlin/Redis等等
- Linux——clamAV查杀病毒与防护
- 【如何7天写完一篇发明专利】
- Windows中使用Java执行shell命令运行检测,通过sonarqube的webapi获取扫描结果
- IDEA插件系列(20):Grep Console插件——显示多颜色调试日志
- LC振荡电路 频域计算
- 软件方法(下)第8章分析之分析类图—知识篇Part09-审查类和属性1
- 计算机行业的发展及未来前景论文,【计算机应用论文】计算机应用发展现状及发展趋势(共2737字)...
- 富士通代理Quad SPI铁电FRAM存储器MB85RQ4M
- Linux系统下搭建Zabbix(agentd篇)
- 【nexus5刷机教程】
热门文章
- [jQuery知识]jQuery之知识十一-Ajax初级
- 键盘中按键对应的键码值
- git可视化版本控制工具SourceTree的基本使用
- matlab出现索引超出数组元素的数目(0)怎么解决
- 尚筹网 —— 4、[知识] RBAC 权限控制模型 和 Ajax请求
- 开源中文医疗大模型华佗GPT来了,真人医生盲测效果优于ChatGPT
- 21.项目部署-usgi
- 计算机科学数学理论浅谈
- 携载PEG-PLA纳米粒子/F3O4磁性纳米粒子/银纳米团簇基/纳米二氧化钛改性壳聚糖水凝胶
- 基于NB-IoT的智慧路灯监控系统(NB-IoT专栏—实战篇2:硬件开发)