日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

對(duì)稱(chēng)式加密和非對(duì)稱(chēng)加密的對(duì)比

作者:好的OK Txtcyvy 更新時(shí)間: 2022-08-15 編程語(yǔ)言

對(duì)稱(chēng)式加密

對(duì)稱(chēng)加密算法就是傳統(tǒng)的用一個(gè)密碼進(jìn)行加密和解密。例如,我們常用的WinZIP和WinRAR對(duì)壓縮包的加密和解密,就是使用對(duì)稱(chēng)加密算法

常見(jiàn)的對(duì)稱(chēng)加密算法有:

算法 密鑰長(zhǎng)度 工作模式 填充模式
DES 56/64 ECB/CBC/PCBC/CTR/... NoPadding/PKCS5Padding/...
AES 128/192/256 ECB/CBC/PCBC/CTR/... NoPadding/PKCS5Padding/PKCS7Padding/...
IDEA 128 ECB PKCS5Padding/PKCS7Padding/...

密鑰長(zhǎng)度直接決定加密強(qiáng)度,工作模式和填充模式可以看成是對(duì)稱(chēng)加密算法的參數(shù)和格式選擇。

DES算法由于密鑰過(guò)短,可以在短時(shí)間內(nèi)被暴力破解,所以現(xiàn)在已經(jīng)不安全了。

AES是目前應(yīng)用最廣泛的加密算法,比較常見(jiàn)的工作模式是ECB和CBC。

ECB模式加密與解密

ECB模式只需要一個(gè)固定長(zhǎng)度的密鑰固定的明文會(huì)生成固定的密文

ECB模式加/解密的代碼編寫(xiě)需要根據(jù)算法名稱(chēng)/工作模式/填充模式獲取Cipher實(shí)例,再通過(guò)算法名稱(chēng)和固定的密鑰獲取SecretKey實(shí)例,之后通過(guò)SecretKey實(shí)例和設(shè)置的加/解密模式初始化秘鑰,最后就可以根據(jù)傳入的明文/密文,進(jìn)行加密/解密

具體代碼如下:

package com.gjh.demo;

import java.io.ObjectInputStream.GetField;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Text02 {
	//AES對(duì)稱(chēng)加密
	//ECB工作模式
	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		//原文
		String message="Hello,world!";
		System.out.println("Message:"+message);
		//128位秘鑰=16 bytes key:
		byte[] key="1234567890abcdef1234567890abcdef".getBytes();
		//加密:
		byte[] data=message.getBytes();
		byte[] encrypted=encrypt(key,data);
		System.out.println("Encrypted(加密):"+Base64.getEncoder().encode(encrypted));
		//解密:
		byte[] decrypted=decrypt(key,encrypted);
		System.out.println("Decrypted:"+new String(decrypted));
	}
	//加密:
	public static byte[] encrypt(byte[] key,byte[] input) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		//創(chuàng)建密碼對(duì)象,需要傳入算法/工作模式/填充模式
		Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
		//根據(jù)key的字節(jié)內(nèi)容,“恢復(fù)”秘鑰對(duì)象
		SecretKey keySpec=new SecretKeySpec(key, "AES");
		//初始化秘鑰:設(shè)置加密模式ENCRYPT_MOED
		cipher.init(Cipher.ENCRYPT_MODE, keySpec);
		//根據(jù)原始內(nèi)容(字節(jié)),進(jìn)行加密
		return cipher.doFinal(input);
	}
	//解密:
	public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		//創(chuàng)建密碼對(duì)象,需要傳入算法/工作模式/填充模式
		Cipher cipher =Cipher.getInstance("AES/ECB/PKCS5Padding");
		//根據(jù)key的字節(jié)內(nèi)容,“恢復(fù)”秘鑰對(duì)象
		SecretKey keySpec=new SecretKeySpec(key, "AES");
		//初始化秘鑰:設(shè)置解密模式ENCRYPT_MOED
		cipher.init(Cipher.DECRYPT_MODE, keySpec);
		//根據(jù)原始內(nèi)容(字節(jié)),進(jìn)行解密
		return cipher.doFinal(input);
	}

}

運(yùn)行結(jié)果如下:

?

CBC模式加密與解密

CBC模式下,需要一個(gè)隨機(jī)生成的16字節(jié)IV參數(shù),使用SecureRandom生成。

因?yàn)槎嗔艘粋€(gè)IvParameterSpec實(shí)例,因此,初始化方法需要調(diào)用Cipher的重載方法傳入IV參數(shù)和操作模式、秘鑰。

具體代碼如下:

package com.gjh.demo;

import java.io.ObjectInputStream.GetField;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Text03 {
	//AES對(duì)稱(chēng)加密
	//CBC工作模式
	public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
		//原文
		String message="Hello,world!";
		System.out.println("Message(原始信息):"+message);
		//256位秘鑰=32 bytes key:
		byte[] key="1234567890abcdef1234567890abcdef".getBytes();
		//加密:
		byte[] data=message.getBytes();
		byte[] encrypted=encrypt(key,data);
		System.out.println("Encrypted(加密內(nèi)容):"+Base64.getEncoder().encodeToString(encrypted));
		//解密:
		byte[] decrypted=decrypt(key,encrypted);
		System.out.println("Decrypted(解密內(nèi)容:"+new String(decrypted));
	}
	//加密:
	public static byte[] encrypt(byte[] key,byte[] input) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
		//設(shè)置算法名稱(chēng)/工作模式CBC/填充模式
		Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");
		//“恢復(fù)”秘鑰對(duì)象
		SecretKey keySpec=new SecretKeySpec(key, "AES");
		//CBC模式需要生成一個(gè)16bytes的initialization vector:
		SecureRandom sr=SecureRandom.getInstanceStrong();
		byte[] iv=sr.generateSeed(16);   //生成16個(gè)字節(jié)的隨機(jī)數(shù)
		System.out.println(Arrays.toString(iv));
		IvParameterSpec ivps=new IvParameterSpec(iv);   //隨機(jī)數(shù)封裝成IvParameterSpec參數(shù)對(duì)象
		//初始化秘鑰:操作模式、秘鑰、IV參數(shù)
		cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivps);
		//加密
		byte[] data=cipher.doFinal(input);
		//IV不需要保密,把IV和密文一起返回
		return join(iv,data);
	}
	
	private static byte[] join(byte[] bs1, byte[] bs2) {
		byte[] r=new byte[bs1.length+bs2.length];
		System.arraycopy(bs1,0,r,0,bs1.length);
		System.arraycopy(bs2,0,r,bs1.length,bs2.length);
		return r;
	}
	//解密:
	public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
		//把input分割成IV和密文
		byte[] iv=new byte[16];
		byte[] data=new byte[input.length-16];
		
		System.arraycopy(input,0,iv,0,16);
		System.arraycopy(input, 16, data, 0, data.length);
		System.out.println(Arrays.toString(iv));
		
		//解密:
		Cipher cipher =Cipher.getInstance("AES/CBC/PKCS5Padding");   //密碼對(duì)象
		SecretKey keySpec=new SecretKeySpec(key, "AES");   //恢復(fù)秘鑰
		IvParameterSpec ivps=new IvParameterSpec(iv);  //恢復(fù)IV
		//初始化秘鑰:操作模式、秘鑰、IV參數(shù)
		cipher.init(Cipher.DECRYPT_MODE, keySpec,ivps);
		//解密操作
		return cipher.doFinal(data);
	}

}

運(yùn)行結(jié)果如下:

?

?觀(guān)察輸出,可以發(fā)現(xiàn)每次生成的IV不同,密文也不同。

另外,DH算法是一種密鑰交換協(xié)議,通信雙方通過(guò)不安全的信道最終協(xié)商出一個(gè)共同的密鑰(這個(gè)密鑰不會(huì)通過(guò)網(wǎng)絡(luò)傳輸),然后進(jìn)行對(duì)稱(chēng)加密傳輸

非對(duì)稱(chēng)式加密算法

非對(duì)稱(chēng)加密加密和解密使用的不是相同的密鑰,只有同一個(gè)公鑰-私鑰對(duì)才能正常加解密。

非對(duì)稱(chēng)加密的典型算法就是RSA算法,它的密鑰有256/512/1024/2048/4096等不同的長(zhǎng)度。長(zhǎng)度越長(zhǎng),密碼強(qiáng)度越大,當(dāng)然計(jì)算速度也越慢。

非對(duì)稱(chēng)加密的優(yōu)點(diǎn):對(duì)稱(chēng)加密需要協(xié)商密鑰,而非對(duì)稱(chēng)加密可以安全地公開(kāi)各自的公鑰,在N個(gè)人之間通信的時(shí)候:使用非對(duì)稱(chēng)加密只需要N個(gè)密鑰對(duì),每個(gè)人只管理自己的密鑰對(duì)。而使用對(duì)稱(chēng)加密需要?jiǎng)t需要N*(N-1)/2個(gè)密鑰,因此每個(gè)人需要管理N-1個(gè)密鑰,密鑰管理難度大,而且非常容易泄漏。
非對(duì)稱(chēng)加密的缺點(diǎn):運(yùn)算速度非常慢,比對(duì)稱(chēng)加密要慢很多。
所以,在實(shí)際應(yīng)用的時(shí)候,非對(duì)稱(chēng)加密總是和對(duì)稱(chēng)加密一起使用。

原文鏈接:https://blog.csdn.net/qq_50587186/article/details/125918772

欄目分類(lèi)
最近更新