(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 ) 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)=(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算法使用初始化向量 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.” 对其进行加密,具体结果分析如下:
计算 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:
计算 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 Files\Java\jre7\lib\ext\sunjce_provider.jar
查找相关文档的解释说明后,我发现该错误是由于对应的 jar 包版本较低所导致的,但可以选择忽视这个异常。
解决方法:
Window -> Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rules) -> Warnings
如图所示:
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
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
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
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");
}
}
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");
}
}
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");
}
}
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");
}
}
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");
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");
}
}
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");
}
}
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");
}
}