简介:
公开密钥密码学(英语:Public-key cryptography)也称非对称式密码学(英语:Asymmetric cryptography)是密码学的一种算法。加密与解密使用不同的密钥,其中一个称之为公钥,对外公开,通常用于数据加密。另一个称之为私钥,是不能对外公布的,通常用于数据解密,这样使用公钥加密的数据即使被人非法截取,因为没有与之配对的私钥也不能对数据进行解密。
具体过程如下图:
优点:
较于对称算法有较高的安全性,主要是因为加密与解密采用不同的密钥,且无法通过一个密钥推导出另一个密钥,公钥加密的信息只能用同一方的私钥解密。
缺点:
算法非常复杂,导致加密大量数据的时候所用的时间比较长,加密后的报文比较长,会导致数据分片,不利于传输。
常用算法:
DH DSA RDA
RSA介绍:
是公开密钥系统的代表;
安全性:建立在具有大素数因子的合数,其因子分解困难这一法则之上;处理速度慢密钥管理:加解密过程中不必网络传输保密的密钥;密钥管理优于AES算法;
RSA加解密速度慢,不适合大量数据文件加密;
RSA原理:
RSA算法是一种基于数学原理的非对称加密算法,利用公钥加密、私钥解密的特性来保护数据安全和实现数字签名。
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,使用一对密钥(公和私)进行加密和解密操作。它是目前广泛应用于数据加密和数字签名领域的一种加密算法。RSA算法的原理基于两个数学问题:
1.大数分解:在给定一个大的合数的情况下,找到该合数的质因数。
2.模幂运算:计算一个数的指数次幂除以另一个数后的余数。
RSA算法的过程如下:
生成密钥对:首先生成一对密钥,分别是公钥和私钥。公钥可以公开,而私钥必须保密。
加密:使用公钥将明文进行加密。发送方使用公钥对明文进行加密得到密文。
解密:使用私钥将密文进行解密。接收方使用私钥对密文进行解密,还原出原始明文。在RSA算法中,公钥用于加密数据,私钥用于解密数据。加密时,数据经过公钥加密后,只能通过对应的私钥进行解密。这种不对称的特性使得RSA算法在保护数据安全和实现数字签名方面具有重要的应用价值。 RSA算法的安全性基于大数分解问题的困难性,即要通过公钥找到私钥的计算复杂度远远高于通过私钥找到公钥。此外,RSA算法的安全性还依赖于合理选择的秘钥长度。
RSA应用
签名和验签的流程:
代码示例:
package com.gfc.test;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import java.security.*;
/**
* RSA算法
*
* @author gfc
* @date 2023/11/14 9:16
*/
public class EncryptAndDecrypt {
public static void main(String[] args) throws Exception {
// 明文字符串
String plaintext = "Hello, world!";
// 生成RSA密钥对
KeyPair keyPair = generateRSAKeyPair();
// 获取公钥和私钥
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 公钥加密
byte[] encryptedBytes = encryptRSA(plaintext, publicKey);
// 输出密文
System.out.println("密文:" + new String(encryptedBytes));
// 私钥解密
String decryptedBytes = decryptRSA(encryptedBytes, privateKey);
// 输出明文
System.out.println("明文:" + decryptedBytes);
}
/**
* 生成RSA密钥对
*
* @return RSA密钥对
* @throws NoSuchAlgorithmException 理解和处理算法不存在异常
*/
public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
Security.addProvider(new BouncyCastleProvider());
// 初始化密钥对生成器,指定密钥长度为1024位
final int keySize = 1024;
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keySize);
return keyPairGenerator.generateKeyPair();
}
/**
* 公钥加密
*
* @param plaintext 明文
* @param publicKey 公钥
* @return 密文
* @throws Exception 异常
*/
public static byte[] encryptRSA(String plaintext, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(plaintext.getBytes());
}
/**
* @param ciphertext 密文
* @param privateKey 私钥
* @return 明文
* @throws Exception 异常
*/
public static String decryptRSA(byte[] ciphertext, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(ciphertext);
return new String(decryptedBytes);
}
}
代码注意:
每次用公钥加密后,结果是不一致的,主要是在明文填充的时候有随机数验证算法的正确性:将生的私钥 copy,解密公加密结果,如果与最初的明文一致,则说明RSA算法运算正确!
标签:算法,公钥,加密,RSA,Java,密钥,私钥,非对称 From: https://blog.51cto.com/u_16356983/8371468