常见的对称式加密与非对称式加密算法

本文介绍了对称加密与非对称加密的区别,重点讲解了AES和RSA两种常见加密算法。AES加密使用相同的密钥进行加解密,操作速度快,适合大量数据;RSA则采用公钥加密、私钥解密,安全性高但速度慢。文中通过Java代码示例展示了AES的加密解密过程,并简述了RSA算法的密钥生成和加密解密流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概述

        对称式加密:对称加密算法就是传统的用一个密码进行加密和解密,通信发送方使用这种算法加密数据,接收方也用同样的算法解密数据. 因此对称式加密本身不是安全的。从程序的角度看,所谓加密,就是这样一个函数:

        它接收密码和明文,然后输出密文: secret = encrypt(key, message); 而解密则相反,它接收密码和密文,然后输出明文: plain = decrypt(key, secret);

        常见的对称式加密算法:

算法秘钥长度工作模式填充模式
AES56/64ECB/CBC/PCBC/CTR/...NoPadding/PKCS5Padding/...
DES128/192/256ECB/CBC/PCBC/CTR/..NoPadding/PKCS5Padding/PKCS7Padding/...
IDEA128ECBPKCS5Padding/PKCS7Padding/...

        密钥长度直接决定加密强度,而工作模式和填充模式可以看成是对称加密算法的参数和格式选择。Java标准库提供的算法实现并不包括所有的工作模式和所有填充模式,但是通常我们只需要挑选常用的使用就可以了。

        非对称式加密:加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密,例如:小明要加密一个文件发送给小红,他应该首先向小红索取她的公钥,然后,他用小红的公钥加密,把加密文件发送给小红,此文件只能由小红的私钥解开,因为小红的私钥在她自己手里,所以,除了小红,没有任何人能解开此文件。

        非对称加密的优点:对称加密需要协商密钥,而非对称加密可以安全地公开各自的公钥,在N个人之间通信的时候:使用非对称加密只需要N个密钥对,每个人只管理自己的密钥对。而使用对称加密需要则需要N*(N-1)/2个密钥,因此每个人需要管理N-1个密钥,密钥管理难度大,而且非常容易泄漏。

        非对称加密的缺点:运算速度非常慢,比对称加密要慢很多

        非对称加密的典型算法就是RSA算法,它是由Ron Rivest,Adi Shamir,Leonard Adleman这三个人一起发明的,所以用他们三个人的姓氏首字母缩写表示。

2.使用AES加密

1.根据算法名称/工作模式/填充模式获取Cipher实例;

2 根据算法名称初始化一个SecretKey实例,密钥必须是指定长度;

3 使用SerectKey初始化Cipher实例,并设置加密或解密模式;

4 传入明文或密文,获得密文或明文。

public class AES_Test {
	public static void main(String[] args) throws Exception{
		String message = "HelloWorld";
		System.out.println("原始内容:" +message);
		
		//128位秘钥=16 bytes key:
		byte[] key = "1234567996xxyabc".getBytes();
		
		//加密:
		byte[] data = message.getBytes();
		byte[] encrypted = encrypt(key,data);
		System.out.println("加密结果: "+Base64.getEncoder().encodeToString(encrypted));
		
		//解密:
		byte[] decrypted = decrypt(key,encrypted);
		System.out.println("解密结果: "+new String(decrypted));
		
	}
	//加密:
	public static byte[] encrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		//创建密码对象,需要传入算法/工作模式/填充模式
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		
		//根据key的字节内容,"恢复"密码对象
		SecretKey keySpec = new SecretKeySpec(key, "AES");
		//初始化秘钥,设置加密模式ENCRYPT_MODE
		cipher.init(cipher.ENCRYPT_MODE, keySpec);
		//根据原始内容(字节),进行加密
		return cipher.doFinal(input);		
	}
	//解密:
	public static byte[] decrypt(byte[] key,byte[] input) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		//创建密码对象,需要传入算法/工作模式/填充模式
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		
		//根据key的字节内容,"恢复"密码对象
		SecretKey keySpec = new SecretKeySpec(key, "AES");
		//初始化秘钥,设置解密模式DECRYPT_MODE
		cipher.init(cipher.DECRYPT_MODE, keySpec);
		//根据原始内容(字节),进行解密
		return cipher.doFinal(input);		
	}
}

输出结果:

原始内容:HelloWorld
加密结果: z0cr9rJRvwNu9V7D6EOlzw==
解密结果: HelloWorld

3.RSA加密算法

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;

// RSA
public class Main {
	public static void main(String[] args) throws Exception {
		// 明文:
		byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");

		// 创建公钥/私钥对:
		Human alice = new Human("Alice");

		// 用Alice的公钥加密:
		// 获取Alice的公钥,并输出
		byte[] pk = alice.getPublicKey();
		System.out.println(String.format("public key(公钥): %x", new BigInteger(1, pk)));

		// 使用公钥加密
		byte[] encrypted = alice.encrypt(plain);
		System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));

		// 用Alice的私钥解密:
		// 获取Alice的私钥,并输出
		byte[] sk = alice.getPrivateKey();
		System.out.println(String.format("private key(私钥): %x", new BigInteger(1, sk)));

		// 使用私钥解密
		byte[] decrypted = alice.decrypt(encrypted);
		System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
	}
}

// 用户类
class Human {
	// 姓名
	String name;

	// 私钥:
	PrivateKey sk;

	// 公钥:
	PublicKey pk;

	// 构造方法
	public Human(String name) throws GeneralSecurityException {
		// 初始化姓名
		this.name = name;

		// 生成公钥/私钥对:
		KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
		kpGen.initialize(1024);
		KeyPair kp = kpGen.generateKeyPair();

		this.sk = kp.getPrivate();
		this.pk = kp.getPublic();
	}

	// 把私钥导出为字节
	public byte[] getPrivateKey() {
		return this.sk.getEncoded();
	}

	// 把公钥导出为字节
	public byte[] getPublicKey() {
		return this.pk.getEncoded();
	}

	// 用公钥加密:
	public byte[] encrypt(byte[] message) throws GeneralSecurityException {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, this.pk); // 使用公钥进行初始化
		return cipher.doFinal(message);
	}

	// 用私钥解密:
	public byte[] decrypt(byte[] input) throws GeneralSecurityException {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, this.sk); // 使用私钥进行初始化
		return cipher.doFinal(input);
	}
}

        RSA算法的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢。

4.总结:

        1.加密和解密过程不同 :对称加密过程和解密过程使用的同一个密钥,加密过程相当于用原文+密钥可以传输出密文,同时解密过程用密文-密钥可以推导出原文。但非对称加密采用了两个密钥,一般使用公钥进行加密,使用私钥进行解密。

         2.加密解密速度不同 : 对称加密解密的速度比较快,适合数据比较长时的使用。非对称加密和解密花费的时间长、速度相对较慢,只适合对少量数据的使用。  

        3.传输的安全性不同 : 对称加密的过程中无法确保密钥被安全传递,密文在传输过程中是可能被第三方截获的,如果密码本也被第三方截获,则传输的密码信息将被第三方破获,安全性相对较低。  非对称加密算法中私钥是基于不同的算法生成不同的随机数,私钥通过一定的加密算法推导出公钥,但私钥到公钥的推导过程是单向的,也就是说公钥无法反推导出私钥。所以安全性较高。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值