一、了解BlowFish算法
BlowFish是一种对64位(8字节)数据块进行操作的对称分组密码(symmetric block cipher)算法。该算法可以用来替代DES (Data Encryption Standard) 或 IDEA (International Data Encryption Algorithm) 算法。它采用从32位到448位的可变长度密钥。作为已有加密算法的快速、免费替代方案,Bruce Schneier在1993年设计了Blowfish算法。Blowfish是无专利和无许可证的,可免费用于所有用途。
提示:Blowfish算法每次加密的块比较小,只有64bits,因为加密块小会导致生日攻击等。Twofish是Blowfish的继任者。
通过对Blowfish算法的学习,有助于我们了解如何使用Java去实现一个加密算法,有助于我们解决现有项目的安全问题(也许项目中还再使用)。
二、实现思路
1.研究Cipher类
javax.crypto.Cipher类提供了密码的加解密功能。它构成了Java加密扩展 (JCE) 框架的核心。
首先,通过调用Cipher类的getInstance方法来构造一个Cipher对象
public static final Cipher getInstance(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException
public static final Cipher getInstance(String transformation,String provider) throws NoSuchAlgorithmException,NoSuchProviderException,NoSuchPaddingException
public static final Cipher getInstance(String transformation,Provider provider) throws NoSuchAlgorithmException,NoSuchPaddingException
参数transformation:String类型,描述要对给定输入执行的操作(或一组操作),以产生一些输出。由3个部分组成:
algorithm:算法组件,如AES、DES、Blowfish、RC4、RSA等
mode:模式组件,如ECB、CBC、GCM、CCM、NONE等
padding:填充组件,如NoPadding、PKCS5Padding、ISO10126Padding等
参数provider:String类型 或 Provider类,表示Java安全API的“提供者”。可以通过Security.getProviders()查询当前已注册的Providers列表。
Provider[] providers = Security.getProviders();
for (Provider provider: providers){
System.out.println(provider.getName() + "||" + provider.getInfo() + "||" + provider.getVersion());
}
那这些provider是如何注册的呢?
通过源码分析,我们发现它们是通过java.security文件配置的。
sun.security.jca.ProviderList
$JAVA_HOME\jre\lib\security\java.security
com.sun.crypto.provider.SunJCE
Provider name: SunJCE
支持Blowfish算法以及该算法支持的模式、填充方案等;
支持生成Blowfish使用的密钥;
2.创建Cipher对象
采用下面的方法来构造Cipher对象,使用的是CBC模式以及PKCS5PADDING
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5PADDING", "SunJCE"); 或
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5PADDING");
注意:如果不指定mode和padding,则默认使用 ECB mode和 PKCS5Padding。
初始化cipher对象
Cipher类重载init方法
CBC模式需要使用初始化向量。使用下面的方法来初始化cipher对象。
public final void init(int opmode, Key key, AlgorithmParameters params) throws InvalidKeyException,InvalidAlgorithmParameterException
opmode: 操作模式,加密或解密; Cipher.ENCRYPT_MODE、Cipher.DECRYPT_MODE
key: 密钥; 需要生成一个Key对象
params:算法参数集合
除了指定opmode,还需要构造Key对象和AlgorithmParameterSpec对象。
3.创建Key对象
这里需要使用另外一个类:SecretKeySpec
使用SecretKeySpec构造器来构造对象,传入的参数为key字节数组、算法名。
public SecretKeySpec(byte[] key, String algorithm);
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "Blowfish");
** 使用KeyGenerator来生成key字节数组**,指定算法为Blowfish:
KeyGenerator kGen = KeyGenerator.getInstance("Blowfish");
SecretKey sKey = kGen.generateKey();
byte[] keyRaw = sKey.getEncoded();
4.创建AlgorithmParameterSpec对象
CBC模式需要使用初始化向量,这里使用到IvParameterSpec类。该类指定初始化向量(IV)。
先用SecureRandom生成一个给定长度的种子字节数组,然后构造IvParameterSpec的实例。
SecureRandom secureRandom = new SecureRandom();
byte[] seed = secureRandom.generateSeed(8);
IvParameterSpec ivSpec = new IvParameterSpec(seed);
字节数组长度须为8,否则执行的时候会报异常 Wrong IV length: must be 8 bytes long。
这是因为Blowfish算法的块大小是8个字节。
三、实现代码
加密函数
private static byte[] encrypt(byte[] plainData, byte[] rawKey, IvParameterSpec iv) throws NoSuchPaddingException,
NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5PADDING","SunJCE");
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] cipherData = cipher.doFinal(plainData);
return cipherData;
}
解密函数
private static byte[] decrypt(byte[] cipherData, byte[] rawKey, IvParameterSpec iv) throws NoSuchPaddingException,
NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchProviderException {
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5PADDING", "SunJCE");
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "Blowfish");
cipher.init(Cipher.DECRYPT_MODE, keySpec,iv);
byte[] plainData = cipher.doFinal(cipherData);
return plainData;
}
测试结果
总结
ECB、CBC模式已经被证明是不安全的了。在实际使用过程中,我们需要考虑密钥的保密性和算法的安全性。
以上就是分享的内容,仅作学习交流使用。后面我们再学习Twofish算法,看看如何实现。
版权归原作者 匡河捞小鱼 所有, 如有侵权,请联系我们删除。