现实网络中,web应用的开发少不了需要对敏感信息来进行加密,但是加密又不能草草了事,过于简单。一旦被钻了空子,就成了事故。比如密码。
之前用到了非对称加密没做记录,这次又用到了,所以记录下来!
RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:
将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。
公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
流程:解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送到解密者,解密者用私钥解密将密文解码为明文。
举例:
以要把信息发给乙为例,
首先确定角色:甲为加密者,乙为解密者。
首先由乙随机确定一个KEY,称之为密匙,将这个KEY始终保存在机器B中而不发出来;
然后,由这个 KEY计算出另一个KEY,称之为公匙。这个公钥的特性是几乎不可能通过它自身计算出生成它的私钥。
接下来通过网络把这个公钥传给甲,甲收到公钥后,利用公钥对信息加密(此处的加密不可逆),并把密文通过网络发送到乙,
最后乙利用已知的私钥,就对密文进行解码了。
以上就是RSA算法的工作流程。
代码实现步骤:
一、 后台服务器生成私钥和公钥,并且把公钥传给前台(渲染需要加密信息的页面之前):
/**
* 加密登录前置条件
* @param request
* @param mv
* @throws NoSuchAlgorithmException
*/
private void passwordEncodeBefore(HttpServletRequest request, ModelAndView mv) throws NoSuchAlgorithmException {
// ModelAndView mv = new ModelAndView();
/********* 加密登录 begin *********************/
HashMap<String, Object> map = RSAUtils.getKeys();
//生成公钥和私钥
RSAPublicKey publicKey = (RSAPublicKey) map.get(RSAUtils.RAS_Key_Public);
RSAPrivateKey privateKey = (RSAPrivateKey) map.get(RSAUtils.RAS_Key_Private);
request.getSession().setAttribute(RSAUtils.RAS_Key_Private, privateKey);//私钥保存在session中,用于解密
//公钥信息保存在页面,用于加密
String publicKeyExponent = publicKey.getPublicExponent().toString(16);
String publicKeyModulus = publicKey.getModulus().toString(16);
mv.addObject("publicKeyExponent", publicKeyExponent);
mv.addObject("publicKeyModulus", publicKeyModulus);
/********* 加密登录 end *********************/
}
以上代码用到一个RSA工具类,用以生成公钥和私钥。 点击打开链接下载
其中工具类中用到了一个类,BouncyCastleProvider 其所在的jar包 maven地址为如下:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.47</version>
</dependency>
二、前台页面获取后台传的公钥信息(js)
RSAUtils.setMaxDigits(200);
var key = new RSAUtils.getKeyPair("${publicKeyExponent}", "", "${publicKeyModulus}");
var password = $('input[name=password]').val();
//js里面是反序的字符串
var reversedPwd = password.split("").reverse().join("");
//加密后密码
var encrypedPwd = RSAUtils.encryptedString(key,reversedPwd);
这里需要引入一个加密的js,点击打开链接下载
三、 前台把加密后的密文传递给后台,后台解密
//解密后的密码,password是提交过来的密码
RSAPrivateKey privateKey = (RSAPrivateKey)request.getSession().getAttribute(RSAUtils.RAS_Key_Private);
String password = RSAUtils.decryptByPrivateKey(password, privateKey);
以上就是整个实现的过程!有问题请指正。