11 种加密 & 哈希算法的原理及其 Java 实现

2023-11-12

11 种加密 & 哈希算法的原理及其 Java 实现

一、目的

(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):

算法介绍
  1. 属于对称加密算法;
  2. 数据分组(64 位)用密钥(64 位;其中 56 位有效位,8 位校验位)加密;
  3. 算法公开,对密钥保护。
算法流程
  1. 根据用户输入,取得一个 64 位的密钥,然后进行等分、移位、选取和迭代形成一套 16 个加密密钥,分别提供每轮运算使用;
  2. 对 64 位明文分组 M M M 进行操作, M M M 经过初期置换 I P IP IP,置换为 m 0 {m_{0}} m0,将 m 0 {m_{0}} m0 分为左右各 32 位长,并进行 16 轮相同的运算(迭代),每轮运算都和相应的密钥结合;
  3. 在每一轮中,密码位移位,从密钥的 56 位中选出 48 位,通过一个扩展置换将数据右半边扩展成 48 位,并通过异或操作替代成新的 48 位;然后压缩至 32 位,并通过一个异或与左半边结合,其结果为右半边,原来的右半边成为左半边,该操作执行 16 次;
  4. 经过 16 轮迭代,左右部分合在一起进行一个末置换(数据整理),完成加密过程;
  5. 解密时同样使用此算法。
优点

  算法公开、计算量小、加密速度快、效率高。

缺点
  1. 如果双方都持有密钥,安全性无法保证;
  2. 密钥安全的保护成本高,管理困难。
破解方式

  暴力破解、穷举。

适用场景

  普通数据加密。

安全性

  低。

② 3DES(DES ede)(或称为Triple DES)——是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)的通称 :

算法介绍
  1. 三重 DES 加密算法;
  2. 每个数据块用三次 DES 加密;
  3. 是 DES 向 AES 过渡的加密算法。
算法流程
  1. 加密过程: C = E k 3 ( D k 2 ( E k 1 ( P ) ) ) {\rm{C = }}{{\rm{E}}_{{k_3}}}{\rm{(}}{{\rm{D}}_{{k_2}}}{\rm{(}}{{\rm{E}}_{{k_1}}}{\rm{(P)))}} C=Ek3(Dk2(Ek1(P)))
  2. 解密过程: P = D k 1 ( E k 2 ( D k 3 ( 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):

算法介绍
  1. 属于对称加密算法;
  2. 基于排列置换算法;
  3. 易于软硬件实现;
  4. 属于分组密码体制;
  5. 用于取代原来的 DES。
算法流程
  1. 对数据进行 128 位(16 字节)的分组加密,每次对一组数据加密需要多轮;
  2. 输入密钥长度为:128、192 或 256,如果不够则补齐;
  3. 加密基本流程:
    1)生成各轮的扩展密钥,存于 key 数组中,包含用户的输入密钥和扩展密钥;
    2)将待加密数组与第一组密钥异或;
    3)最后一轮前的变换操作:
      SubBytes(state)——对数据进行 S 字节变换;
      ShiftRows(state)——进行行变换;
      MixColumns( state )——进行列混合变换;
      AddRoundKey( state,Keys [当前轮密钥组] )——与当前轮密钥异或。
    4)最后一轮变换操作
      invShiftRows(state)——进行反行变换;
      invSubBytes(state)——对数据进行反 S 字节变换;
      AddRoundKey( state, Keys [第一组] )——与第一组密钥进行异或。
  4. 解密流程:与加密相反。
  5. 分组模式:
    1)ECB(电码本模式):
      优点:简单、并行计算、误差不会传递;
      缺点:不能隐藏明文的模式、可能造成对明文的主动攻击。
    2)CBC(密码分组链接):
      优点:能抵抗主动攻击、安全性好于 ECB、适合传输较长报文、是 SSL,IPSec 的标准;
      缺点:不利于并行计算、有误差传递、需要初始化向量;
    3)CFB(密码反馈模式):
      优点:隐藏明文的模式、将分组密码转化为流模式、可以及时加密传送分组的数据;
      缺点:不利于并行计算、有误差传递、 I V IV IV值唯一。
    4)OFB(输出反馈模式):
      优点:隐藏明文、将分组密码转化流模式、可以及时加密传送分组的数据;
      缺点:不利于并行计算、可能对明文产生主动攻击、误差传递。
    5)CTR(计数器模式):
      优点:并行计算、仅要求实现加密算法而无需解密算法、无需填充、可以作为流进行高效加密。
  6. 常用填充方式:
    NoPadding——不填充;
    ZerosPadding——0 填充;
    PKCS5Padding——每个填充都记录了填充的总数。
优点

  分组模式选择多,加密安全。

缺点
  1. 同 DES 类似,存在密钥管理问题;
  2. 曾遭受线性密码攻击、差分密码攻击。
安全性

  较高。

④ PBE(Password Based Encryption,基于口令加密):

算法原理

  PBE(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数、杂凑、多重加密等方法保证数据的安全性。

  PBE 算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由 PBE 算法中的 KDF 函数完成。
在这里插入图片描述

算法流程

  KDF 函数的实现过程为:

  1. 将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥;
  2. 将准密钥经过散列函数,多次迭代后,生成最终的加密密钥;
  3. 密钥生成后,PBE 算法再使用对称加密算法对数据进行加密,可以选择 DES、3DES、RC5 等对称加密算法。

⑤ IDEA(国际数据加密算法):

算法介绍

  国际数据加密算法(IDEA)是上海交通大学教授来学嘉与瑞士学者 James Massey 联合提出的,它在 1990 年正式公布并得到增强。这种算法是在 DES 算法的基础上发展出来的,类似于三重 DES。发展 IDEA 也是因为 DES 密钥太短等缺点,IDEA 的密钥为 128 位,在今后若干年内应该是安全的。

算法特点

  类似于 DES,IDEA 算法也是一种分组加密算法,它设计了一系列加密轮次,每轮加密都使用从完整的加密密钥中生成的一个子密钥。与 DES 的不同之处在于,它在软件和硬件实现上同样快速。
  
  由于 IDEA 是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限制,因此,有关 IDEA 算法和实现技术的书籍都可以自由出版和交流,极大地促进了 IDEA 的发展和完善。

应用领域

  目前 IDEA 在工程中已有大量应用实例:

  1. PGP ( Pretty Good Privacy)使用 IDEA 作为其分组加密算法;
  2. 安全套接字层 SSL(Secure Socket Layer)将 IDEA 包含在其加密算法库 SSLRef 中;
  3. 基于 IDEA 的 Exchange 安全插件;
  4. IDEA 加密芯片;
  5. IDEA 加密软件包等。

⑥ RSA:

算法介绍
  1. 非对称加密;
  2. 密钥长度决定了其复杂度;
  3. 简单原理:公钥加密、私钥解密;
         私钥签名、公钥解密验证。
算法流程
  1. 随意选择两个大的质数 p p p q q q p p p 不等于 q q q,计算 N = p × q N = p × q N=p×q
  2. 根据欧拉函数,求得 r = ( p − 1 ) ( q − 1 ) r = (p - 1)(q - 1) r=(p1)(q1)
  3. 选择一个小于 r r r 的整数 e e e,求得 e e e 关于模 r r r 的模反元素,命名为 d d d(模反元素存在,当且仅当 e e e r r r 互质);
  4. p p p q q q 的记录销毁;
  5. ( N , e ) (N,e) (N,e) 是公钥, ( N , d ) (N,d) (N,d) 是私钥。
优点

  原理简单。

缺点
  1. 密钥生成较为麻烦,受到素数产生技术的限制,因此难以做到一次一密;
  2. 分组长度太大,不利于数据格式标准化;
  3. 加密难度大。
应用场景
  1. 数字签名;
  2. 公钥加密;
  3. 防止数据篡改;
  4. 用于通讯领域较多。
安全性

  高。

⑦ 凯撒密码:

算法介绍

  作为一种最为古老的对称加密体制,凯撒密码在古罗马的时候就已经很流行了。它的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果字母的位数是 3,明文字母 B 就变成了密文的 E,依次类推,X 将变成 A,Y 变成 B,Z 变成 C……由此可见,位数就是凯撒密码加密和解密的密钥。

算法流程

  一般化的凯撒加密算法为: C = E ( k , P ) = ( P + k ) m o d 26 C = E(k, P) = (P + k) mod 26 C=E(k,P)=(P+k)mod26

  一般化的凯撒解密算法为: P = D ( k , C ) = ( C − k ) m o d 26 P = D(k, C) = (C - k) mod 26 P=D(k,C)=(Ck)mod26

  1. 由于字母表中共有 26 个字符,因此移位前先将移动的位数 ( k e y key key) 和 26 取模。将字符加上一个正整数即代表在字母表中右移多少位;
  2. 如果移动的位数是负值,则代表在字母表中左移多少位。尽管在移动之前已经将移动的位数和 26 取模,但通过这种方式实现右移或左移仍可能发生超界;
  3. 移位后进行判断,如果向左超界(c <‘a’)则增加 26;向右超界(c >‘z’)则减去 26。

(II)各种 Hash 算法的原理:

① MD5:

算法介绍
  1. 信息摘要算法;
  2. 压缩性:任意长度的数据,可以算出固定长度;
  3. 容易计算:从原数据计算 MD5 很容易;
  4. 抗修改性:对原数据修改 1 个字节,MD5 值的变化都很大;
  5. 强碰撞性:找一个具有相同 MD5 值的数据(伪造)比较困难;
  6. 具有不可逆性。
算法流程

  按照 512 位分组处理,每一个分组分为 16 个 32 位子分组,处理后输出 4 个 32 位分组,将这 4 个分组级联后生成 128 位散列值。

优点

  简单、难以伪造。

缺点

  具有潜在的冲突;有破解的案例。

应用场景
  1. 登录密码保护;
  2. 防止文件篡改;
  3. HTTP 传输内容加密防篡改;
  4. 用于数字签名。
安全性

  较高。

② SHA1:

算法介绍
  1. 属于消息摘要算法;
  2. 用于签名算法,保护数据的完整性;
  3. 算法不可逆;
  4. 消息算法:512 位。
算法流程

  把原始信息变换成位(二进制)字符串,5 个步骤计算:
  1)补位:消息满足长度在对 512 取模后余数是 448,否则补位;
  2)补长度:原始数据长度补到补位操作的后面,如果大于 512,补成 512 的倍数;
  3)使用常量和相关的函数;
  4)计算消息摘要。

优点

  保密性强。

缺点

  效率较低;难度大。

应用场景
  1. 数字签名;
  2. 数据完整性保护。
安全性

  高。

(III)javax.crypto.Cipher 类的原理

  基于 Java 中的 javax.crypto.Cipher 类,可以实现各种算法的加密和解密功能,该类是 JCE 框架的核心。

  1. 与所有的引擎类一样,可以通过调用 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 实例后将它初始化是等价的。

  1. 调用 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)
  1. SunJCE 提供者实现的 Cipher 算法参数:

  (1)采用 CBC、CFB、OFB、PCBC 模式的 DES、DES-EDE 和 Blowfish算法使用初始化向量 I V IV IV 作为参数。可以使用 javax.crypto.spec.IvParameterSpec 类并使用给定的 I V IV IV 参数来初始化 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

②总结

  1. 对称算法:
      密钥管理:比较难,不适合互联网,一般用于内部系统;
      安全性:中;
      速度:快好几个数量级(软件加解密速度至少快 100 倍,每秒可以加解密几兆比特的数据),适合大数据量的加解密处理。

  2. 非对称算法:
      密钥管理:密钥容易管理;
      安全性:高;
      速度:慢,适合小数据量加解密或数据签名。

  3. 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 Key
    public 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");    
        }
    }    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

11 种加密 & 哈希算法的原理及其 Java 实现 的相关文章

  • 密码学与网络安全笔记整理-数据完整性技术

    1 数据完整性 类似于通信中的校验码功能 在密码学领域数据完整性用于验证收到信息的正确性 校验收到的信息是否经过篡改 校验收到的信息是真实的发送者发送而非伪造 发送者通过编码为消息增加一些 冗余 生成一个校验值 并将该校验值附在消息之后 接
  • 密码学原语如何应用?解析密码学特有的数据编解码|第10论

    隐私保护方案的工程实现 如何关联到学术论文中天书一般的公式符号 密码学工程中 有哪些特有的数据编解码方式 存在哪些认知误区和注意事项 需要克服哪些限制和挑战 作为支撑隐私保护方案的核心技术 如何运用数据编解码 将密码学论文中抽象的数学符号和
  • 信息安全密码学:DES算法的核心 E盒、S盒、P盒

    加密密钥等于脱密密钥 或者由一个可以轻易的计算出另一个的密码体制 称为单密钥密码体制 亦或称为对称密码体制或传统密码体制 其最具代表意义的当然属于DES密码体制了 1 DES的设计背景 1973年5月 NBS 美国国家标准局 发布通告 征集
  • 斯坦福密码学课程-笔记-02-Stream Ciphers流密码

    斯坦福密码学课程笔记 02 流密码 Stream Ciphers The One Time Pad Symmetric Ciphers definition The One Time Pad Vernam 1917 Information
  • 密码学——1.密码学概论

    1 基本术语 1 1 密码使用学 ceyptography vs 密码编码学 crypyology 密码使用学是一种为了达到隐藏消息含义而使用秘文写的一门科学 密码分析学是一门研究在不知道通常解密所需要的秘密信息的情况下对加密的信息进行解
  • 【现代密码学原理】——密钥管理和其他公钥密码体制(学习笔记)

    前言 本章首先介绍最早 最简单的PKCS Diffe Hellman密钥交换 然后介绍另一个重要方案 EIGamal PKCS 目录 0 思维导图 1 Diffie Hellman密钥交换 1 1 本原根 primitive root 1
  • 网络安全与密码学

    1 网络安全威胁 破坏网络安全的一些理论方式 窃听 窃听信息 在网路通信双方直接进行窃听 插入 主动在网络连接中插入信息 可以在message中插入恶意信息 假冒 伪造 spoof 分组中的源地址 假冒客户端或服务器 劫持 通过移除 取代发
  • openssl hmac源码分析

    hmac 原理 HMAC 用于保护消息的完整性 它采用摘要算法对消息 填充以及秘密密钥进行混合 运算 在消息传输时 用户不仅传送消息本身 还传送 HMAC 值 接收方接收数据后也进 行 HMAC 运算 再比对 MAC 值是否一致 由于秘密密
  • AES加密算法详解(图文解释)

    由于DES加密算法被破解了 3DES加密算法虽然没有被破解 但是3DES算法的加解密效率低 所有现在都使用AES算法 AES加密算法是密码学中的高级加密标准 AES为分组加密法 把明文分成一组一组的 每组长度相等 每次加密一组数据 直到加密
  • BUUCTF Crypto(密码学)刷题

    MD5 拿到一串字符串e00cf25ad42683b3df678c61f42c6bda 根据题目可到在线MD5在线解密 拿到flag Url编码 根据提示可知是url编码 url编码在线解密 一眼就解密 的确 一眼就解密了 非常明显的bes
  • Windows 下PBC库的安装和配置

    背景 PBC库是一个基于双线性对的密码学库 这库在公钥密码学中使用非常广泛 这个库在Linux下的安装非常的简单 有些只会纸上谈兵的人需要在WIN下做 呵呵 但是没办法 需求到了 硬着头皮也要写完 对于一些只会谈兵的人 呵呵 现在主要介绍下
  • 密码学-hash加密

    以下代码分别为乘法hash sha256 md5 ripemd160的使用方法 package main import fmt crypto sha256 os io crypto md5 encoding hex golang org x
  • 密码学原语如何应用?解析单向哈希的妙用|第9论

    作者 廖飞强 来源 微众银行区块链 隐私数据如何验明真伪 区块链数据何以可信 如何快速检验海量数据是否被篡改 单向哈希在其中起到了什么作用 隐私数据的价值很大程度上源自其真实性 如何防止数据被恶意篡改 是隐私保护方案设计中不可忽视的关键目标
  • 27、HMAC

    HMAC产生背景 HMAC为什么会被提出来 是MAC的产生有什么缺陷么 HMAC规范的设计是由于存在对将密钥与hash函数相结合的更简单机制的攻击 换言之就是有些将密钥和hash函数结合使用产生MAC的算法容易被攻击 而这种生成消息认证码的
  • 密码学研究重点

    密码学涵盖了认证 数字签名以及更多基本的安全功能 密码学涉及领域及其宽广 包括计算机安全 高等数学 经济学 量子物理学 民法和刑法 统计学 芯片设计 软件优化 政治 用户界面设计等 0x01 密码学重要性 密码学本身没有价值 必须作为一个系
  • [Cryptography]1.对称密钥和非对称密钥 2.计算modulo inverse 3.计算possible key

    对称密钥和非对称密钥 对称密钥顾名思义就是两个end users使用同一个key Secret Key来进行加密解密 最大的问题就是如何安全的传输SK给另一方 非对称密钥就是说每个人都拥有一个public key和一个private key
  • 【密码学】古代、古典密码

    古代密码 数据的保密基于加密算法的保密 Scytale密码 使用一条纸袋作为载体 环绕在一根固定半径的圆柱上 加密 在绕好的纸带上写上明文 解开缠绕后 就是加密好的 无序的密文 圆柱的半径就是密钥 解密 找到相同大小的圆柱 将纸带缠绕在援助
  • 【区块链与密码学】第6-7讲:SM9数字签名算法

    本课堂内容全部选编自PlatON首席密码学家 武汉大学国家网络安全学院教授 博士生导师何德彪教授的 区块链与密码学 授课讲义 教材及互联网 版权归属其原作者所有 如有侵权请立即与我们联系 我们将及时处理 6 7 SM9数字签名算法 为了降低
  • 密码学原语如何应用?解析密文同态性的妙用

    隐私数据在密文形式下是否依旧可以加减乘除 其背后的同态性原理具体指什么 半同态性和全同态性有什么区别 单密钥和多密钥同态加密有哪些奇妙的应用场景 隐私保护方案设计 往往需要在密文状态下 对隐私数据进行特定的业务操作 以此保障数据的机密性 沿
  • 密码学替代密码

    1 请指出一般替代密码的明文空间 密文空间和密钥空间各是什么 明文空间M和密文空间C都是26个英文字母的集合 密钥空间K Z 26 gt Z 26 是置换 是所有可能置换的集合 2 单表替代密码和多表替代密码的主要特点是什么 单表替代密码

随机推荐

  • 好用到爆,GitHub 星标 32.5k+的命令行软件管理神器,功能真强大

    前言 废话 本来打算在公司偷偷摸摸给星球的用户写一篇编程喵整合 MongoDB 的文章 结果在通过 brew 安装 MongoDB 的时候竟然报错了 原因很简单 公司这台 Mac 上的 homebrew 环境没有配置好 刚好 Java 程序
  • 计算机的”性能“

    前言 性能这个词在很多领域都出现过 比如一个跑车的性能 一个家电的性能 一个电脑的性能 其实在我看来一个东西的性能 就是他在某一方法的能力 比如跑车最重要的就是速度 一个计算机则是他的运行速度 在计算机组成原理中理解计算机怎么运行 为什么要
  • selenium启动Chrome配置参数问题

    每次当selenium启动chrome浏览器的时候 chrome浏览器很干净 没有插件 没有收藏 没有历史记录 这是因为selenium在启动chrome时为了保证最快的运行效率 启动了一个裸浏览器 这就是为什么需要配置参数的原因 但是有些
  • JavaFX 滚动条

    使用ScrollBar可以创建滚动条 创建滚动条 使用如下的构造函数可以创建滚动条 ScrollBar scrollbar new ScorllBar 查看API帮助文档 我们可以看到几个常用的设置属性的方法 这里简单介绍几个比较常用的方法
  • 大数据(hadoop分布式搭建--尚硅谷)手把手教学

    二 Hadoop 运行环境搭建 1 创建虚拟机 创建名称为hadoop100 在这里插入图片描述 https img blog csdnimg cn e89556e0b9b54d9fa3f25dea18873db2 png 2 配置三处网络
  • chart模板文件简单语法使用

    参考网址 https docs helm sh chart template guide the chart template developer s guide helm 模板 helm模板语法嵌套在 和 之间 有三个常见的 Values
  • 通过反编译定制android ROM

    以下操作是基于接近原生Android 4 4的系统下进行 是白牌设备 1 copy system 整个目录的 apk copy 到本地 2 对里面的 apk 重新进行签名 3 放回设备里面 重新启动 如果运行正常 那么现在就拥有设备的系统签
  • 上海链节科技的介绍

    上海链节科技有限公司 诞生于产业加速重塑 数字化金融格局加速转型的浪潮中 立足于区块链 数字经济为实体经济赋能 为社会进步和经济发展提供高效率 低成本的数字化转型解决方案 通过与实体企业 人民大众的生产 生活消费产生直接 正向的链接 从真正
  • JavaFX 程序退出时结束子线程

    1 前言 在JavaFX的程序开发中 在调用子线程之后子线程还未结束时 我们点击应用程序右上角的关闭按钮的时候 我们会发现程序还没有真正的结束运行 这是因为我们的子线程没有在JavaFX的管理之下 2 如何关闭 在主方法中找到Stage类
  • 机器学习数据集_机器学习数据集的选择

    机器学习数据集 Before you is an article guide to open data sets for machine learning In it I for a start will collect a selecti
  • 会话列表

    java实现 题目描述 小云正在参与开发一个即时聊天工具 他负责其中的会话列表部分 会话列表为显示为一个从上到下的多行控件 其中每一行表示一个会话 每一个会话都可以以一个唯一正整数id表示 当用户在一个会话中发送或接收信息时 如果该会话已经
  • Wifi模块—源码分析Wifi热点扫描2(Android P)

    一 前言 这次接着讲Wifi工程流程中的Wifi热点扫描过程部分的获取扫描结果的过程 也是Wifi扫描过程的延续 可以先看前面Wifi扫描的分析过程 Wifi模块 源码分析Wifi热点扫描 Android P 二 图示调用流程 这次的调用流
  • 【华为OD机试真题2023B卷 JS】勾股数元组

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 勾股数元组 知识点编程基础 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 如果3个正整数 a b c 满足a2 b2 c2的关系 则称 a b c 为勾股数 著名的勾
  • 【华为OD】最多几个直角三角形_全组合求解

    目录 一 题目描述 二 输入描述 三 输出描述 3 1 描述 四 题目解析 五 Java玩法 六 JavaScript玩法 一 题目描述 有 N 条线段 长度分别为 a 1 a n 现要求你计算这 N 条线段最多可以组合成几个直角三角形 每
  • Java中内部类详解(类的五成员之五:内部类)

    目录 友情提醒 概述 Java类的五成员之五 内部类 一 内部类 1 成员内部类 2 方法内部类 3 匿名内部类 4 静态内部类 二 匿名内部类与Lambda表达式 友情提醒 先看文章目录 大致了解知识点结构 直接点击文章目录可以跳转到文章
  • Git 如何优雅地回退代码

    前言 从接触编程就开始使用 Git 进行代码管理 先是自己玩 Github 又在工作中使用 Gitlab 虽然使用时间挺长 可是也只进行一些常用操作 如推拉代码 提交 合并等 更复杂的操作没有使用过 看过的教程也逐渐淡忘了 有些对不起 Li
  • 测试开发工程师的简历和面试准备

    文章目录 职业规划 核心事项 不必等待准备 完美 才投简历 准备简历 确定一批目标公司和目标职位 详细事项 可以慢慢完备 时间有限 注意结合所需 简历 简历命名 邮件标题同理 携带个人信息 优先使用pdf格式的简历 最好打印大小是A4 简历
  • WINAPI WinMain

    include
  • 为什么每个程序执行都有内核地址空间和程序地址空间?

    为什么每个用户态的程序映射到虚拟地址空间 都需要有内核地址空间和程序地址空间呢 因为程序地址空间最终都会调用系统调用 也就是内核的东东 所以每个程序要想执行 就必须有内核地址空间 也必须有程序地址空间 所用的application程序要想使
  • 11 种加密 & 哈希算法的原理及其 Java 实现

    11 种加密 哈希算法的原理及其 Java 实现 一 目的 二 运行环境 三 基本原理及步骤 I 各种加密算法的原理 DES 数据加密标准 Data Encryption Standard 算法介绍 算法流程 优点 缺点 破解方式 适用场景