JAVA——RSA加密【X509EncodedKeySpec、PKCS8EncodedKeySpec、RSAPublicKeySpec、RSAPrivateKeySpec】
基本概念
RSA加密算法:RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業中RSA被廣泛使用。RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。
RSA是目前最有影響力的公鑰加密算法,該算法基于一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰,即公鑰,而兩個大素數組合成私鑰。公鑰是可發布的供任何人使用,私鑰則為自己所有,供解密之用。
解密者擁有私鑰,并且將由私鑰計算生成的公鑰發布給加密者。加密都使用公鑰進行加密,并將密文發送到解密者,解密者用私鑰解密將密文解碼為明文。
API
https://docs.oracle.com/javase/7/docs/api/index.html?
X509EncodedKeySpec:
- 該類表示公鑰的ASN.1編碼,根據ASN.1類型SubjectPublicKeyInfo進行編碼。 SubjectPublicKeyInfo語法在X.509標準中定義如下: SubjectPublicKeyInfo ::= SEQUENCE {algorithm AlgorithmIdentifier,subjectPublicKey BIT STRING }
?
| 構造方法: X509EncodedKeySpec(byte[]?encodedKey) 用給定的編碼密鑰創建一個新的X509EncodedKeySpec。 ? 參數 encodedKey - 假定按照X.509標準編碼的密鑰。 復制數組的內容以防止后續修改。 異常 NullPointerException - 如果 encodedKey為空。 |
PKCS8EncodedKeySpec:
- 該類代表私有密鑰的ASN.1編碼,根據ASN.1類型PrivateKeyInfo進行編碼。 PrivateKeyInfo語法在PKCS#8標準中定義如下: PrivateKeyInfo ::= SEQUENCE {version Version,privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,privateKey PrivateKey,attributes [0] IMPLICIT Attributes OPTIONAL }Version ::= INTEGERPrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifierPrivateKey ::= OCTET STRINGAttributes ::= SET OF Attribute
| 構造方法: PKCS8EncodedKeySpec(byte[]?encodedKey) 使用給定的編碼密鑰創建一個新的PKCS8EncodedKeySpec。 |
RSAPrivateKeySpec:
- 此類指定一個RSA私鑰。
| 構造方法: RSAPrivateKeySpec(BigInteger?modulus, BigInteger?privateExponent) 創建一個新的RSAPrivateKeySpec。 參數 modulus - 模數 privateExponent - 私人指數 |
RSAPublicKeySpec:
- 此類指定一個RSA公鑰。
| 構造方法: RSAPublicKeySpec(BigInteger?modulus, BigInteger?publicExponent) 創建一個新的RSAPublicKeySpec。 參數 modulus - 模數 publicExponent - 公眾指數 |
DEMO?
package cn.aizichan.utils.digest;import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map;import javax.crypto.Cipher;public class RSACoder {//非對稱密鑰算法 public static final String KEY_ALGORITHM="RSA"; /** * 密鑰長度,DH算法的默認密鑰長度是1024 * 密鑰長度必須是64的倍數,在512到65536位之間 * */ private static final int KEY_SIZE=512; //公鑰 private static final String PUBLIC_KEY="xiaoxiaorenzhe"; //私鑰 private static final String PRIVATE_KEY="dadapangzi"; /** * 初始化密鑰對 * @return Map 甲方密鑰的Map * */ public static Map<String,Object> initKey() throws Exception{ //實例化密鑰生成器 KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密鑰生成器 keyPairGenerator.initialize(KEY_SIZE); //生成密鑰對 KeyPair keyPair=keyPairGenerator.generateKeyPair(); //甲方公鑰 RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic(); System.out.println("系數:"+publicKey.getModulus()+" 加密指數:"+publicKey.getPublicExponent());//甲方私鑰 RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate(); System.out.println("系數:"+privateKey.getModulus()+"解密指數:"+privateKey.getPrivateExponent());//將密鑰存儲在map中 Map<String,Object> keyMap=new HashMap<String,Object>(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 私鑰加密 * @param data待加密數據 * @param key 密鑰 * @return byte[] 加密數據 * */ public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{ //取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成私鑰 PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec); //數據加密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公鑰加密 * @param data待加密數據 * @param key 密鑰 * @return byte[] 加密數據 * */ public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{ //實例化密鑰工廠 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //初始化公鑰 //密鑰材料轉換 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key); //產生公鑰 PublicKey pubKey=keyFactory.generatePublic(x509KeySpec); //數據加密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, pubKey); return cipher.doFinal(data); } /** * 私鑰解密 * @param data 待解密數據 * @param key 密鑰 * @return byte[] 解密數據 * */ public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{ //取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key); KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //生成私鑰 PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec); //數據解密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公鑰解密 * @param data 待解密數據 * @param key 密鑰 * @return byte[] 解密數據 * */ public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{ //實例化密鑰工廠 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //初始化公鑰 //密鑰材料轉換 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key); //產生公鑰 PublicKey pubKey=keyFactory.generatePublic(x509KeySpec); //數據解密 Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, pubKey); return cipher.doFinal(data); } /** * 取得私鑰 * @param keyMap 密鑰map * @return byte[] 私鑰 * */ public static byte[] getPrivateKey(Map<String,Object> keyMap){ Key key=(Key)keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 取得公鑰 * @param keyMap 密鑰map * @return byte[] 公鑰 * */ public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception{ Key key=(Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //初始化密鑰 //生成密鑰對 Map<String,Object> keyMap=RSACoder.initKey(); //公鑰 byte[] publicKey=RSACoder.getPublicKey(keyMap);//byte[] publicKey = b;//私鑰 byte[] privateKey=RSACoder.getPrivateKey(keyMap); System.out.println("公鑰:"+Base64.encode(publicKey)); System.out.println("私鑰:"+Base64.encode(privateKey)); System.out.println("================密鑰對構造完畢,甲方將公鑰公布給乙方,開始進行加密數據的傳輸============="); String str="aattaggcctegthththfef/aat.mp4"; System.out.println("===========甲方向乙方發送加密數據=============="); System.out.println("原文:"+str); //甲方進行數據的加密 byte[] code1=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);System.out.println("甲方 使用乙方公鑰加密后的數據:"+Base64.encode(code1)); System.out.println("===========乙方使用甲方提供的公鑰對數據進行解密=============="); //乙方進行數據的解密 //byte[] decode1=RSACoder.decryptByPublicKey(code1, publicKey); byte[] decode1=RSACoder.decryptByPrivateKey(code1, privateKey); System.out.println("乙方解密后的數據:"+new String(decode1)+""); System.out.println("===========反向進行操作,乙方向甲方發送數據=============="); str="乙方向甲方發送數據RSA算法"; System.out.println("原文:"+str); //乙方使用公鑰對數據進行加密 byte[] code2=RSACoder.encryptByPublicKey(str.getBytes(), publicKey); System.out.println("===========乙方使用公鑰對數據進行加密=============="); System.out.println("加密后的數據:"+Base64.encode(code2)); System.out.println("=============乙方將數據傳送給甲方======================"); System.out.println("===========甲方使用私鑰對數據進行解密=============="); //甲方使用私鑰對數據進行解密 byte[] decode2=RSACoder.decryptByPrivateKey(code2, privateKey); System.out.println("甲方解密后的數據:"+new String(decode2)); } }參考文章
https://www.iteye.com/topic/1148471
https://www.jianshu.com/p/40a1be871bee
https://blog.csdn.net/tabactivity/article/details/49685319
總結
以上是生活随笔為你收集整理的JAVA——RSA加密【X509EncodedKeySpec、PKCS8EncodedKeySpec、RSAPublicKeySpec、RSAPrivateKeySpec】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Eclipse——Maven项目工程无法
- 下一篇: JAVA——基于HttpClient的正