web登陆非对称加密 已解密的登录请求

一、js引入Barrett.js、BigInt.js、RSA.js

二、js请求后台获取key

        $http({
    		method: 'post', 
    		url: 'action/key', 
    		params: {
    			t:Math.random()
    		},
    		headers: { 'Content-Type': 'application/x-www-form-urlencoded' }  
    	}).success(function(data, status) {
    		$scope.publicKey = data;
    		if($scope.publicKey){
    			$scope.login();
    		}
        }).error(function(data, status) {
            alert('失败');
        });

三、java生成key

需要引入bcprov-jdk16-1.46.jar

package com.neusoft.streamone.app.security.controller;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.neusoft.streamone.app.utils.RSAUtils;

@Controller
@RequestMapping("/key")
public class KeyController {
	
	@RequestMapping
	@ResponseBody
	public Map<String, Object> generate(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> m = new HashMap<String, Object>();
		RSAPublicKey publicKey = null;
		try{
			Map<String, Object> keyMap = RSAUtils.getkeyPairMap();
			publicKey=RSAUtils.getPublicKey(keyMap);
			m.put("modulus", publicKey.getModulus().toString(16));
			m.put("exponent", publicKey.getPublicExponent().toString(16));
			RSAPrivateKey privateKey=RSAUtils.getPrivateKey(keyMap);
	        request.getSession().setAttribute(RSAUtils.PRIVATE_KEY, privateKey);
		}catch(Exception e){
			e.printStackTrace();
		}
		return m;
	}
	
}
package com.neusoft.streamone.app.utils;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

public class RSAUtils {
	
	//非对称密钥算法
    public static final String KEY_ALGORITHM = "RSA";
    //密钥长度,DH算法的默认密钥长度是1024,密钥长度必须是64的倍数,在512到65536位之间
    private static final int KEY_SIZE = 512;
    //公钥
    public static final String PUBLIC_KEY = "RSAPublicKey";
    //私钥
    public static final String PRIVATE_KEY = "RSAPrivateKey";
    
    private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
	
    //初始化密钥
    public static Map<String,Object> getkeyPairMap() throws Exception {
        KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGenerator.initialize(KEY_SIZE);
        KeyPair keyPair=keyPairGenerator.generateKeyPair();
        RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();
        Map<String,Object> keyMap=new HashMap<String,Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }
    
    //私钥解密
    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);
    }
    
    public static String decryptToString(RSAPrivateKey key, String text) throws Exception {
    	if(StringUtils.isBlank(text)) {
            return null;
        }
        byte[] en_data = Hex.decodeHex(text.toCharArray());
        byte[] data = decrypt(key, en_data);
        return StringUtils.reverse(new String(data));
    }
    
    public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM, DEFAULT_PROVIDER);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  
        return cipher.doFinal(data);
    }
    
    //取得私钥
    public static RSAPrivateKey getPrivateKey(Map<String,Object> keyMap){
        return (RSAPrivateKey)keyMap.get(PRIVATE_KEY);
    }

    //取得公钥
    public static RSAPublicKey getPublicKey(Map<String,Object> keyMap) throws Exception{
        return (RSAPublicKey) keyMap.get(PUBLIC_KEY);
    }
}

四、根据返回key值加密登陆

    $scope.login = function() {
        var loginParam = {
            userName : encryptByPublicKey('admin', $scope.publicKey),
            passWord : encryptByPublicKey('123456', $scope.publicKey)
        };

	    $http.post('action/login?format=json&t='+Math.random(), loginParam, {
	        headers: {
	            'Content-Type': 'application/x-www-form-urlencoded' 
	        }
	    }).success(function(response, status, headers, config) {
	        ...
	    }).error(function(data, status, headers, config) {
	    	...
	    });
    };


    function encryptByPublicKey(input, publicKey){
        setMaxDigits(76);
        var keyPair = new RSAKeyPair(publicKey.exponent, '', publicKey.modulus);
        var s = encryptedString(keyPair, input);
    	return s;
    }

五、后台解密

    protected void login(HttpServletRequest request) {
    	RSAPrivateKey privateKey = (RSAPrivateKey)request.getSession().getAttribute(RSAUtils.PRIVATE_KEY);
    	String username = getUsername(request);
        String password = getPassword(request);
    	username = RSAUtils.decryptToString(privateKey, username);
    	password = RSAUtils.decryptToString(privateKey, password);

    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值