RSA 加解密 1024 位 2048 位
生活随笔
收集整理的這篇文章主要介紹了
RSA 加解密 1024 位 2048 位
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
RSA 算法是一種非對稱加密算法,會生成一對 RSA 秘鑰,即公鑰+私鑰,將公鑰提供給調用方,調用方使用公鑰對數據進行加密后,接口根據私鑰進行解密
RSA 加解密工具類
import java.io.ByteArrayOutputStream; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.Date; import java.util.HashMap; import?java.util.Map; import?javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;public class RSAUtil {public?static?final?String?KEY_ALGORITHM?=?"RSA";private static final String PUBLIC_KEY = "RSAPublicKey";private static final String PRIVATE_KEY = "RSAPrivateKey";/*** RSA最大加密明文大小*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** RSA最大解密密文大小*/private static final int MAX_DECRYPT_BLOCK = 128;/*** 生成密鑰對*/public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//設置密鑰對的bit數 越大越安全keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();//獲取公鑰RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//獲取私鑰RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}/*** 獲取公鑰字符串*/public static String getPublicKeyStr(Map<String, Object> keyMap) throws Exception {//獲得map中的公鑰對象 轉為key對象Key key = (Key) keyMap.get(PUBLIC_KEY);//編碼返回字符串return encryptBASE64(key.getEncoded());}/*** 獲得私鑰字符串*/public static String getPrivateKeyStr(Map<String, Object> keyMap) throws Exception {//獲得map中的私鑰對象 轉為key對象Key key = (Key) keyMap.get(PRIVATE_KEY);//編碼返回字符串return encryptBASE64(key.getEncoded());}/*** 獲取公鑰*/public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException {byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PublicKey publicKey = keyFactory.generatePublic(keySpec);return publicKey;}/*** 獲取私鑰*/public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** BASE64解碼 返回字節數組* key 需要解碼的字符串*/public static byte[] decryptBASE64(String key) {return Base64.getDecoder().decode(key);}/*** BASE64編碼返回加密字符串* key 需要編碼的字節數組*/public static String encryptBASE64(byte[] key) throws Exception {return new String(Base64.getEncoder().encode(key));}/*** 公鑰加密*/public?static?String?encrypto(String?text,?String?publicKeyStr)?{try?{System.out.println("明文lenth為"+text.length());Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyStr));byte tempBytes[] = cipher.doFinal(text.getBytes());String secretText = Base64.getEncoder().encodeToString(tempBytes);return secretText;} catch (Exception e) {throw new RuntimeException("加密字符串[" + text + "]時遇到異常", e);}}/*** 私鑰解密** @param secretText*/public?static?String?decrypto(String?secretText,?String?privateKeyStr)?{try {//生成公鑰Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr));// 密文解碼byte[] secretText_decode = Base64.getDecoder().decode(secretText.getBytes());byte tempBytes[] = cipher.doFinal(secretText_decode);String text = new String(tempBytes);return text;} catch (Exception e) {throw new RuntimeException("解密字符串[" + secretText + "]時遇到異常", e);}}public static void main(String[] args) throws Exception {Map<String, Object> keyMap;String cipherText;String input = "數字測試就是多久覅偶按實際說就大佛我按時間覅哦啊師傅歐艾斯師傅到了獨愛偶素大放";try {keyMap = initKey();String publicKey = getPublicKeyStr(keyMap);System.out.println("公鑰------------------");System.out.println(publicKey);System.out.println("length: " + publicKey.length());String privateKey = getPrivateKeyStr(keyMap);System.out.println("私鑰------------------");System.out.println(privateKey);System.out.println("length: " + privateKey.length())cipherText = encrypto(input, publicKey);//加密后的東西System.out.println("密文=======" + cipherText);System.out.println("length: " + cipherText.length());//開始解密String plainText = decrypto(cipherText, privateKey);System.out.println("解密后明文=====?"?+?plainText);} catch (Exception e) {e.printStackTrace();}} }如果所示, 生成一對1024 bit 的 RSA 密鑰對,并加解密成功。
報文長度過長加解密失敗
測試發現當明文過長時,加密異常,返回如下報錯
原因
RSA 加解密時,對加密的數據大小有限制,最大不大于密鑰長度。
在使用 1024 位的密鑰時,最大可以加密 1024/8 = 128字節的數據,此時需要對數據進行分組加密,分組加密后的加密串拼接成一個字符串返回給客戶端。如果 Padding 方式使用默認的 OPENSSL_PKCS1_PADDING(需要占用11字節用于填充),則明文長度最多為 128 - 11 = 117 Bytes
同理當解密的密文超過128Byte時,也需要進行分組解密
分段加解密
/** * 分段加密 */ public static String encrypt(String plainText, String publicKeyStr) throws Exception {System.out.println("明文lenth為"+plainText.length());byte[] plainTextArray = plainText.getBytes();PublicKey publicKey = getPublicKey(publicKeyStr);Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, publicKey);int inputLen = plainTextArray.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;int i = 0;byte[] cache;while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(plainTextArray, offSet, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(plainTextArray, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] encryptText = out.toByteArray();out.close();return Base64.getEncoder().encodeToString(encryptText);}/*** 分段解密*/public static String decrypt(String encryptTextHex, String privateKeyStr) throws Exception {byte[] encryptText = Base64.getDecoder().decode(encryptTextHex);PrivateKey privateKey = getPrivateKey(privateKeyStr);Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, privateKey);int inputLen = encryptText.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 對數據分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(encryptText, offSet, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(encryptText, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] plainText = out.toByteArray();out.close();return new String(plainText); }當密鑰對為 2048 bit
如上文提到, 當密鑰對改為 2048 位時, 最大加密明文大小 = 2048(bit) / 8 - 11(byte) = 245 byte
/** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 245;/** * RSA最大解密密文大小 */ private?static?final?int?MAX_DECRYPT_BLOCK?=?256;/** * 生成密鑰對*/ public?static?Map<String,?Object>?initKey()?throws?Exception?{KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//設置密鑰對的bit數 越大越安全keyPairGen.initialize(2048);KeyPair keyPair = keyPairGen.generateKeyPair();//獲取公鑰RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//獲取私鑰RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return?keyMap; }附
PKCS1 和 PKCS8 的區別
PKCS#1格式
PKCS#8格式
通常JAVA中需要PKCS8 格式的密鑰
在線 RSA 加解密網站
https://www.toolscat.com/decode/rsasource ://blog.csdn.net/qq_34890544/article/details/122394379記得點「贊」和「在看」↓
愛你們
總結
以上是生活随笔為你收集整理的RSA 加解密 1024 位 2048 位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java统计代码行数
- 下一篇: oracle32 plsql,32位pl