目录
前言
一、什么是RSA?
二、RSA加密的基本概念
1.非对称加密
2.密钥生成
3.加密和解密
三、RSA加密的工作原理
四、RSA的应用场景
五、RSA加密解密的实现
六、RSA算法的局限性及改进措施
前言
在当今的数字化时代,信息的安全性成为了人们关注的重点。如何在不安全的通信网络上确保数据传输的安全性?RSA加密算法就是一种非常经典的公钥密码体制,它的安全性和高效性使其成为互联网加密的基石。本文将对RSA加密算法进行详细解读,带大家了解其原理、实现过程以及应用场景。
一、什么是RSA?
RSA(Rivest-Shamir-Adleman)加密算法是一种非对称加密算法,由罗纳德·里维斯特(Ronald Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)于1977年提出。RSA算法基于数论中的大素数分解难题,其安全性依赖于将一个大数分解成两个大素数的难度。
二、RSA加密的基本概念
1.非对称加密
非对称加密使用一对密钥:公钥(public key)和私钥(private key)。公钥用于加密消息,私钥用于解密消息。这意味着,即使公钥被公开,只有拥有私钥的人才能解密消息。
2.密钥生成
RSA算法涉及三个主要步骤:密钥生成、加密和解密。
-
选择两个大素数 ( p ) 和 ( q ):
这两个素数应随机选择且足够大,以确保安全性。
-
计算 ( n ) 和 ( \phi(n) ):
( n = p \times q )
( \phi(n) = (p-1) \times (q-1) ),其中 ( \phi ) 是欧拉函数。
-
选择公钥指数 ( e ):
( e ) 应满足 ( 1 < e < \phi(n) ) 且与 ( \phi(n) ) 互质。
-
计算私钥指数 ( d ):
( d ) 是 ( e ) 关于模 ( \phi(n) ) 的乘法逆元,即 ( d \times e \equiv 1 \mod \phi(n) )。
公钥由 ( (e, n) ) 组成,私钥由 ( (d, n) ) 组成。
3.加密和解密
-
加密:给定消息 ( M ),使用公钥 ( (e, n) ) 进行加密得到密文 ( C ): [ C = M^e \mod n ]
-
解密:使用私钥 ( (d, n) ) 进行解密得到明文 ( M ): [ M = C^d \mod n ]
三、RSA加密的工作原理
RSA加密的核心在于大素数的选取和运算的复杂性。以下是详细的步骤:
-
密钥生成:
选择两个大素数 ( p ) 和 ( q )。
计算 ( n = p \times q )。
计算 ( \phi(n) = (p-1) \times (q-1) )。
选择公钥指数 ( e ),使其与 ( \phi(n) ) 互质。
计算私钥指数 ( d ),使 ( d \times e \equiv 1 \mod \phi(n) )。
-
加密:
将明文消息 ( M ) 转换为整数形式。
计算密文 ( C = M^e \mod n )。
-
解密:
使用私钥 ( d ) 解密,计算 ( M = C^d \mod n )。
四、RSA的应用场景
数据加密
RSA常用于保护敏感信息的传输。例如,在HTTPS中,RSA用于交换对称密钥,从而保护数据传输的安全性。
数字签名
RSA还能用于创建数字签名,验证消息的完整性和发送者的身份。发送者使用私钥对消息签名,接收者用公钥验证签名是否正确。
证书颁发机构(CA)
RSA广泛应用于数字证书,证书颁发机构(CA)使用RSA生成和验证数字证书,确保通信双方的身份真实性。
五、RSA加密解密的实现
package com.ctb.demo;import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class RSADemo {private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //用于封装随机产生的公钥与私钥/** * 随机生成密钥对 * @throws NoSuchAlgorithmException */ public static void genKeyPair() throws NoSuchAlgorithmException { // KeyPairGenerator类用于生成公钥和私钥对,获取一个RSA密钥对生成器实例,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,密钥大小为96-1024位,指定密钥的长度为1024位//SecureRandom类提供的随机数生成器生成随机数作为种子keyPairGen.initialize(1024,new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥 //得到公钥字符串String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded())); // 得到私钥字符串 String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded()))); // 将公钥和私钥保存到MapkeyMap.put(0,publicKeyString); //0表示公钥keyMap.put(1,privateKeyString); //1表示私钥System.out.println("公钥"+publicKeyString);System.out.println("私钥"+privateKeyString);} /** * RSA公钥加密 * * @param str * 加密字符串* @param publicKey * 公钥 * @return 密文 * @throws Exception * 加密过程中的异常信息 */ public static String encrypt( String str, String publicKey ) throws Exception{//通过Base64类对公钥字符串进行解码,得到原始的字节数组//base64编码的公钥byte[] decoded = Base64.getDecoder().decode(publicKey);//通过KeyFactory.getInstance("RSA")获取RSA密钥工厂实例,//并使用generatePublic()方法根据解码后的字节数组生成RSA公钥对象RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));//RSA加密,获取RSA加密算法的密码器实例Cipher cipher = Cipher.getInstance("RSA");//初始化密码器,指定加密模式为Cipher.ENCRYPT_MODE,并传入公钥对象cipher.init(Cipher.ENCRYPT_MODE, pubKey);//使用cipher.doFinal()方法对输入字符串进行加密操作,得到加密后的字节数组//通过Base64类对加密后的字节数组进行编码,并将编码后的字符串返回String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));return outStr;}/** * RSA私钥解密* * @param str * 加密字符串* @param privateKey * 私钥 * @return 铭文* @throws Exception * 解密过程中的异常信息 */ public static String decrypt(String str, String privateKey) throws Exception{//通过Base64类对加密后的字符串进行解码,得到原始的字节数组//64位解码加密后的字符串byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8"));//base64编码的私钥//通过Base64类对私钥字符串进行解码,得到原始的字节数组byte[] decoded = Base64.getDecoder().decode(privateKey); //通过KeyFactory.getInstance("RSA")获取RSA密钥工厂实例,//并使用generatePrivate()方法根据解码后的字节数组生成RSA私钥对象RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 获取RSA解密算法的密码器实例Cipher cipher = Cipher.getInstance("RSA");//初始化密码器,指定解密模式为Cipher.DECRYPT_MODE,并传入私钥对象cipher.init(Cipher.DECRYPT_MODE, priKey);//使用cipher.doFinal()方法对输入字节数组进行解密操作,得到解密后的字节数组//将解密后的字节数组转换为字符串,并返回解密后的明文。String outStr = new String(cipher.doFinal(inputByte));return outStr;}public static void main(String[] args) throws Exception {//生成公钥和私钥genKeyPair();//加密字符串String message = "123";System.out.println("随机生成的公钥为:" + keyMap.get(0));System.out.println("随机生成的私钥为:" + keyMap.get(1));System.out.println("----------------------------");String messageEn = encrypt(message,keyMap.get(0));System.out.println(message + "\t加密后的字符串为:" + messageEn);String messageDe = decrypt(messageEn,keyMap.get(1));System.out.println("还原后的字符串为:" + messageDe);//MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2ocAG/DBOxQRIWDVpo79jjst9Aakcna7dfKugQI4SfjApVYXJdLmk6UU4VPERMb//MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALahwAb8ME7FBEhYNWmjv2OOy30BqRydrt18q6BAjhJ+MClSystem.out.println(messageEn.length());}}
结果:
六、RSA算法的局限性及改进措施
尽管RSA算法在加密领域有着广泛的应用,但也存在一些局限性。例如,随着计算能力的提升,大质数的分解变得越来越容易,这可能导致RSA算法的安全性受到威胁。为了应对这些挑战,大佬提出了许多改进措施,比如使用更长的密钥长度、采用椭圆曲线加密算法等。