您的位置:首页 > 其它

使用RSA非对称加密登陆界面登陆密码,防止明文传输

2016-12-27 12:39 531 查看

 一、RSA的概念

         RSA加密算法是一种非对称加密算法。在公开密钥加密电子商业中RSA被广泛使用,在java中可用作表单密码加密,工作原理可理大致是,首先服务器端会产生一对公钥和私钥,然后客户端在需要加密的时候会异步请求服务器端,获取公钥,并利用公钥进行加密操作(加密表单密码元素),服务器端收到加了密的用户密码,再使用私钥进行解密,从而获取加密前的明文密码。由于仅仅有了公钥并不能解密,必须使用服务器的私钥解码,所以在web端的项目中使用时能提高密码的安全性。

二、实现过程(代码)

 1.需要jar包以及js插件:bcprov-ext-jdk15on-1.55.jar,jquery.jcryption-1.1.js(附件有)
    2. 登陆页面,分2种:
   第一种直接是表单form提交:处理思路是提交ajax请求异步获得公钥,使用jquery获取页面所有type='password'的input框,然后循环遍历,并同时将加密的密码值放到对应的type='password'的input框中,然后点击提交按钮即可发送请求

   第二种是点击按钮后使用ajax请求提交:
        js代码:
/**
* 单击登陆按钮
*/
$("#logInpt").click(function(){
//访问后台获取公钥
$.jCryption.getKeys(url,function(receivedKeys){ // 异步请求获取用来加密的公钥
keys = receivedKeys;
if( null != keys && "undefined" != keys){
var postData = {};
var origPwd = $("#J_PasswordPsd").val();
//实用公钥进行加密
$.jCryption.encrypt(origPwd, keys, function(encryptedPasswd) {  ///使用公钥谨慎性加密
var serlizeFormData =$("#J_ValidForm").serializeArray();//获取表单的序列化元素
$.each(serlizeFormData,function(key,val){               //将提交的参数中的密码进行处理
if(val['name']=="password" && val['value']==origPwd){
postData["password"] = encryptedPasswd;
}else{
postData[val.name]=val['value'];
}
})
//修改参数后提交ajax请求
$.ajax({
url:'',
beforeSend:,//提交前事件处理方法
type:"post",
dataType:"json",
data:postData,
success:function(){
}//回掉函数处理
})
// usrForm.submit();
})
}
});

})
  java代码(Config存储静态代码块,执行RSAutil中的代码,产生密钥
,也可以采用将生成的密钥保存到seesion中,然后揭秘时候从session中取的方法):
@RequestMapping(value = "/getPublicKey.htm",  method = { RequestMethod.GET })
public void encryptionWithPublicKey(HttpServletRequest request,HttpServletResponse response){
String generateKeypair = request.getParameter("generateKeypair");
try{
if (generateKeypair != null && ("true").equals(generateKeypair)) {
Map<String ,Object> keyMap = Config.getRsaKeyMap();
//RSAUtil RSAUtil = new RSAUtil();

if (keyMap == null) {
String basePath = "config/ds.properties";
KeyPair kp = RSAUtil.generateKeypair(1024, basePath);
Map<String, Object> map = new HashMap<String,Object>();
map.put("keyPair",kp);
keyMap = map;
}
KeyPair keyPair = (KeyPair)keyMap.get("keyPair");
StringBuffer output = new StringBuffer();
String e = RSAUtil.getPublicKeyExponent(keyPair);
String n = RSAUtil.getPublicKeyModulus(keyPair);
String md = String.valueOf(RSAUtil.getMaxDigits(1024));
output.append("{\"e\":\"");
output.append(e);
output.append("\",\"n\":\"");
output.append(n);
output.append("\",\"maxdigits\":\"");
output.append(md);
output.append("\"}");
output.toString();
response.getOutputStream().print(output.toString().replaceAll("\r", "").replaceAll("\n", "").trim());

}
}catch(Exception e){
e.printStackTrace();
}
}
  产生密钥对的工具类:
    
public class RSAUtil {
public static final String PUBLIC_KEY = "RSAPublicKey";
public static final String PRIVATE_KEY = "RSAPrivateKey";
public static final String BASEPATH = "config/ds.properties";
public static final java.security.Provider provider = new BouncyCastleProvider();
/**
* Constructor
*/
public RSAUtil() throws Exception {
java.security.Security.addProvider(provider);
}

/**
* Generates the Keypair with the given keyLength.
*
* @param keyLength
*            length of key
* @return KeyPair object
* @throws RuntimeException
*             if the RSA algorithm not supported
*/
public static KeyPair generateKeypair(int keyLength,String basePath) throws Exception {
try {
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance("RSA");
} catch (Exception e) {
kpg = KeyPairGenerator.getInstance("RSA",provider);
}
kpg.initialize(keyLength);
KeyPair keyPair = kpg.generateKeyPair();
// saveKeyPair(keyPair, basePath);
return keyPair;
} catch (NoSuchAlgorithmException e1) {
throw new RuntimeException("RSA algorithm not supported", e1);
} catch (Exception e) {
throw new Exception("other exceptions", e);
}
}
/**
* 保存密钥
* @param kp
* @throws Exception
*/
public static void saveKeyPair(KeyPair kp, String basePath) throws Exception {
basePath =StringUtils.isNotBlank(basePath)?basePath:BASEPATH;
String path = Thread.currentThread().getContextClassLoader().getResource(basePath).getPath();
Properties prop = new Properties();// 属性集合对象
InputStream  fis = new BufferedInputStream(new FileInputStream(path));// 属性文件输入流
prop.load(fis);// 将属性文件流装载到Properties对象中
fis.close();// 关闭流
// 修改公钥值的属性值
prop.setProperty(PUBLIC_KEY,byteArrayToHexString(kp.getPublic().getEncoded()));
// 修改私钥值的属性值
prop.setProperty(PRIVATE_KEY,byteArrayToHexString(kp.getPrivate().getEncoded()));
// 文件输出流
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(path));

// 将Properties集合保存到流中
prop.store(fos, "modify");
fos.flush();
fos.close();// 关闭流
//System.out.println("获取修改后的属性值:password=" + prop.getProperty("password"));

}
/**
* Decrypts a given string with the RSA keys
*
* @param encrypted
*            full encrypted text
* @param keys
*            RSA keys
* @return decrypted text
* @throws RuntimeException
*             if the RSA algorithm not supported or decrypt operation failed
*/
public static String decrypt(String encrypted, KeyPair keys) throws Exception {
Cipher dec;
try {
try {
dec = Cipher.getInstance("RSA/NONE/NoPadding");
} catch (Exception e) {
dec = Cipher.getInstance("RSA/NONE/NoPadding",provider);
}
dec.init(Cipher.DECRYPT_MODE, keys.getPrivate());
} catch (GeneralSecurityException e) {
throw new RuntimeException("RSA algorithm not supported", e);
}
String[] blocks = encrypted.split("\\s");
StringBuffer result = new StringBuffer();
try {
for (int i = blocks.length - 1; i >= 0; i--) {
byte[] data = hexStringToByteArray(blocks[i]);
byte[] decryptedBlock = dec.doFinal(data);
result.append(new String(decryptedBlock));
}
} catch (GeneralSecurityException e) {
throw new RuntimeException("Decrypt error", e);
}
/**
* Some code is getting added in first 2 digits with Jcryption need to investigate
*/
return result.reverse().toString().substring(2);
}

/**
* Parse url string (Todo - better parsing algorithm)
*
* @param url
*            value to parse
* @param encoding
*            encoding value
* @return Map with param name, value pairs
*/
public static Map parse(String url, String encoding) {
try {
String urlToParse = URLDecoder.decode(url, encoding);
String[] params = urlToParse.split("&");
Map parsed = new HashMap();
for (int i = 0; i < params.length; i++) {
String[] p = params[i].split("=");
String name = p[0];
String value = (p.length == 2) ? p[1] : null;
parsed.put(name, value);
}
return parsed;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unknown encoding.", e);
}
}

/**
* Return public RSA key modulus
*
* @param keyPair
*            RSA keys
* @return modulus value as hex string
*/
public static String getPublicKeyModulus(KeyPair keyPair) {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
return publicKey.getModulus().toString(16);
}

/**
* Return public RSA key exponent
*
* @param keyPair
*            RSA keys
* @return public exponent value as hex string
*/
public static String getPublicKeyExponent(KeyPair keyPair) {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
return publicKey.getPublicExponent().toString(16);
}

/**
* Max block size with given key length
*
* @param keyLength
*            length of key
* @return numeber of digits
*/
public static int getMaxDigits(int keyLength) {
return ((keyLength * 2) / 16) + 3;
}

/**
* Convert byte array to hex string
*
* @param bytes
*            input byte array
* @return Hex string representation
*/
public static String byteArrayToHexString(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
result.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16)
.substring(1));
}
return result.toString();
}

/**
* Convert hex string to byte array
*
* @param data
*            input string data
* @return bytes
*/
public static byte[] hexStringToByteArray(String data) {
int k = 0;
byte[] results = new byte[data.length() / 2];
for (int i = 0; i < data.length();) {
results[k] = (byte) (Character.digit(data.charAt(i++), 16) << 4);
results[k] += (byte) (Character.digit(data.charAt(i++), 16));
k++;
}
return results;
}

/**
* @param args
*/
public static void main(String[] args) {
/*	 KeyPair keyPair = generateKeypair(1024, "");
String pwd = "11111111";
System.out.println(jCryption.toPublicKeyString());  */
}

}
  RSA解密的部分代码(config中使用静态变量存储密钥对)
//RSA解密
Map<String ,Object> keyMap = Config.getRsaKeyMap();
KeyPair keys = (KeyPair)keyMap.get("keyPair");
String decryptedPass = RSAUtil.decrypt(password, keys);  //RSA解密
至此,有关RSA加密解密就结束了,下面附上文章开始提到的文件,jar可以从maen中央仓库下载,js提供一下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RSA 加密 密码 加密