【双十一钜惠:科技人的专属保障】移动端认证保障 ——非对称加密及jwt应用
——非对称加密及jwt应用
第一时间了解程序员大小事儿
作者:open,从事java开发领域8年,对spring开发框架,缓存服务器,搜索引擎,中间件,代理服务器都有很深的造诣。现专注于项目组内技术研发及架构搭建。
编者按:本次双十一钜惠活动,移动APP、线上系统直面大量客户,那么我们科技人是如何保证数据安全,特别是登陆认证凭据数安全?让我们一起来寻找答案。随着移动APP、微服务架构兴起,JWT技术广泛应用,JWT数据的安全性愈发重要;本篇文章,主要与大家分享利用数据加密保证JWT数据安全的应用方案总结,希望热爱技术的伙伴能够从中找到共鸣,得到受益,不当之处请多多批评指教。
对称与非对称加密
对称加密:加密和解密的秘钥为同一个,加密速度快、效率高、计算量小算法公开,缺点是安全性低。常用的对称加密算法有DES、3DES(TripleDES)、AES等。
非对称加密:具有公开和私有的一对密钥,公开密钥加密只能私有密钥解密,同样私有密钥加密只有公开密钥能够解密。非对称加密最大的优点是安全性高,缺点是加密速度慢,加密内容有字节数限制,如果加密内容较长需要进行分段加密或其他加密方式进行辅助加密。常见的非对称加密类型有RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)。
对于移动端应用,大多采用前后分离架构,所有数据由原生、h5、vue等终端通过json与后端服务进行交互,对于一些敏感数据(密码),如果使用对称加密,算法和密钥很容易暴露在前端,攻击者能够轻易对加密数据进行破译和伪造,对于用户敏感数据信息安全存在极大的风险。所以需要使用安全的非对称加密算法进行数据加密,下面通过对RSA非对称加密算法的具体应用更深入的理解他的安全性。
RSA非对称加密具体应用
假设某系统登录模块,前后分离架构,需要进行用户名密码加密传输到后端进行认证,如果利用对称加密,密钥和算法直接通过浏览器即可获取,如果传输数据被截获,很容易反解出用户密码。采用非对称加密会存在此类问题吗?下面模拟登录请求进行测试。
(1)生成一对RSA密钥
(2)公钥提供给前端,进行密码加密传输(此例模拟公钥加密)
(3)模拟登录请求,后端利用私钥进行解密,成功解密出密码。
(4)截获请求利用提供给前端的公钥进行解密,无法解密,程序出现异常。
(5)结论
非对称加密,公钥加密只有私钥能够解密,私钥存储在服务器端,只要私钥不被暴露,加密内容无法被反解出来,能够保护数据传输的安全性。
基于RSA非对称算法的jwt安全认证应用
JWT (Json web token), 是为了在网络应用双方进行信息传递执行的一种安全、简洁的基于JSON的开放标准(RFC 7519)。可用于用户认证,jwt是无状态的,较session有更好的扩展性。具体应用如下:
(1)认证流程图
(2)引入相关依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
(3)认证通过,生成token(对应图中步骤2)
//指定签名的时候使用的签名算法,也就是header那部分,jwt已对此部分内容进行封装。
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
//创建payload的私有声明(键值对儿,存储业务关键信息,请勿存放关键敏感信息,jwt虽然不能被伪造,但是可以被解密查看)
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("id", "1233456");
//生成签名的时候使用的秘钥secret,这个方法本地封装了的,此密钥一定不能泄露,如果泄露,就能够伪造token了。
String privateKey = "asdfasdfasdfsadfsa";
//生成JWT的时间
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//设置jwt
JwtBuilder builder = Jwts.builder()
.setClaims(claims)
//iat: jwt的签发时间
.setIssuedAt(now)
//代表这个JWT的主体,即它的所有人,可以酌情设置。
.setSubject("user123")
//设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, RSA.genPrivateKey(privateKey));
long expMillis = nowMillis + 60*1000;
Date exp = new Date(expMillis);
//设置过期时间为一分钟。
builder.setExpiration(exp);
String tokenJwt = builder.compact();
return tokenJwt;
(4)将token存入cookie返回(对应图中步骤4)
Cookie cookie = new Cookie("token",tokenJwt);
//单位为秒
cookie .setMaxAge(60*1000);
cookie .setPath("/");
response.addCookie(cookie);
(5)网关添加全局过滤器,校验token。token校验通过后检查是否需要续期,如果需要续期则调用相应服务进行续期(此例为伪代码,直接在网关进行续期)。最后将token解析出的用户关键信息存入header供后端服务使用。(对应图中步骤6)
MultiValueMap<String, HttpCookie> cookies= request.getCookies();
String tokensrcret = null;
HttpCookie tokenCookie = (HttpCookie)(cookies.get("token").get(0));
tokensrcret =tokenCookie.getValue();
if(StringUtils.isNotBlank(tokensrcret)){
//签名公钥,与生成token的私钥是一对
String key = "asafasdfsdf";
//解密jwt
Claims claims = Jwts.parser()
//设置签名的秘钥
.setSigningKey(RSA.genPublicKey(key))
//设置需要解析的jwt
.parseClaimsJws(tokensrcret).getBody();
Date issuedAtDate = claims.getIssuedAt();
long issatTokenMillis = issuedAtDate.getTime();
long nowMillis = System.currentTimeMillis();
//签发日期超过40秒,强制token失效,防止恶意无限刷新token。
if(nowMillis-issatTokenMillis<45*1000){
//获取JWT的失效时间
Date expirateDate = claims.getExpiration();
long tokenExpirateMillis = expirateDate.getTime();
if(tokenExpirateMillis-nowMillis<60*60*1000){
//超过45秒为token继续续期75秒,此处为伪代码,实际可将此部分抽出到认证服务中。
long expMillis = nowMillis + 75*1000;
Date exp = new Date(expMillis);
claims.setExpiration(exp);
//私钥,注意防止泄露
String privateKey="qwerq";
String token= Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.RS256,RSA.genPrivateKey(privateKey)).compact();
//放入cookie返回给终端
ResponseCookie.ResponseCookieBuilder cookieBuilder = ResponseCookie.from("token",token);
cookieBuilder.maxAge(75*1000/1000);
cookieBuilder.path("/");
response.addCookie(cookieBuilder.build());
}
//将解密出的信息放入header供后端服务使用
request.addHeader("id",JSONObject.toJSON(claims.get("id")).toString());
return true;
}
}
return false;
总结
RSA非对称加密结合jwt能够提供安全、简洁的网络数据传输,jwt的无状态性,能够为应用提供更好的扩展性。
科技人需要时刻谨记系统安全红线,规避风险。在日常生活中,我们同样需要为自己、家人和关心的人提供安全的保障。本次双十一钜惠活动,为生活中的各种风险提供各类的保障计划,赶紧扫描下方二维码,选择适合自己、实惠的保险保障。
真爱无价,惠保万家,双十一感恩钜惠!