一:对称加密EDS--
1.获取随机密匙加密
对称加密只有一把钥匙,密匙获取是随机的每次获取的密匙都不一样,所以如果想需要使用同一个密匙就需要进行保存,最安全的保存方式是通过jni保存(c++没去自学过,不知道怎么写,所以就使用本地文件存储方式存储),密匙对象SecretKey本身实现了序列化,所以可以直接把密匙对象直接存储到文件中.如果要得到直接反序列化获取密匙密匙对象即可.
public class CiperDemo {
public static void main(String[] args) throws Exception{
//保存密钥
saveKey("my.key");
//获取密钥
SecretKey getKey = (SecretKey) getKey("my.key");
//通过密钥加密后
String result= "测试加密";
System.out.println(result+":加密前");
//对称加密后返回加密后的字节数组,
byte[] b = encrypt(getKey,result);
//解密
decrypt(b,getKey);
}
private static void getText(String aa) {
File file = new File(aa);
}
/**通过本地文件夹获取密钥*/
private static Object getKey(String path) throws Exception {
FileInputStream file = new FileInputStream(path);
ObjectInputStream inputStream = new ObjectInputStream(file);
Object object = (SecretKey) inputStream.readObject();
System.out.println(object);
return object;
}
/**创建文件夹把密钥存入本地*/
private static void saveKey(String path) throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
FileOutputStream file = new FileOutputStream(new File(path));
ObjectOutputStream stream = new ObjectOutputStream(file);
stream.writeObject(key);
}
/**解密*/
private static void decrypt(byte[] m, SecretKey key) throws Exception{
//对称加密使用
Cipher cipher = Cipher.getInstance("DES");
//使用加密模式
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] bs = cipher.doFinal(m);
//测试打印字节
System.out.println(new String(bs)+":解密后");
}
/**加密
* @param result */
public static byte[] encrypt(SecretKey key, String result) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
//对称加密使用
Cipher cipher = Cipher.getInstance("DES");
//使用加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] bs = cipher.doFinal(result.getBytes());
System.out.println(new String(bs)+"加密后 ");
return bs;
}
}
运行结果:
javax.crypto.spec.SecretKeySpec@1853b
测试加密:加密前
�7K�^���l�hE-?加密后
测试加密:解密后
2.:自定义密匙加密EDS,
方法差不多,只是把随机获取变成了密匙工厂获取密匙:自定义密匙长度是固定 的,其中加密长度是56个字节,但是还需要8个字节充当效验码,所以传入的字节必须是64位.同时,我们知道,加密后的密文是字节数组,是不能直接强转成字符串的,否则无法解密密文.
public class DESCiperDemo2 {
// public static final String DES = "DES/ECB/PKCS5Padding"; 如果使用这个模式,那么就可以改变传入的字节长度
//public static final String key ="1234a";
public static final String key ="1234568a";
public static void main(String[] args) throws Exception{
String input = "这是加密";
//String key = ;
//加密
byte[] mEncrypt = encrypt(input,key);
//把获取到字节密文转换成字符串密文
String string = Utils.printUtil(mEncrypt);
//把字符串密文转换成字节密文
byte[] bs = Utils.getByteArray(string.split(","));
//解密
byte[] mDerypt = derypt(bs,key);
//byte[] mDerypt = derypt(mEncrypt,key);
//打印解密
System.out.println(new String(mDerypt));
}
private static byte[] derypt(byte[] mEncrypt, String key) throws Exception {
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKey secret = SecretKeyFactory.getInstance(DES).generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(DES);
cipher.init(Cipher.DECRYPT_MODE, secret);
byte[] bs = cipher.doFinal(mEncrypt);
return bs;
}
private static byte[] encrypt(String input, String key) throws Exception{
//密匙规范--把自己想变成密匙的字符串规范成密匙对象
//加密算法:"algorithm/mode/padding" "算法/工作模式/填充模式"
DESKeySpec keySpec = new DESKeySpec(key.getBytes());//通过密匙工厂获取密匙
SecretKey secretKey = SecretKeyFactory.getInstance(DES).generateSecret(keySpec);
//获取加密对象
Cipher cipher = Cipher.getInstance(DES);
//初始化对象
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
//进行加密
byte[] bs = cipher.doFinal(input.getBytes());
System.out.println("加密后:"+new String(bs));
return bs;
}
}
运行结果
加密后:M� �(����� I��
77,-128,12,26,-63,40,-11,17,-89,-76,-80,-96,9,73,-80,-83,
这是加密
Utils类中,----哈哈方法写的比较随意
//把字节转换成字符串格式
public static String printUtil(byte[] bt){
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < bt.length; i++) {
buffer.append(bt[i]).append(",");
}
System.out.println(buffer.toString());
return buffer.toString();
}
//把符合字节格式的字符串数组转换成字节数组
public static byte[] getByteArray(String[] array){
byte[] bt = new byte[array.length];
for (int i = 0; i < array.length; i++) {
bt[i] = Byte.parseByte(array[i]);
}
return bt;
}
3.对称加密AES模式
AES模式安全系数要比DES安全系数高的多,AES密匙长度是128位
public class CiperDemo2 {
public static final String AES= "AES";
//加密算法:"algorithm/mode/padding" "算法/工作模式/填充模式"
//如果要实现这个cbc模式,就必须添加iv参数,
public static final String AES2 = "AES/CBC/PKCS5Padding";
public static final String key ="1234567812345689";
public static void main(String[] args) throws Exception{
String input = "这是加密";
//加密
byte[] mEncrypt = encrypt(input,key);
//解密
byte[] mDerypt = derypt(mEncrypt,key);
//打印解密
System.out.println("解密后:"+new String(mDerypt));
}
private static byte[] derypt(byte[] mEncrypt, String key) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), AES);
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
//Cipher cipher = Cipher.getInstance(AES);
Cipher cipher = Cipher.getInstance(AES2);
//cipher.init(Cipher.DECRYPT_MODE, keySpec);
//使用cbc模式
cipher.init(Cipher.DECRYPT_MODE, keySpec,iv);
byte[] bs = cipher.doFinal(mEncrypt);
return bs;
}
private static byte[] encrypt(String input, String key) throws Exception{
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), AES);
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
//获取加密对象
//Cipher cipher = Cipher.getInstance(AES);
Cipher cipher = Cipher.getInstance(AES2);
//初始化对象
//cipher.init(Cipher.ENCRYPT_MODE, keySpec);
cipher.init(Cipher.ENCRYPT_MODE, keySpec,iv);
//进行加密
byte[] bs = cipher.doFinal(input.getBytes());
System.out.println("加密后:"+new String(bs));
return bs;
}
}
三:非对称加密.RSA
非对称加密的的特点是一次生成2把钥匙,一把公钥,一把私钥,可以相互加密解密.
public class AsCiperRSA {
public static final String RSA = "RSA";
public static void main(String[] args) throws Exception{
String input = "非对称加密";
byte[] mEncrypt = encrypt(input,RSA);
}
private static byte[] encrypt(String input, String rsa) throws Exception {
//生成密匙对
KeyPair pair = KeyPairGenerator.getInstance(rsa).generateKeyPair();
//公钥
PublicKey publicKey = pair.getPublic();
//私钥
PrivateKey privateKey = pair.getPrivate();
Cipher cipher = Cipher.getInstance(rsa);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//不能处理大数据,会报错
//byte[] doFinal = cipher.doFinal(input.getBytes());
byte[] doFinal = doFinalWrite(cipher,input.getBytes(),20);
//测试下加密结果
System.out.println(new String(doFinal));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//测试后发现不能低于128否则Decryption error报错,其实我也不知道为什么
byte[] bs = doFinalWrite(cipher, doFinal, 128);
System.out.println(new String(bs));
return doFinal;
}
/**
* 把字符串分批添加到数组中
* 需要调用cipher.doFinal(input, inputOffset, inputLen)
* @param cipher
* @param bytes
* @param i
* @return
* @throws Exception
*/
private static byte[] doFinalWrite(Cipher cipher, byte[] bytes, int i) throws Exception {
int offset=0;
byte[] temp;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while(bytes.length-offset>0){
if(bytes.length-offset>=i){
temp = cipher.doFinal(bytes,offset,i);
offset=offset+i;
}else{
temp = cipher.doFinal(bytes, offset,bytes.length-offset);
offset = offset+(bytes.length-offset);
}
bos.write(temp);
}
bos.close();
return bos.toByteArray();
}
}