对称加密和非对称加密,

一:对称加密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 DES= "DES";
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();
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值