RSA
RSA加解密是一种非对称加密算法,由三位数学家Rivest、Shamir和Adleman于1977年提出。它的概念是基于两个密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据。
RSA算法的原理
RSA算法的原理基于数论中的两个重要问题:大数分解和模幂运算。其核心思想是选择两个大素数p和q,计算它们的乘积n=p*q,并选择一个整数e作为公钥,满足e与(p-1)(q-1)互质。然后,计算私钥d,使得e*d ≡ 1 (mod (p-1)(q-1))。公钥是(n, e),私钥是(n, d)。
加密过程中,将明文m转换为整数M,然后使用公钥对M进行加密,得到密文C。加密操作为C ≡ M^e (mod n)。解密过程中,使用私钥对密文C进行解密,得到明文m。解密操作为m ≡ C^d (mod n)。
优点
RSA算法的优点是安全性高,能够提供可靠的数据加密和解密。它的缺点是加密和解密的速度相对较慢,尤其是对于大数据量的处理。
应用场景
RSA算法在实际应用中广泛使用,包括数字签名、密钥交换、安全通信等领域。它可以用于保护敏感信息的传输和存储,确保数据的机密性和完整性。
代码示例
首先,生成RSA密钥对,然后使用公钥对明文进行加密,再使用私钥对密文进行解密。最后,输出解密后的明文
import javax.crypto.Cipher; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Base64; public class RSAExample { /** * 创建密钥规范 */ public static final String RSA_KEY = "RSA"; public static void main(String[] args) throws Exception { //注:这里加密解密要用同一个 一对存在 KeyPair keyPair = keyPairInit(); Cipher cipher = Cipher.getInstance(RSA_KEY); // 明文 String plainText = "Hello, RSA!"; System.out.println("明文: " + plainText); // 加密 PublicKey publicKey = keyPair.getPublic(); cipher.init(Cipher.ENCRYPT_MODE, publicKey); String encode = encode(plainText, cipher); System.out.println("加密后: " + encode); // 解密 PrivateKey privateKey = keyPair.getPrivate(); cipher.init(Cipher.DECRYPT_MODE, privateKey); String decode = decode(encode, cipher); System.out.println("解密后: " + decode); } /** * 生成RSA密钥对 * * @return * @throws Exception */ public static KeyPair keyPairInit() throws Exception { // 生成RSA密钥对 KeyPairGenerator instance = KeyPairGenerator.getInstance(RSA_KEY); KeyPair keyPair = instance.generateKeyPair(); return keyPair; } /** * 加密 * * @param plainText 明文 * @return * @throws Exception */ public static String encode(String plainText, Cipher cipher) throws Exception { byte[] encryptedBytes = cipher.doFinal(plainText.getBytes()); String encode = Base64.getEncoder().encodeToString(encryptedBytes); return encode; } /** * 解密 * * @param encrypted 密文 * @return * @throws Exception */ public static String decode(String encrypted, Cipher cipher) throws Exception { byte[] decode = Base64.getDecoder().decode(encrypted); byte[] decryptedBytes = cipher.doFinal(decode); return new String(decryptedBytes); } }
RSA公钥和私钥的生成(.asc)
RSA公钥和私钥的生成可以使用Java的密钥对生成器(KeyPairGenerator)来实现。具体步骤如下:
- 使用KeyPairGenerator.getInstance("RSA")获取一个RSA密钥对生成器实例。
- 使用generateKeyPair方法生成密钥对,该方法返回一个KeyPair对象。
- 从生成的KeyPair对象中分别获取公钥和私钥,并将它们保存到文件中。
代码示例
第一种
生成RSA公钥和私钥:
import java.io.FileOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; public class RSAGenerator { public static void main(String[] args) throws Exception { // 创建RSA密钥对生成器对象 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,指定密钥长度为1024位 kpg.initialize(1024); // 生成RSA密钥对 KeyPair keyPair = kpg.generateKeyPair(); // 获取公钥和私钥 PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); // 保存公钥和私钥到文件中 saveKeyToFile("public.key", publicKey.getEncoded()); saveKeyToFile("private.key", privateKey.getEncoded()); System.out.println("RSA公钥和私钥已生成并保存到文件中!"); } /** * 将密钥保存到文件中 * * @param fileName * @param keyBytes * @throws Exception */ public static void saveKeyToFile(String fileName, byte[] keyBytes) throws Exception { FileOutputStream fos = new FileOutputStream(fileName); fos.write(keyBytes); fos.close(); } }
生成.asc文件
运行该程序后,将会生成一个名为public.key的文件和一个名为private.key的文件,其中public.key文件保存公钥,private.key文件保存私钥。这两个文件的格式为二进制格式,如果需要以.asc文件的形式保存,可以使用如下命令将其转换:
$ openssl rsa -in private.key -outform PEM -out private.asc $ openssl rsa -in public.key -outform PEM -out public.asc
这将把private.key和public.key转换为private.asc和public.asc文件,其中private.asc和public.asc文件就是RSA私钥和公钥的.asc形式。
第二种:
生成RSA密钥对并保存为.pem和.der文件
import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.io.FileOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; public class RSAKeyPairGenerator { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // Generate RSA key pair KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC"); generator.initialize(2048); KeyPair keyPair = generator.generateKeyPair(); // Save private key as .pem file try (FileOutputStream privateKeyFile = new FileOutputStream("private_key.pem")) { privateKeyFile.write(keyPair.getPrivate().getEncoded()); } // Save public key as .der file try (FileOutputStream publicKeyFile = new FileOutputStream("public_key.der")) { publicKeyFile.write(keyPair.getPublic().getEncoded()); } System.out.println("RSA key pair generated and saved successfully."); } }
注:依赖
<dependencies> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.68</version> </dependency> </dependencies> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.68</version> </dependency>