RSA加密算法原理及其Java实现

RSA加密算法原理及其Java实现简单介绍了 RSA 加密算法的原理及其 Java 实现 原文过长时 进行了分段加密 RSA 加密算法的基本原理主要步骤本文所有的字母都为正整数 其主要步骤如下 1 取两个不相等的质数 p q 一般都比较大 例如 p 67 q 79 2 n p q 其中 n 所对应的二进制长度即为密钥的长度 一般为 1024 位或 2048 位 n 67 79 5293 转化为二进制数为 01 共 13 位 3 计算 n 的欧拉函数 f

简单介绍了RSA加密算法的原理及其Java实现:原文过长时,进行了分段加密。

RSA加密算法的基本原理

主要步骤

BigInteger num1 = new BigInteger("65"); BigInteger num2 = new BigInteger("5293"); BigInteger b = num1.pow(19).mod(num2); System.out.println(b); System.out.println("普通的整数运算是错误的:"+Math.pow(65, 19)%5293); BigInteger a = b.pow(271).mod(num2); System.out.println(a); // 输出为: 1863 普通的整数运算是错误的:4055.0 65 

解密过程证明

java实现

package mytest; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import javax.crypto.Cipher; public class RSAUtil { 
     // 密钥长度,可调 public static int keyLength = 1025; // 注意这里1024对应128byte,其中11byte用来存储相关信息,所以1024最多加密117Byte数据 // 若超过117Byte需要分段,计算公式为keyLength/8并向上取整再减去11 // 解密时候长度为keyLength/8向上取整 // 存储密钥 public static Map<String, String> keyMap = new HashMap<String, String>(); public static void main(String[] args) throws Exception { 
     //生成公钥和私钥 geneKeyPair(); // 输入原文 System.out.print("输入原文:"); Scanner in = new Scanner(System.in); String message = in.nextLine(); //String message = "1aa"; System.out.println("随机生成的公钥为:" + keyMap.get("publicKey")); System.out.println("随机生成的私钥为:" + keyMap.get("privateKey")); //加密字符串 String messageEnctypt = encrypt(message, keyMap.get("publicKey")); System.out.println("原文:"+message + "\n加密后的字符串为:" + messageEnctypt); String messageDecrypt = decrypt(messageEnctypt, keyMap.get("privateKey")); System.out.println("还原后的字符串为:" + messageDecrypt); in.close(); } / * function:随机生成密钥对并存放在keyMap中 * 也可以直接保存RSAPublicKey对象和RSAPrivateCrtKey对象 * 一般情况下密钥可能会保存在本地或者其他地方,然后直接读取密钥,这时候存储的一般是密钥字符串 * @throws NoSuchAlgorithmException */ public static void geneKeyPair() throws NoSuchAlgorithmException { 
     // RSA密钥生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); // 初始化密钥生成器 keyPairGenerator.initialize(keyLength, new SecureRandom()); // 生成密钥对并保存 KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 公钥 RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) keyPair.getPrivate(); // 私钥 String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded()); // 公钥字符串 String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded()); // 私钥字符串 // 存放 keyMap.put("publicKey", publicKeyString); keyMap.put("privateKey", privateKeyString); } /* * function:加密 * @param 明文 * @param 公钥字符串,十六进制字符串 * @return 密文 * @throws Exception */ public static String encrypt(String input, String publicKeyString) throws Exception { 
     // 从字符串获取公钥 byte[] decoded = Base64.getDecoder().decode(publicKeyString.getBytes()); RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); // 加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] inputArr = input.getBytes(); StringBuilder output = new StringBuilder(); int splitLength = (int) Math.ceil((float)keyLength/8) - 11; // 分段长度 for(int i = 0; i < inputArr.length; i += splitLength) { 
     // 分段加密 int len = inputArr.length-i >= splitLength ? splitLength : inputArr.length-i; output.append(byteArray2HexString(cipher.doFinal(Arrays.copyOfRange(inputArr, i, i+len)))); } return output.toString(); } /* * function:私钥解密 * @param 密文 * @param 私钥字符串 * @return 明文 * @throws Exception */ public static String decrypt(String input, String privateKeyString) throws Exception { 
     // 从字符串获取私钥 byte[] decoded = Base64.getDecoder().decode(privateKeyString.getBytes()); RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); // 解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); int splitLength = (int) Math.ceil((float)privateKey.getModulus().bitLength()/8); // 分段长度 byte[] inputArr = hexString2byteArray(input); StringBuilder output = new StringBuilder(); for(int i = 0; i < inputArr.length; i += splitLength) { 
     // 分段解密 int len = inputArr.length-i >= splitLength ? splitLength : inputArr.length-i; output.append(new String(cipher.doFinal(Arrays.copyOfRange(inputArr, i, i+len)))); } return output.toString(); } public static int getKeyLength() { 
     return keyLength; } /* * function:设置密钥长度 */ public static void setKeyLength(int keyLength) { 
     // RSA keys must be at least 512 bits long if(keyLength < 512) { 
     keyLength = 512; } RSAUtil.keyLength = keyLength; } /* * function:byte[]转换为十六进制字符串 * byte占8位,可以用两位16进制数表示 * @param byte[] * @return String */ public static String byteArray2HexString(byte[] bytes) { 
     StringBuilder output = new StringBuilder(); String temp; for(byte b : bytes) { 
     temp = Integer.toHexString(0xff & b); if(temp.length() == 1) { 
     output.append(0); } output.append(temp); } return output.toString(); } /* * function:十六进制字符串转换位byte[] * @param String * @return byte[] */ public static byte[] hexString2byteArray(String hexString) { 
     int len = hexString.length() / 2; byte[] output = new byte[len]; for(int i = 0; i < len; i++) { 
     int pos = i * 2; output[i] = (byte) (char2Byte(hexString.charAt(pos)) << 4 | char2Byte(hexString.charAt(pos+1))); } return output; } /* * function: char转换位byte,这里的char只包含0abcdef * @param char * @return byte */ private static byte char2Byte(char c) { 
     byte b = (byte)"0abcdef".indexOf(c); return b; } } 

测试结果:

输入原文:sadjhfkkjasdghjkhadkjsdhgksdhgjkshgdweuosyhjkhfsdg5sd4g5s4dg1564h56d4as1gd521f56a1sa3f54a654g5s6d41fg56ha456sd41f23g1h5a6s4dg1gf2asd5g45 随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo+UfWVK/CQVayLR5DRy9ydyahLUjr0Eq4xD6pXmMouNWgSjWkiEiQ2eWE3RfAVI89qGYwvD76VvBd+uO9lMLZmh3aVk+Iu0ajTwEt4UxI3T3oGpirYYHWIBHNmcKrRyuGPpQZd+klNzzJeiS+/4Ee5mOPEKun5kJs33D61o4kKwIDAQAB 随机生成的私钥为:MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKj5R9ZUr8JBVrItHkNHL3J3JqEtSOvQSrjEPqleYyi41aBKNaSISJDZ5YTdF8BUjz2oZjC8PvpW8F36472UwtmaHdpWT4i7RqNPAS3hTEjdPegamKthgdYgEc2ZwqtHK4Y+lBl36SU3PMl6JL7/gR7mY48Qq6fmQmzfcPrWjiQrAgMBAAECgYBZKkodMM0abc4o8aQRjoPcHEH3NWVQgrabb3s9dsBOodKg5egOrZfVUBZMmTrKVBTOTYm3V+7HvY7TmOwKg3CZ9UzxYrhhIbh7p42gAIlpnyiq7YCz3X0hz+FrRKEOJJ5eLINKxl6w3jOG1ZeY9FIHUrGIb0KJe/a5m1gkG8zFoQJBAN0zS/DPpDNJKCrnxRs1TijtLdL9JgOle7ecPKp2kbJQB6RLmJ5/675JrlR1SD5N9E4KUdgEsyF4uUr3cew6XlsCDDjpcTHn3wgjZOGU8WAuNHV132TSfT1YiCttFjRuXNtGVrmYdbyZh77g6qbk+DxjJ1Zw0dNh1WhsGyLOTCI9pxAkAJxW1SWunG9jFXC9vyIr2sIyYGDvax7Ip1hupLIWe4N77OrCQ2xDHWuwx/YJrrXagwFladMz/yd5G/1QRsSfvHAkB50wuEapt0R/oCnzuob7YczG2Jsbkc+0pme/NnUFR62GXSKTusz6LBmaTjQYMhiUgH4WHHD94o+BwUnmkIFIPRAkAr5ToL9zeevlwYvIxqd4++Vdcfm+1uDbxa0Rjm00ay5S3fS/3jXHs0j+CB2faxakVUYueMKmdUoYpWKfgOOk7A 原文:sadjhfkkjasdghjkhadkjsdhgksdhgjkshgdweuosyhjkhfsdg5sd4g5s4dg1564h56d4as1gd521f56a1sa3f54a654g5s6d41fg56ha456sd41f23g1h5a6s4dg1gf2asd5g45 加密后的字符串为:9186b953a69941d47b35e0abff66356c03b29e3b0be1b1187f845fd212f2bf14e9fe56484fd5b15b23782dbb6cb1a7a6f2854e81f89c20216b5e15cf9bc17224f1820fece0adf10eba16d130dd63885b6ede13ae2493f1eeaaee35e67fdcddabd85eefc1613ce132c731d6be0d34e00c7ed04a6a0c8b695a0fde47ecd60023cf223ac5b70c047c9c6b155ecbdb13ffcb8a2a4d029b3cdd2de9b1cbf1729e5ddcdfc6db93a593b8e1f38c70dc064147a3d6ffaf9a21d338fa5d9a676a9449e37c8d9446abea15f1dfc 还原后的字符串为:sadjhfkkjasdghjkhadkjsdhgksdhgjkshgdweuosyhjkhfsdg5sd4g5s4dg1564h56d4as1gd521f56a1sa3f54a654g5s6d41fg56ha456sd41f23g1h5a6s4dg1gf2asd5g45 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/176143.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午10:37
下一篇 2026年3月26日 下午10:37


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号