Java 前端与后端的非对称密钥加密

版权声明:转载原创文章请以超链接形式请注明原文章出处,尊重作者,尊重原创!


恰饭广告




RSAUtil.java

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.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class RSAUtil {
	private static String KEY_RSA_TYPE = "RSA";
    private static int KEY_SIZE = 1024;//JDK方式RSA加密最大只有1024位
    private static int ENCODE_PART_SIZE = KEY_SIZE/8;
    public static final String PUBLIC_KEY_NAME = "public";
    public static final String PRIVATE_KEY_NAME = "private";
    
    //私钥
    public static final String privatekey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI9pPL7UlVmgtNB0ODY8xnevOUOrOYv5Yp3kCo9h8WDUY1DzTaoBQNYm74mKPTMHL4UCrHFdrPB6yzTpJSvW/ZGlzCmpHIeE2LU3g/B9qzha4eLBGohkhhRhubx5fZaIvBsBmwOUl0DCaNHiIisCj5ByJGNek8vw2z82prLkvac/AgMBAAECgYA32lCiMcEI6yIAnYLW/Mx/CGtRA3qiHTpfK9VBCnArugwEFv4EXACYZwmbk49KNF45e1UVwdn8vpYtwS+M52pRmxzQzGwqMN2bt7rg5BoIZKZTYBDF+AO1hAJkqeYQIuCEzcjMYWlQlt10uyffYsczQiwUrM0shIFEaX9e0Gb4AQJBAOjatO6ttwdz2bHlpaA//CRxmQ184Ya10Tx5mlR6ll2oTwHQIeOlz+mXEG2iTAuZ4ILtwiP3LsmA3j2IhZeC7D8CQQCdqoa6tDv/qafqVNQAkvK6SGjFGzRHRRLiks/lwbTa8/IMkw3hWZHnPeF2x70oZo/dkU9/W3zCwa0hrjOQAoUBAkEAsDVhGgVHLlKS+LZqAbyp2AJG6hgIqmJIdlUnXqptw24sa5jPLHA7x+7TNcPNfDHz3eCCO6lANKhahYIcZi1jDQJAeLkqwmjhDAjW1tmvHuVlz/dDqbED3ZJpPG2XnGAu3/wsGS68URGpYzuBmNal4vptLAVorqbZp7Juo7xkJN+ZAQJAA/UynM7gu25YaqdxEaVk7+GbUZuyTBpApEvdGjYKrqfmBFJOJepqrF1AAv9LqAg1FmiReRu7P8578lLV6SsZYQ==";
    //公钥
    public static final String publickey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPaTy+1JVZoLTQdDg2PMZ3rzlDqzmL+WKd5AqPYfFg1GNQ802qAUDWJu+Jij0zBy+FAqxxXazwess06SUr1v2RpcwpqRyHhNi1N4Pwfas4WuHiwRqIZIYUYbm8eX2WiLwbAZsDlJdAwmjR4iIrAo+QciRjXpPL8Ns/Nqay5L2nPwIDAQAB";
    /**
     * 创建公钥秘钥
     * @return
     */
    public static Map<String,String> createRSAKeys(){
        Map<String,String> keyPairMap = new HashMap<>();//里面存放公私秘钥的Base64位加密
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA_TYPE);
            keyPairGenerator.initialize(KEY_SIZE,new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
 
            //随机获取公钥秘钥
            //String publicKeyValue = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
            //String privateKeyValue = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());
            
            String publicKeyValue = publickey;
            String privateKeyValue = privatekey;
 
            //存入公钥秘钥,以便以后获取
            keyPairMap.put(PUBLIC_KEY_NAME,publicKeyValue);
            keyPairMap.put(PRIVATE_KEY_NAME,privateKeyValue);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPairMap;
    }
 
    /**
     * 公钥加密
     * 描述:
     *     1字节 = 8位;
     *     最大加密长度如 1024位私钥时,最大加密长度为 128-11 = 117字节,不管多长数据,加密出来都是 128 字节长度。
     * @param sourceStr
     * @param publicKeyBase64Str
     * @return
     */
    public static String encode(String sourceStr){
        byte [] publicBytes = Base64.decodeBase64(publickey);
        //公钥加密
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicBytes);
        List<byte[]> alreadyEncodeListData = new LinkedList<>();
 
        int maxEncodeSize = ENCODE_PART_SIZE - 11;
        String encodeBase64Result = null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE);
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);
            byte[] sourceBytes = sourceStr.getBytes("utf-8");
            int sourceLen = sourceBytes.length;
            for(int i=0;i<sourceLen;i+=maxEncodeSize){
                int curPosition = sourceLen - i;
                int tempLen = curPosition;
                if(curPosition > maxEncodeSize){
                    tempLen = maxEncodeSize;
                }
                byte[] tempBytes = new byte[tempLen];//待加密分段数据
                System.arraycopy(sourceBytes,i,tempBytes,0,tempLen);
                byte[] tempAlreadyEncodeData = cipher.doFinal(tempBytes);
                alreadyEncodeListData.add(tempAlreadyEncodeData);
            }
            int partLen = alreadyEncodeListData.size();//加密次数
 
            int allEncodeLen = partLen * ENCODE_PART_SIZE;
            byte[] encodeData = new byte[allEncodeLen];//存放所有RSA分段加密数据
            for (int i = 0; i < partLen; i++) {
                byte[] tempByteList = alreadyEncodeListData.get(i);
                System.arraycopy(tempByteList,0,encodeData,i*ENCODE_PART_SIZE,ENCODE_PART_SIZE);
            }
            encodeBase64Result = Base64.encodeBase64String(encodeData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encodeBase64Result;
    }
 
    /**
     * 私钥解密
     * @param sourceBase64RSA
     * @param privateKeyBase64Str
     */
    public static String decode(String sourceBase64RSA){
        byte[] privateBytes = Base64.decodeBase64(privatekey);
        byte[] encodeSource = Base64.decodeBase64(sourceBase64RSA);
        int encodePartLen = encodeSource.length/ENCODE_PART_SIZE;
        List<byte[]> decodeListData = new LinkedList<>();//所有解密数据
        String decodeStrResult = null;
        //私钥解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateBytes);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA_TYPE);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(KEY_RSA_TYPE);
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            int allDecodeByteLen = 0;//初始化所有被解密数据长度
            for (int i = 0; i < encodePartLen; i++) {
                byte[] tempEncodedData = new byte[ENCODE_PART_SIZE];
                System.arraycopy(encodeSource,i*ENCODE_PART_SIZE,tempEncodedData,0,ENCODE_PART_SIZE);
                byte[] decodePartData = cipher.doFinal(tempEncodedData);
                decodeListData.add(decodePartData);
                allDecodeByteLen += decodePartData.length;
            }
            byte [] decodeResultBytes = new byte[allDecodeByteLen];
            for (int i = 0,curPosition = 0; i < encodePartLen; i++) {
                byte[] tempSorceBytes = decodeListData.get(i);
                int tempSourceBytesLen = tempSorceBytes.length;
                System.arraycopy(tempSorceBytes,0,decodeResultBytes,curPosition,tempSourceBytesLen);
                curPosition += tempSourceBytesLen;
            }
            decodeStrResult = new String(decodeResultBytes,"UTF-8");
        }catch (Exception e){
            e.printStackTrace();
        }
        return decodeStrResult;
    }
}

Servlet

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Jsencrypt
 */
@WebServlet("/Jsencrypt")
public class Jsencrypt extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Jsencrypt() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//doGet(request, response);
		String data=request.getParameter("data");
        response.getWriter().print(RSAUtil.decode(data)); //返回解密字段
	}
	
}

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript"
	src="https://www.idaobin.com/js/jquery-3.2.1.js"></script>
<script type="text/javascript"
	src="https://www.idaobin.com/test/jsencrypt.min.js"></script>
<script type="text/javascript">
	$(document).ready(function() {
		$("#btn").click(function() {
			//公钥
			var publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPaTy+1JVZoLTQdDg2PMZ3rzlDqzmL+WKd5AqPYfFg1GNQ802qAUDWJu+Jij0zBy+FAqxxXazwess06SUr1v2RpcwpqRyHhNi1N4Pwfas4WuHiwRqIZIYUYbm8eX2WiLwbAZsDlJdAwmjR4iIrAo+QciRjXpPL8Ns/Nqay5L2nPwIDAQAB";

			var encrypt = new JSEncrypt();
			encrypt.setPublicKey(publickey);
			var encrypted = encrypt.encrypt("123456"); //加密的字段
			$.ajax({
				type : 'Post',
				url : '/testweb/Jsencrypt', //请求地址
				data : {
					action : "click",
					data : encrypted
				},
				dataType : 'text', //返回类型

				success : function(data) { //请求成功
					alert(data);

				},
				error : function(XMLHttpRequest, textStatus) { //请求失败
					if (textStatus == 'timeout') {
						var xmlhttp = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHttp");
						xmlhttp.abort();
						alert("请求超时");
					} else if (textStatus == "error") {
						alert("服务器内部错误");
					} else if (textStatus == "parsererror") {
						alert("返回类型错误");
					}
				}
			});
		});
	});
</script>
</head>
<body>
	This is my JSP page.
	<br>
	<div id="btn">click</div>
</body>
</html>

相关jar包下载

原文链接:https://www.idaobin.com/archives/2074.html

让我恰个饭吧.ヘ( ̄ω ̄ヘ)

支付宝 ——————- 微信
图片加载中图片加载中



恰饭广告

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

16 − = 9