好久没有写博客了,最近比较忙,更比较烦。工作忙的一塌糊涂,感情也没有着落,怎一个杯具了得呀~!
前些天日方客户要求对用户信息文件加密,需要采用blowfish算法。其实网上blowfish代码也挺多的,不过给大家分享下,用的时候也方便。
一、Blowfish算法是什么呢?
Blowfish是一个64位分组及可变密钥长度的分组密码算法,算法由两部分组成:密钥扩展和数据加密。密钥扩展把长度可达到448位的密钥转变成总共4168字节的几个子密钥。
数据加密由一个简单函数迭代16轮,每一轮由密钥相关的置换,密钥相关和数据相关的代替组成。所有的运算都是32位字的加法和异或,仅有的另一个运算是每轮的四个查表。
Blowfish使用了大量的子密钥,这些密钥必须在加密及解密之前进行预计算。
二、Blowfish算法的计算步骤?
1.初始化P数组,然后是4个S盒用固定的串.这些串由π的十六进制组成.
2.用密钥的第一个32位与P1异或,用密钥的第二个32位与P2异或,依此类推,直到密钥的所有位(直到P18).周期性地循环密钥的所有位直到整个P数组与密钥异或完为止.
3.利用Blowfish算法加密全零串,其密钥为在第1和第2步中描述的子密钥.
4.用第3步的输出取代P1和P2.
5.利用Blowfish算法加密第3步的输出,其密钥为修改过的子密钥.
6.用第5步的输出取代P3和P4.
7.重重上述操作,直到P数组的所有元素及4个S盒全部被连续变化的Blowfish的输出所取代.
主要代码:
import java.security.MessageDigest;
import java.util.Random;
public class BlowfishUtil
{
private BlowfishCBC m_bfish;
private static Random m_rndGen = new Random();
private static final char HEXTAB[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'
};
private static class BlowfishCBC extends BlowfishECB
{
public long getCBCIV()
{
return m_lCBCIV;
}
public void getCBCIV(byte dest[])
{
BlowfishUtil.longToByteArray(m_lCBCIV, dest, 0);
}
public void setCBCIV(long lNewCBCIV)
{
m_lCBCIV = lNewCBCIV;
}
public void setCBCIV(byte newCBCIV[])
{
m_lCBCIV = BlowfishUtil.byteArrayToLong(newCBCIV, 0);
}
public void cleanUp()
{
m_lCBCIV = 0L;
super.cleanUp();
}
private long encryptBlockCBC(long lPlainblock)
{
lPlainblock ^= m_lCBCIV;
lPlainblock = super.encryptBlock(lPlainblock);
return m_lCBCIV = lPlainblock;
}
private long decryptBlockCBC(long lCipherblock)
{
long lTemp = lCipherblock;
lCipherblock = super.decryptBlock(lCipherblock);
lCipherblock ^= m_lCBCIV;
m_lCBCIV = lTemp;
return lCipherblock;
}
public void encrypt(byte inbuffer[], byte outbuffer[])
{
int nLen = inbuffer.length;
for(int nI = 0; nI < nLen; nI += 8)
{
long lTemp = BlowfishUtil.byteArrayToLong(inbuffer, nI);
lTemp = encryptBlockCBC(lTemp);
BlowfishUtil.longToByteArray(lTemp, outbuffer, nI);
}
}
public void encrypt(byte buffer[])
{
int nLen = buffer.length;
for(int nI = 0; nI < nLen; nI += 8)
{
long lTemp = BlowfishUtil.byteArrayToLong(buffer, nI);
lTemp = encryptBlockCBC(lTemp);
BlowfishUtil.longToByteArray(lTemp, buffer, nI);
}
}
public void encrypt(int inbuffer[], int outbuffer[])
{
int nLen = inbuffer.length;
for(int nI = 0; nI < nLen; nI += 2)
{
long lTemp = BlowfishUtil.intArrayToLong(inbuffer, nI);
lTemp = encryptBlockCBC(lTemp);
BlowfishUtil.longToIntArray(lTemp, outbuffer, nI);
}
}
public void encrypt(int buffer[])
{
int nLen = buffer.length;
for(int nI = 0; nI < nLen; nI += 2)
{
long lTemp = BlowfishUtil.intArrayToLong(buffer, nI);
lTemp = encryptBlockCBC(lTemp);
BlowfishUtil.longToIntArray(lTemp, buffer, nI);
}
}
public void encrypt(long inbuffer[], long outbuffer[])
{
int nLen = inbuffer.length;
for(int nI = 0; nI < nLen; nI++)
outbuffer[nI] = encryptBlockCBC(inbuffer[nI]);
}
public void encrypt(long buffer[])
{
int nLen = buffer.length;
for(int nI = 0; nI < nLen; nI++)
buffer[nI] = encryptBlockCBC(buffer[nI]);
}
public void decrypt(byte inbuffer[], byte outbuffer[])
{
int nLen = inbuffer.length;
for(int nI = 0; nI < nLen; nI += 8)
{
long lTemp = BlowfishUtil.byteArrayToLong(inbuffer, nI);
lTemp = decryptBlockCBC(lTemp);
BlowfishUtil.longToByteArray(lTemp, outbuffer, nI);
}
}
public void decrypt(byte buffer[])
{
int nLen = buffer.length;
for(int nI = 0; nI < nLen; nI += 8)
{
long lTemp = BlowfishUtil.byteArrayToLong(buffer, nI);
lTemp = decryptBlockCBC(lTemp);
BlowfishUtil.longToByteArray(lTemp, buffer, nI);
}
}
public void decrypt(int inbuffer[], int outbuffer[])
{
int nLen = inbuffer.length;
for(int nI = 0; nI < nLen; nI += 2)
{
long lTemp = BlowfishUtil.intArrayToLong(inbuffer, nI);
lTemp = decryptBlockCBC(lTemp);
BlowfishUtil.longToIntArray(lTemp, outbuffer, nI);
}
}
public void decrypt(int buffer[])
{
int nLen = buffer.length;
for(int nI = 0; nI < nLen; nI += 2)
{
long lTemp = BlowfishUtil.intArrayToLong(buffer, nI);
lTemp = decryptBlockCBC(lTemp);