非對稱加密RSA算法Java實現
package com.test.rsa;import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom;
import javax.crypto.Cipher;
public class RSAUtil {
/** * 加密 */ public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, pk); int blockSize = cipher.getBlockSize();// 獲得加密塊大小,如:加密前數據為128個byte,而key_size=1024 // 加密塊大小為127 // byte,加密后為128個byte;因此共有2個加密塊,第一個127 // byte第二個為1個byte int outputSize = cipher.getOutputSize(data.length);// 獲得加密塊加密后塊大小 int leavedSize = data.length % blockSize; int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize; byte[] raw = new byte[outputSize * blocksSize]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize); else cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize); // 這里面doUpdate方法不可用,查看源代碼后發現每次doUpdate后并沒有什么實際動作除了把byte[]放到 // ByteArrayOutputStream中,而最后doFinal的時候才將所有的byte[]進行加密,可是到了此時加密塊大小很可能已經超出了 // OutputSize所以只好用dofinal方法。 i++; } return raw; } catch (Exception e) { throw new Exception(e.getMessage()); } } /** * 解密 */ public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(cipher.DECRYPT_MODE, pk); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (raw.length - j * blockSize > 0) { bout.write(cipher.doFinal(raw, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { throw new Exception(e.getMessage()); } } /** * * 根據本地的RSAKey文件獲取KeyPair * * @throws Exception */ public static KeyPair getKeyPair(String rsaKeyStore) throws Exception { FileInputStream fis = new FileInputStream(rsaKeyStore); ObjectInputStream oos = new ObjectInputStream(fis); KeyPair kp = (KeyPair) oos.readObject(); oos.close(); fis.close(); return kp; } /** * * 存儲KeyPair到本地 * * @throws Exception */ public static void saveKeyPair(KeyPair kp, String path) throws Exception { FileOutputStream fos = new FileOutputStream(path); ObjectOutputStream oos = new ObjectOutputStream(fos); // 生成密鑰 oos.writeObject(kp); oos.close(); fos.close(); } /** * * 用于生成公匙或私匙 * * @throws NoSuchAlgorithmException * */ public static KeyPair generateKeyPair() throws NoSuchAlgorithmException { SecureRandom sr = new SecureRandom(); KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 注意密鑰大小最好為1024,否則解密會有亂碼情況. kg.initialize(1024, sr); KeyPair genKeyPair = kg.genKeyPair(); return genKeyPair; } /** * * 測試 * */ public static void main(String[] args) throws Exception { // 獲取公匙及私匙 KeyPair generateKeyPair = getKeyPair("E:\\code\\key"); //生成公鑰及私鑰 //KeyPair generateKeyPair = generateKeyPair(); // 公匙 用于前臺加密 PublicKey publicKey = generateKeyPair.getPublic(); System.out.println(publicKey); // 私匙 存儲在后臺用于解密 PrivateKey privateKey = generateKeyPair.getPrivate(); System.out.println(privateKey); // 存儲KeyPair到本地用于后期解密 注意修改前臺RSAKeyPair //saveKeyPair(generateKeyPair,"E:\\code\\key"); // 測試加密解密 String test = "saaaa"; // test = "阿斯頓發送對發生地發送盜伐水電費圣達菲sadfsadf愛上對方愛上對方"; byte[] en_test = encrypt(publicKey, test.getBytes()); System.out.println("加密后字符:" + new String(en_test)); byte[] de_test = decrypt(privateKey, en_test); System.out.println("解密后字符:" + new String(de_test)); }
} </pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!