首页 > 开发 > Java > 正文

JAVA 中解密RSA算法JS加密实例详解

2024-07-13 10:06:27
字体:
来源:转载
供稿:网友

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("状态:" + 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使用私钥进行解密即可。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

 

注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表