非對稱加密演算法(2):RSA
阿新 • • 發佈:2019-02-13
一.RSA:RSA公鑰加密演算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美國公佈,當時他們三人都在麻省理工學院工作實習。RSA就是他們三人姓氏開頭字母拼在一起組成的。
RSA演算法基於一個十分簡單的數論事實:將兩個大質數相乘十分容易,但是想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密金鑰。
二.優缺點:
1)產生金鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。 2)安全性,RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難度與大數分解難度等價,而且密碼學界多數人士傾向於因子分解不是NP問題。 3)速度太慢,由於RSA 的分組長度太大,為保證安全性,n 至少也要 600 bits以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利於資料格式的標準化。SET(Secure Electronic Transaction)協議中要求CA採用2048位元長的金鑰,其他實體使用1024位元的金鑰。為了速度問題,人們廣泛使用單,三.實現過程:
四.具體的實現程式碼(java):
import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; 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 javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.apache.commons.codec.binary.Base64; /** * 使用 RSA 演算法對資料進行加解密 * @author wsy */ public class RSA { static String src = "歐陽草帽"; public static void main(String[] args) throws Exception { //初始化祕鑰 KeyPair keyPair = getKeyPair(); RSAPublicKey rsaPublicKey = getPublicKey(keyPair); RSAPrivateKey rsaPrivateKey = getPrivateKey(keyPair); //私鑰加密,公鑰解密 ---- 加密 byte[] result = encryptedByPublic(rsaPrivateKey,src); System.out.println("加密結果:"+Base64.encodeBase64String(result)); //私鑰加密,公鑰解密 ---- 解密 result = decryptByPrivate(rsaPublicKey, result); System.out.println("解密結果:"+new String(result)); //公鑰加密,公私鑰解密 ---- 加密 result = encryptByPrivate(rsaPublicKey, src); System.out.println("加密結果 :"+Base64.encodeBase64String(result)); //公鑰加密,公私鑰解密 ---- 解密 result = decryptByPublic(rsaPrivateKey, result); System.out.println("解密結果:"+new String(result)); } /** * 私鑰加密,公鑰解密 --- 解密 * @param rsaPrivateKey * @param encryptBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public static byte[] decryptByPublic(RSAPrivateKey rsaPrivateKey, byte[] encryptBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] result = cipher.doFinal(encryptBytes); // 解密結果 return result; } /** * 私鑰加密,公鑰解密 --- 加密 * @param rsaPublicKey * @param src * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public static byte [] encryptByPrivate(RSAPublicKey rsaPublicKey, String src) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] result = cipher.doFinal(src.getBytes()); //加密結果 return result; } /** * 公鑰加密,私鑰解密 --- 解密 * @param rsaPublicKey * @param encryptBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public static byte[] decryptByPrivate(RSAPublicKey rsaPublicKey, byte[] encryptBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] result = cipher.doFinal(encryptBytes); //解密結果 return result; } /** * 公鑰加密,私鑰解密 --- 加密 * @param rsaPrivateKey * @param src * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public static byte[] encryptedByPublic(RSAPrivateKey rsaPrivateKey,String src) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte [] result = cipher.doFinal(src.getBytes()); // 加密結果 return result; } /** * 獲取私鑰 * @param keyPair * @return */ public static RSAPrivateKey getPrivateKey(KeyPair keyPair) { RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); return rsaPrivateKey; } /** * 獲取公鑰 * @param keyPair * @return */ public static RSAPublicKey getPublicKey(KeyPair keyPair) { RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); return rsaPublicKey; } private static KeyPair getKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair; } }