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

學無先后,達者為師

網站首頁 編程語言 正文

對稱式加密與非對稱式加密的對比

作者:卡多希y 更新時間: 2022-07-22 編程語言

? ? 對稱加密算法就是傳統的用一個密碼進行加密和解密。例如:我們常用的WinZip和WinRAR對壓縮包的加密和解密就是使用的對稱加密算法。

? ? ? ? 常見的對稱加密算法有:

目前主流的對稱式加密算法為AES加密算法

我們以AES算法,ECB工作模式為例,看看如如計算哈希:

一:加密:

1、創建加密對象Cipher

2、根據key內容,恢復密鑰對象

3、初始化密鑰,設置加密模式

4、根據原始內容進行加密

5、輸出加密結果

二:解密

1、創建解密對象Cipher

2、根據key內容,恢復密鑰對象

3、初始化密鑰,設置解密模式

4、根據原始內容進行解密

5、輸出解密結果

public class Demo07 {
	public static void main(String[] args) {
		// 對稱加密算法
		// AES算法 ECB模式
		
		try {
			// 密文
			byte[] messageByte = "12346".getBytes();
			
			// 密鑰
			byte[] keyByte = "1234567891234567".getBytes();
			
			// 加密
			// 創建密碼對象
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			
			// 根據key內容,恢復密鑰對象
			SecretKey keySpec = new SecretKeySpec(keyByte, "AES");
			
			// 初始化密鑰,設置加密模式
			cipher.init(Cipher.ENCRYPT_MODE, keySpec);
			
			// 根據原始內容,進行加密
			byte[] resByteArray = cipher.doFinal(messageByte);
			
			// 輸出加密內容
			System.out.println(Base64.getEncoder().encodeToString(resByteArray));
			
			// 解密
			cipher.init(Cipher.DECRYPT_MODE, keySpec);
			byte[] aaaByteArray = cipher.doFinal(resByteArray);
			
			// 輸出加密內容
			System.out.println(new String(aaaByteArray));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

加解密結果:

?根據結果可以發現,加解密步驟大致相同,但是要保證雙方密鑰在交換的過程中保證安全性,一般我們會采用DH算法,也就是密鑰交換算法,使用了這種算法可以保證雙方的共享密鑰一致,并且保證了密鑰的安全性。一般情況下,對稱式加密算法都是與密鑰交換算法配合起來使用的。

再來看非對稱式加密算法:

非對稱加密算法使用的是一對密鑰,使用公鑰加密私鑰解密的方法,這就使得在通信初期,要想雙方可以通信,必須讓A方先發送公鑰給B方,B方通過接受的公鑰進行加密,再將密文發送給A方,A方再使用私鑰進行解密。盡管這樣會使效率降低,但能大幅度保證安全傳輸。一般情況下,都是對稱式加密算法與非對稱式加密算法配合起來使用。

非對稱式加密算法如下:

public class Main04 {
	public static void main(String[] args) {
        // Bob和Alice:
        Person bob = new Person("Bob");
        Person alice = new Person("Alice");
        
        // 各自生成KeyPair: 公鑰+私鑰
        bob.generateKeyPair();
        alice.generateKeyPair();

        // 雙方交換各自的PublicKey(公鑰):
        // Bob根據Alice的PublicKey生成自己的本地密鑰(共享公鑰):
        bob.generateSecretKey(alice.publicKey.getEncoded());
        
        // Alice根據Bob的PublicKey生成自己的本地密鑰(共享公鑰):
        alice.generateSecretKey(bob.publicKey.getEncoded());

        // 檢查雙方的本地密鑰是否相同:
        bob.printKeys();
        alice.printKeys();
        
        // 雙方的SecretKey相同,后續通信將使用SecretKey作為密鑰進行AES加解密...
    }
}

// 用戶類
class Person {
    public final String name; // 姓名
    
    // 密鑰
    public PublicKey publicKey; // 公鑰
    private PrivateKey privateKey; // 私鑰
    private byte[] secretKey; // 本地秘鑰(共享密鑰)

    // 構造方法
    public Person(String name) {
        this.name = name;
    }

    // 生成本地KeyPair:(公鑰+私鑰)
    public void generateKeyPair() {
        try {
        	// 創建DH算法的“秘鑰對”生成器
            KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");
            kpGen.initialize(512);
            
            // 生成一個"密鑰對"
            KeyPair kp = kpGen.generateKeyPair();
            this.privateKey = kp.getPrivate(); // 私鑰
            this.publicKey = kp.getPublic(); // 公鑰
            
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }
    
    // 按照 "對方的公鑰" => 生成"共享密鑰"
    public void generateSecretKey(byte[] receivedPubKeyBytes) {
        try {
            // 從byte[]恢復PublicKey:
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(receivedPubKeyBytes);
            
            // 根據DH算法獲取KeyFactory
            KeyFactory kf = KeyFactory.getInstance("DH");
            // 通過KeyFactory創建公鑰
            PublicKey receivedPublicKey = kf.generatePublic(keySpec);
            
            // 生成本地密鑰(共享公鑰)
            KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
            keyAgreement.init(this.privateKey); // 初始化"自己的PrivateKey"
            keyAgreement.doPhase(receivedPublicKey, true); // 根據"對方的PublicKey"
            
            // 生成SecretKey本地密鑰(共享公鑰)
            this.secretKey = keyAgreement.generateSecret();
            
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
    }

    public void printKeys() {
        System.out.printf("Name: %s\n", this.name);
        System.out.printf("Private key: %x\n", new BigInteger(1, this.privateKey.getEncoded()));
        System.out.printf("Public key: %x\n", new BigInteger(1, this.publicKey.getEncoded()));
        System.out.printf("Secret key: %x\n", new BigInteger(1, this.secretKey));
    }
}

結果如下:

?總的來說:對稱式加密使用同一個密鑰進行加密和解密。而非對稱式加密就是加密和解密使用的是不同的密鑰,只有同一對的公鑰和私鑰才能正常進行加密和解密。

原文鏈接:https://blog.csdn.net/qq_17845335/article/details/125918566

欄目分類
最近更新