0


BlowFish算法Java实现

一、了解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算法,看看如何实现。

标签: 密码学 java 安全

本文转载自: https://blog.csdn.net/xinyu10001/article/details/128112032
版权归原作者 匡河捞小鱼 所有, 如有侵权,请联系我们删除。

“BlowFish算法Java实现”的评论:

还没有评论