1、概念介绍
Basic authentication:是一种最简单的对Web资源进行访问控制的方法,属应用层的安全保障手段。常用的签名算法有:base64、HmacSHA1
1)优点:简单
- 服务器无需维护session、cookie,方便curl测试。
- 甚至可以不用登陆界面
- 使用HTTP header中的标准字段,所以也不需要握手
2)缺点:如果只采用通过base64这种签名算法进行传输是不行的,因为很容易就被解码。所以为了保证BA的安全,要通过私钥定制签名算法
2、BA认证的过程
案例:服务A要通过restful的方式请求服务B,服务B采取了BA认证的方式来请求是合法的。
2.1 整体流程
B 事先给 A 分配了一对clientID和secret,约定好会校验会用到两个header:Authorization、Date,并将Authorization的格式告诉A。A发起请求的过程如下:
2.2 实现细节
BA认证重要的是设计理念,实现细节因人而异,这里我们讲一下比较通用的做法
1)生成Authorization
格式:"MILK" + " " + "{clientID}" + ":" + "{signature}"
其中:
- “MILK”:只是个示例,一般会用一个字符串常量,标识你的公司,或者系统;
- {clientID}: B给A分配的clientID,格式自由定义
- {signature}: 对一次请求的信息和时间进行签名加密
代码:
public static final String DATE_FORMAT = "EEE dd MMM yyyy HH:mm:ss 'GMT'";
public static String getAuthorization(String uri, String method, String clientId, String secret) {
String date = LocalDateTime.now(ZoneId.of("GMT")).format(DateTimeFormatter.ofPattern(DATE_FORMAT, Locale.US));
String stringToSign = method + " " + uri + "\n" + date;
String signature = getSignature(stringToSign, secret);
return "MILK " + clientId + ":" + signature;
}
public static String getSignature(String data, String secret) {
try {
SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
String result = Base64.encodeToString(rawHmac);
return result;
} catch (Exception e) {
throw new IllegalStateException("Failed to generate HMAC : " + e.getMessage());
}
}
2)服务端进行校验
服务端进行校验,有两种思路:
- 比较解码后的信息是否正确
- 比较编码的结果是否正确:这个
- 从Authorization中解码出clientID,拿到请求的uri、http方法、header中的date,查询对应的secret,进行加密,看下标准的authorization是否正确(加密过程和上面代码几乎一样)
- 通常会增加一些时间窗口,先行检查下是否过期,过期就直接认为验证失败
代码:校验窗口时间:
private static boolean checkDate(String date){
if (StringUtils.isBlank(date)){
return false;
}
try{
DateTime date = DATE_FORMAT.parseDateTime(date);
DateTime now = DateTime.now(DateTimeZone.forID("Etc/GMT"));
return now.minusMinutes(10).isBefore(date) && now.plusMinutes(10).isAfter(date);
}catch (Exception exception){
return false;
}
}
3、Base64编码简介
- 通过64个可打印字符来表示二进制数据,由于2^6=64,所以每6个比特为一组,表示一个可打印字符。
- 可打印字符有:A-Z、a-z、0-9、+、"/"
- 编码过程
- 每 3 个8Bit的字节,转换为4 个 6 Bit的字节;
- 6 Bit再添 2 位高位 0;
- 组成四个8Bit的字节;
- 3*8 = 4*6 = 24
- 3 个字节,变为 4 个字节,字符串长度增长 1/3
Base64等,是一种编码算法,不是一种加密算法;对数据进行编码是为了让数据更适合传输而不是让数据机密性变强。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)