JAVA 中解密RSA算法JS加密實例詳解
更新時間:2017年04月14日 08:39:10 投稿:lqh
這篇文章主要介紹了JAVA 中解密RSA算法JS加密 的相關資料,需要的朋友可以參考下
JAVA 中解密RSA算法JS加密實例詳解
有這樣一個需求,前端登錄的用戶名密碼,密碼必需加密,但不可使用MD5,因為后臺要檢測密碼的復雜度,那么在保證安全的前提下將密碼傳到后臺呢,答案就是使用RSA非對稱加密算法解決 。
java代碼
需要依賴 commons-codec 包
RSACoder.Java
import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * Created by lake on 17-4-12. */ public class RSACoder { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; public static byte[] decryptBASE64(String key) { return Base64.decodeBase64(key); } public static String encryptBASE64(byte[] bytes) { return Base64.encodeBase64String(bytes); } /** * 用私鑰對信息生成數字簽名 * * @param data 加密數據 * @param privateKey 私鑰 * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64編碼的私鑰 byte[] keyBytes = decryptBASE64(privateKey); // 構造PKCS8EncodedKeySpec對象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私鑰匙對象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私鑰對信息生成數字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校驗數字簽名 * * @param data 加密數據 * @param publicKey 公鑰 * @param sign 數字簽名 * @return 校驗成功返回true 失敗返回false * @throws Exception */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64編碼的公鑰 byte[] keyBytes = decryptBASE64(publicKey); // 構造X509EncodedKeySpec對象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公鑰匙對象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 驗證簽名是否正常 return signature.verify(decryptBASE64(sign)); } public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{ // 對密鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對數據解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(String data, String key) throws Exception { return decryptByPrivateKey(decryptBASE64(data),key); } /** * 解密<br> * 用公鑰解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 對密鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對數據解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公鑰加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(String data, String key) throws Exception { // 對公鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對數據加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data.getBytes()); } /** * 加密<br> * 用私鑰加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 對密鑰解密 byte[] keyBytes = decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對數據加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私鑰 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Key> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公鑰 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Key> keyMap) throws Exception { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密鑰 * * @return * @throws Exception */ public static Map<String, Key> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); Map<String, Key> keyMap = new HashMap(2); keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公鑰 keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私鑰 return keyMap; } }
測試類
RSACoderTest.java
import org.junit.Before; import org.junit.Test; import java.security.Key; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Created by lake on 17-4-12. */ public class RSACoderTest { private String publicKey; private String privateKey; @Before public void setUp() throws Exception { Map<String, Key> keyMap = RSACoder.initKey(); publicKey = RSACoder.getPublicKey(keyMap); privateKey = RSACoder.getPrivateKey(keyMap); System.err.println("公鑰: \n\r" + publicKey); System.err.println("私鑰: \n\r" + privateKey); } @Test public void test() throws Exception { System.err.println("公鑰加密——私鑰解密"); String inputStr = "abc"; byte[] encodedData = RSACoder.encryptByPublicKey(inputStr, publicKey); byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData, privateKey); String outputStr = new String(decodedData); System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); assertEquals(inputStr, outputStr); } @Test public void testSign() throws Exception { System.err.println("私鑰加密——公鑰解密"); String inputStr = "sign"; byte[] data = inputStr.getBytes(); byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey); byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey); String outputStr = new String(decodedData); System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); assertEquals(inputStr, outputStr); System.err.println("私鑰簽名——公鑰驗證簽名"); // 產生簽名 String sign = RSACoder.sign(encodedData, privateKey); System.err.println("簽名:" + sign); // 驗證簽名 boolean status = RSACoder.verify(encodedData, publicKey, sign); System.err.println("狀態(tài):" + status); assertTrue(status); } }
前端代碼
依賴 jsencrypt 項目
<script src="bin/jsencrypt.min.js"></script> <script type="text/javascript"> var encrypt = new JSEncrypt(); encrypt.setPublicKey('java生成的公鑰'); var encrypted = encrypt.encrypt('加密的字符串'); </script>
說明
前端生成加密的字符串encrypted,傳到后臺,java使用私鑰進行解密即可。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關文章
Springboot Druid 自定義加密數據庫密碼的幾種方案
這篇文章主要介紹了Springboot Druid 自定義加密數據庫密碼的步驟,幫助大家更好的理解和使用springboot,感興趣的朋友可以了解下2020-12-12SpringCloud?客戶端Ribbon負載均衡的實現方法
Ribbon 是 Netflix 提供的一個基于 Http 和 TCP 的客戶端負載均衡工具,且已集成在 Eureka 依賴中,這篇文章主要介紹了SpringCloud?客戶端Ribbon負載均衡的實現方法,需要的朋友可以參考下2022-06-06Springboot通用mapper和mybatis-generator代碼示例
這篇文章主要介紹了Springboot通用mapper和mybatis-generator代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-12-12