本文主要介绍数据加密相关的技术,数据以加密的形式传输,保证数据的安全性。纵使有人在半路截取了数据,也无法破解。标准的加密算法有两种,对称算法:DES, 3DES, AES;非对称算法:RSA, SSL,本文只介绍对称算法。
首先来说说,什么是加密。简单来说,加密就是,你知、我知、他不知。数据的原文,通过秘钥,然后经过运算得到密文,然后对方通过该秘钥又可以解密。其中加密算法可以公开,秘密都存在秘钥中。
下面我们介绍DES 算法,其特点是:每8个字节为一组,分组加密;秘钥为8个字节;加密方式有 ECB, CBC, FCB 等方式。我们只讲ECB方式。因为秘钥是8个字节,所以我们首先对秘钥进行处理,如果大于8个字节则截取,小于即补齐。于是我们写一个工具类:AdCrypto
package my;
/**
* 秘钥的截取和补全
* @author andy
*
*/
public class AdCrypto
{
/**
* 数据的截取
* @param data
* @param N
* @return
*/
public static byte[] truncate(byte[] data , int N)
{
if(data.length <= N)
return data;
byte[] buf = new byte[N];
for(int i=0 ; i < N ; i++)
{
buf[i] = data[i];
}
return buf;
}
/**
* 数据的补全
* @param data
* @param N
* @param p
* @return
*/
public static byte[] padding(byte[] data , int N , byte p)
{
//首先判断是否已经对齐
int r = data.length % N;
if(r == 0) return data;
byte[] result = new byte[N];
for(int i=0 ; i < N ; i++)
{
if(i > data.length-1)
result[i] = p;
else
result[i] = data[i];
}
return result;
}
}
通过该工具类可以处理秘钥,之后还需对原文进行处理。因为是每8个字节为一组加密,所以我们的数据要求必须是8的整数倍,但是在实际中是很难满足的,所以我们要对其进行补齐。我们采用的方法是,PKCS5算法补齐方式。该算法的实现,不用我们自己写了,直接用jdk自带就可以了。下面给个例子:
package my;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* DES算法
* @author andy
*
*/
public class DESDemo
{
/**
* 加密
* @param plain
* @param key
* @return
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static byte[] encrypt(byte[] plain , byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException
{
//DES算法实例,采用PKCS5补齐方式
Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
//设置秘钥
SecretKeyFactory keyFectory = SecretKeyFactory.getInstance("DES");
SecretKeySpec keySpec = new SecretKeySpec(key, "DES");
c.init(Cipher.ENCRYPT_MODE, keySpec);
//加密
byte[] output = c.doFinal(plain);
return output;
}
/**
* 解密
* @param cipher
* @param key
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static byte[] decrypt(byte[] cipher , byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException
{
//DES算法实例
Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
//设置秘钥
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKeySpec keySpec = new SecretKeySpec(key, "DES");
c.init(Cipher.DECRYPT_MODE, keySpec);
//加密
byte[] output = c.doFinal(cipher);
return output;
}
public static void main(String[] args) throws InvalidKeyException, Exception, Exception, Exception
{
// 密钥, DES 采用8字节的密钥
byte[] key = "2019tes".getBytes();
key = AdCrypto.padding(key, 8, (byte)0);
// 原文
byte[] plain = {
1, 2, 3, 4, 5, 6, 7, 8,
41, 42, 43, 44, 45, 46, 47, 48,
61, 62, 63, 64, 65, 66, 67, 68,
};
// 加密
byte[] cipher = encrypt(plain, key);
String str = "d31b6374385cf76020ab8c65f0ad45e1adeed30e180b20c8b9581f41d3c4b5dc";
byte[] buf = Hex.decodeHex(str);
//解密
byte[] plain2 = decrypt(buf , key);
System.out.println("原文: " + Hex.encodeHexString(plain));
System.out.println("密文: " + Hex.encodeHexString(cipher));
System.out.println("解密:" + Hex.encodeHexString(plain2));
}
}
其实,该加密方式已经过时,现在常用的是AES算法,它的秘钥是16个字节,但是它用法和DES一样的,只是将Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");稍作修改即可。