java RSA加密解密--转载
生活随笔
收集整理的這篇文章主要介紹了
java RSA加密解密--转载
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文地址:http://www.blogjava.net/icewee/archive/2012/05/19/378570.html
該工具類中用到了BASE64,需要借助第三方類庫:javabase64-1.3.1.jar
注意:
RSA加密明文最大長度117字節,解密要求密文最大長度為128字節,所以在加密和解密的過程中需要分塊進行。
RSA加密對明文的長度是有限制的,如果加密數據過大會拋出如下異常:
????at?com.sun.crypto.provider.RSACipher.a(DashoA13*..)
????at?com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
????at?javax.crypto.Cipher.doFinal(DashoA13*..)
RSAUtils.java
import?java.io.ByteArrayOutputStream;
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.Signature;
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;
/**
?*?<p>
?*?RSA公鑰/私鑰/簽名工具包
?*?</p>
?*?<p>
?*?羅納德·李維斯特(Ron?[R]ivest)、阿迪·薩莫爾(Adi?[S]hamir)和倫納德·阿德曼(Leonard?[A]dleman)
?*?</p>
?*?<p>
?*?字符串格式的密鑰在未在特殊說明情況下都為BASE64編碼格式<br/>
?*?由于非對稱加密速度極其緩慢,一般文件不使用它來加密而是使用對稱加密,<br/>
?*?非對稱加密算法可以用來對對稱加密的密鑰加密,這樣保證密鑰的安全也就保證了數據的安全
?*?</p>
?*?
?*?@author?IceWee
?*?@date?2012-4-26
?*?@version?1.0
?*/
public?class?RSAUtils?{
????/**
?????*?加密算法RSA
?????*/
????public?static?final?String?KEY_ALGORITHM?=?"RSA";
????
????/**
?????*?簽名算法
?????*/
????public?static?final?String?SIGNATURE_ALGORITHM?=?"MD5withRSA";
????/**
?????*?獲取公鑰的key
?????*/
????private?static?final?String?PUBLIC_KEY?=?"RSAPublicKey";
????
????/**
?????*?獲取私鑰的key
?????*/
????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;
????/**
?????*?<p>
?????*?生成密鑰對(公鑰和私鑰)
?????*?</p>
?????*?
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?Map<String,?Object>?genKeyPair()?throws?Exception?{
????????KeyPairGenerator?keyPairGen?=?KeyPairGenerator.getInstance(KEY_ALGORITHM);
????????keyPairGen.initialize(1024);
????????KeyPair?keyPair?=?keyPairGen.generateKeyPair();
????????RSAPublicKey?publicKey?=?(RSAPublicKey)?keyPair.getPublic();
????????RSAPrivateKey?privateKey?=?(RSAPrivateKey)?keyPair.getPrivate();
????????Map<String,?Object>?keyMap?=?new?HashMap<String,?Object>(2);
????????keyMap.put(PUBLIC_KEY,?publicKey);
????????keyMap.put(PRIVATE_KEY,?privateKey);
????????return?keyMap;
????}
????
????/**
?????*?<p>
?????*?用私鑰對信息生成數字簽名
?????*?</p>
?????*?
?????*?@param?data?已加密數據
?????*?@param?privateKey?私鑰(BASE64編碼)
?????*?
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?String?sign(byte[]?data,?String?privateKey)?throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(privateKey);
????????PKCS8EncodedKeySpec?pkcs8KeySpec?=?new?PKCS8EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????PrivateKey?privateK?=?keyFactory.generatePrivate(pkcs8KeySpec);
????????Signature?signature?=?Signature.getInstance(SIGNATURE_ALGORITHM);
????????signature.initSign(privateK);
????????signature.update(data);
????????return?Base64Utils.encode(signature.sign());
????}
????/**
?????*?<p>
?????*?校驗數字簽名
?????*?</p>
?????*?
?????*?@param?data?已加密數據
?????*?@param?publicKey?公鑰(BASE64編碼)
?????*?@param?sign?數字簽名
?????*?
?????*?@return
?????*?@throws?Exception
?????*?
?????*/
????public?static?boolean?verify(byte[]?data,?String?publicKey,?String?sign)
????????????throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(publicKey);
????????X509EncodedKeySpec?keySpec?=?new?X509EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????PublicKey?publicK?=?keyFactory.generatePublic(keySpec);
????????Signature?signature?=?Signature.getInstance(SIGNATURE_ALGORITHM);
????????signature.initVerify(publicK);
????????signature.update(data);
????????return?signature.verify(Base64Utils.decode(sign));
????}
????/**
?????*?<P>
?????*?私鑰解密
?????*?</p>
?????*?
?????*?@param?encryptedData?已加密數據
?????*?@param?privateKey?私鑰(BASE64編碼)
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?byte[]?decryptByPrivateKey(byte[]?encryptedData,?String?privateKey)
????????????throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(privateKey);
????????PKCS8EncodedKeySpec?pkcs8KeySpec?=?new?PKCS8EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????Key?privateK?=?keyFactory.generatePrivate(pkcs8KeySpec);
????????Cipher?cipher?=?Cipher.getInstance(keyFactory.getAlgorithm());
????????cipher.init(Cipher.DECRYPT_MODE,?privateK);
????????int?inputLen?=?encryptedData.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(encryptedData,?offSet,?MAX_DECRYPT_BLOCK);
????????????}?else?{
????????????????cache?=?cipher.doFinal(encryptedData,?offSet,?inputLen?-?offSet);
????????????}
????????????out.write(cache,?0,?cache.length);
????????????i++;
????????????offSet?=?i?*?MAX_DECRYPT_BLOCK;
????????}
????????byte[]?decryptedData?=?out.toByteArray();
????????out.close();
????????return?decryptedData;
????}
????/**
?????*?<p>
?????*?公鑰解密
?????*?</p>
?????*?
?????*?@param?encryptedData?已加密數據
?????*?@param?publicKey?公鑰(BASE64編碼)
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?byte[]?decryptByPublicKey(byte[]?encryptedData,?String?publicKey)
????????????throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(publicKey);
????????X509EncodedKeySpec?x509KeySpec?=?new?X509EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????Key?publicK?=?keyFactory.generatePublic(x509KeySpec);
????????Cipher?cipher?=?Cipher.getInstance(keyFactory.getAlgorithm());
????????cipher.init(Cipher.DECRYPT_MODE,?publicK);
????????int?inputLen?=?encryptedData.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(encryptedData,?offSet,?MAX_DECRYPT_BLOCK);
????????????}?else?{
????????????????cache?=?cipher.doFinal(encryptedData,?offSet,?inputLen?-?offSet);
????????????}
????????????out.write(cache,?0,?cache.length);
????????????i++;
????????????offSet?=?i?*?MAX_DECRYPT_BLOCK;
????????}
????????byte[]?decryptedData?=?out.toByteArray();
????????out.close();
????????return?decryptedData;
????}
????/**
?????*?<p>
?????*?公鑰加密
?????*?</p>
?????*?
?????*?@param?data?源數據
?????*?@param?publicKey?公鑰(BASE64編碼)
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?byte[]?encryptByPublicKey(byte[]?data,?String?publicKey)
????????????throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(publicKey);
????????X509EncodedKeySpec?x509KeySpec?=?new?X509EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????Key?publicK?=?keyFactory.generatePublic(x509KeySpec);
????????//?對數據加密
????????Cipher?cipher?=?Cipher.getInstance(keyFactory.getAlgorithm());
????????cipher.init(Cipher.ENCRYPT_MODE,?publicK);
????????int?inputLen?=?data.length;
????????ByteArrayOutputStream?out?=?new?ByteArrayOutputStream();
????????int?offSet?=?0;
????????byte[]?cache;
????????int?i?=?0;
????????//?對數據分段加密
????????while?(inputLen?-?offSet?>?0)?{
????????????if?(inputLen?-?offSet?>?MAX_ENCRYPT_BLOCK)?{
????????????????cache?=?cipher.doFinal(data,?offSet,?MAX_ENCRYPT_BLOCK);
????????????}?else?{
????????????????cache?=?cipher.doFinal(data,?offSet,?inputLen?-?offSet);
????????????}
????????????out.write(cache,?0,?cache.length);
????????????i++;
????????????offSet?=?i?*?MAX_ENCRYPT_BLOCK;
????????}
????????byte[]?encryptedData?=?out.toByteArray();
????????out.close();
????????return?encryptedData;
????}
????/**
?????*?<p>
?????*?私鑰加密
?????*?</p>
?????*?
?????*?@param?data?源數據
?????*?@param?privateKey?私鑰(BASE64編碼)
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?byte[]?encryptByPrivateKey(byte[]?data,?String?privateKey)
????????????throws?Exception?{
????????byte[]?keyBytes?=?Base64Utils.decode(privateKey);
????????PKCS8EncodedKeySpec?pkcs8KeySpec?=?new?PKCS8EncodedKeySpec(keyBytes);
????????KeyFactory?keyFactory?=?KeyFactory.getInstance(KEY_ALGORITHM);
????????Key?privateK?=?keyFactory.generatePrivate(pkcs8KeySpec);
????????Cipher?cipher?=?Cipher.getInstance(keyFactory.getAlgorithm());
????????cipher.init(Cipher.ENCRYPT_MODE,?privateK);
????????int?inputLen?=?data.length;
????????ByteArrayOutputStream?out?=?new?ByteArrayOutputStream();
????????int?offSet?=?0;
????????byte[]?cache;
????????int?i?=?0;
????????//?對數據分段加密
????????while?(inputLen?-?offSet?>?0)?{
????????????if?(inputLen?-?offSet?>?MAX_ENCRYPT_BLOCK)?{
????????????????cache?=?cipher.doFinal(data,?offSet,?MAX_ENCRYPT_BLOCK);
????????????}?else?{
????????????????cache?=?cipher.doFinal(data,?offSet,?inputLen?-?offSet);
????????????}
????????????out.write(cache,?0,?cache.length);
????????????i++;
????????????offSet?=?i?*?MAX_ENCRYPT_BLOCK;
????????}
????????byte[]?encryptedData?=?out.toByteArray();
????????out.close();
????????return?encryptedData;
????}
????/**
?????*?<p>
?????*?獲取私鑰
?????*?</p>
?????*?
?????*?@param?keyMap?密鑰對
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?String?getPrivateKey(Map<String,?Object>?keyMap)
????????????throws?Exception?{
????????Key?key?=?(Key)?keyMap.get(PRIVATE_KEY);
????????return?Base64Utils.encode(key.getEncoded());
????}
????/**
?????*?<p>
?????*?獲取公鑰
?????*?</p>
?????*?
?????*?@param?keyMap?密鑰對
?????*?@return
?????*?@throws?Exception
?????*/
????public?static?String?getPublicKey(Map<String,?Object>?keyMap)
????????????throws?Exception?{
????????Key?key?=?(Key)?keyMap.get(PUBLIC_KEY);
????????return?Base64Utils.encode(key.getEncoded());
????}
}
Base64Utils.java
import?java.io.ByteArrayInputStream;
import?java.io.ByteArrayOutputStream;
import?java.io.File;
import?java.io.FileInputStream;
import?java.io.FileOutputStream;
import?java.io.InputStream;
import?java.io.OutputStream;
import?it.sauronsoftware.base64.Base64;
/**
?* <p>
?* BASE64編碼解碼工具包
?* </p>
?* <p>
?* 依賴javabase64-1.3.1.jar
?* </p>
?*?
?*?@author?IceWee
?* @date 2012-5-19
?*?@version?1.0
?*/
public?class?Base64Utils?{
????/**
???? * 文件讀取緩沖區大小
?????*/
????private?static?final?int?CACHE_SIZE?=?1024;
????
????/**
???? * <p>
???? * BASE64字符串解碼為二進制數據
???? * </p>
???? *?
???? *?@param?base64
???? *?@return
???? *?@throws?Exception
?????*/
????public?static?byte[] decode(String base64)?throws?Exception?{
????????return?Base64.decode(base64.getBytes());
??? }
????
????/**
???? * <p>
???? * 二進制數據編碼為BASE64字符串
???? * </p>
???? *?
???? *?@param?bytes
???? *?@return
???? *?@throws?Exception
?????*/
????public?static?String encode(byte[] bytes)?throws?Exception?{
????????return?new?String(Base64.encode(bytes));
??? }
????
????/**
???? * <p>
???? * 將文件編碼為BASE64字符串
???? * </p>
???? * <p>
???? * 大文件慎用,可能會導致內存溢出
???? * </p>
???? *?
???? *?@param?filePath 文件絕對路徑
???? *?@return
???? *?@throws?Exception
?????*/
????public?static?String encodeFile(String filePath)?throws?Exception?{
????????byte[] bytes?=?fileToByte(filePath);
????????return?encode(bytes);
??? }
????
????/**
???? * <p>
???? * BASE64字符串轉回文件
???? * </p>
???? *?
???? *?@param?filePath 文件絕對路徑
???? *?@param?base64 編碼字符串
???? *?@throws?Exception
?????*/
????public?static?void?decodeToFile(String filePath, String base64)?throws?Exception?{
????????byte[] bytes?=?decode(base64);
??????? byteArrayToFile(bytes, filePath);
??? }
????
????/**
???? * <p>
???? * 文件轉換為二進制數組
???? * </p>
???? *?
???? *?@param?filePath 文件路徑
???? *?@return
???? *?@throws?Exception
?????*/
????public?static?byte[] fileToByte(String filePath)?throws?Exception?{
????????byte[] data?=?new?byte[0];
??????? File file?=?new?File(filePath);
????????if?(file.exists())?{
??????????? FileInputStream in?=?new?FileInputStream(file);
??????????? ByteArrayOutputStream out?=?new?ByteArrayOutputStream(2048);
????????????byte[] cache?=?new?byte[CACHE_SIZE];
????????????int?nRead?=?0;
????????????while?((nRead?=?in.read(cache))?!=?-1)?{
??????????????? out.write(cache,?0, nRead);
??????????????? out.flush();
??????????? }
??????????? out.close();
??????????? in.close();
??????????? data?=?out.toByteArray();
???????? }
????????return?data;
??? }
????
????/**
???? * <p>
???? * 二進制數據寫文件
???? * </p>
???? *?
???? *?@param?bytes 二進制數據
???? *?@param?filePath 文件生成目錄
?????*/
????public?static?void?byteArrayToFile(byte[] bytes, String filePath)?throws?Exception?{
??????? InputStream in?=?new?ByteArrayInputStream(bytes);???
??????? File destFile?=?new?File(filePath);
????????if?(!destFile.getParentFile().exists())?{
??????????? destFile.getParentFile().mkdirs();
??????? }
??????? destFile.createNewFile();
??????? OutputStream out?=?new?FileOutputStream(destFile);
????????byte[] cache?=?new?byte[CACHE_SIZE];
????????int?nRead?=?0;
????????while?((nRead?=?in.read(cache))?!=?-1)?{???
??????????? out.write(cache,?0, nRead);
??????????? out.flush();
??????? }
??????? out.close();
??????? in.close();
??? }
????
????
}
RSATester.java
import?java.util.Map;
public?class?RSATester?{
????static?String publicKey;
????static?String privateKey;
????static?{
????????try?{
??????????? Map<String, Object>?keyMap?=?RSAUtils.genKeyPair();
??????????? publicKey?=?RSAUtils.getPublicKey(keyMap);
??????????? privateKey?=?RSAUtils.getPrivateKey(keyMap);
??????????? System.err.println("公鑰: \n\r"?+?publicKey);
??????????? System.err.println("私鑰: \n\r"?+?privateKey);
??????? }?catch?(Exception e)?{
??????????? e.printStackTrace();
??????? }
??? }
????
????public?static?void?main(String[] args)?throws?Exception?{
??????? test();
??????? testSign();
??? }
????static?void?test()?throws?Exception?{
??????? System.err.println("公鑰加密——私鑰解密");
??????? String source?=?"這是一行沒有任何意義的文字,你看完了等于沒看,不是嗎?";
??????? System.out.println("\r加密前文字:\r\n"?+?source);
????????byte[] data?=?source.getBytes();
????????byte[] encodedData?=?RSAUtils.encryptByPublicKey(data, publicKey);
??????? System.out.println("加密后文字:\r\n"?+?new?String(encodedData));
????????byte[] decodedData?=?RSAUtils.decryptByPrivateKey(encodedData, privateKey);
??????? String target?=?new?String(decodedData);
??????? System.out.println("解密后文字: \r\n"?+?target);
??? }
????static?void?testSign()?throws?Exception?{
??????? System.err.println("私鑰加密——公鑰解密");
??????? String source?=?"這是一行測試RSA數字簽名的無意義文字";
??????? System.out.println("原文字:\r\n"?+?source);
????????byte[] data?=?source.getBytes();
????????byte[] encodedData?=?RSAUtils.encryptByPrivateKey(data, privateKey);
??????? System.out.println("加密后:\r\n"?+?new?String(encodedData));
????????byte[] decodedData?=?RSAUtils.decryptByPublicKey(encodedData, publicKey);
??????? String target?=?new?String(decodedData);
??????? System.out.println("解密后: \r\n"?+?target);
??????? System.err.println("私鑰簽名——公鑰驗證簽名");
??????? String sign?=?RSAUtils.sign(encodedData, privateKey);
??????? System.err.println("簽名:\r"?+?sign);
????????boolean?status?=?RSAUtils.verify(encodedData, publicKey, sign);
??????? System.err.println("驗證結果:\r"?+?status);
??? }
????
}
?
轉載于:https://www.cnblogs.com/davidwang456/p/4385215.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的java RSA加密解密--转载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A XSS filter for Jav
- 下一篇: Ambiguous mapping fo