历史版本18 :数字签名认证 返回文档
编辑时间:
内容长度:图片数:目录数:
修改原因:
1. 描述编辑
数字签名是以电子的形式存在于数据信息中,或者是作为附件,或者是逻辑上与之有联系的数据,可用于辨别使用人的身份,保证数据的安全性。
目前的数字签名是建立在公共密钥体制基础上,它是公用密钥加密技术的另一类应用。它的主要方式是:报文的发送方从报文文本中生成一个128位的散列值(或报文摘要)。
发送方用自己的私人密钥对这个散列值进行加密来形成发送方的数字签名。这个数字签名将作为报文的附件和报文一起发送给报文的接收方。
报文的接收方首先从接收到的原始报文中计算出128位的散列值(或报文摘要),再用发送方的公用密钥来对报文附加的数字签名进行解密。
如果两个散列值相同、那么接收方就能确认该数字签名是发送方的。通过数字签名能够实现对原始报文的鉴别。
2. 思路编辑
9.0采用的方案是RSA的公私钥方案,该方案在跨平台支持不够好,所以10.0引入JWT方案,由于JWT是一个通用的规范,有很多语言版本能支持,并且校验起来更为简单,有使用方便、环境搭建更为容易的优点。
3. 生成密钥编辑
目前只支持HS256(HmacSHA256)的签名算法,所以需要提供一个HmacSHA256的秘钥,以下是JAVA生成的源码,可参考:
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
private String createSecret() {
try {
//secret可以自定义的
String secret = "123456";
String message = "";
Mac sha256Hmac = Mac.getInstance("HmacSHA256");//指定算法
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256Hmac.init(secret_key);
BASE64Encoder encoder = new BASE64Encoder();//使用base64对生成的二进制byte流编码
String hash = encoder.encode(sha256Hmac.doFinal(message.getBytes()));
return hash;//最终结果
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "";
}
根据上述方法获得密钥为:uUbMyYdGWvzafkWxcVIZcRoTUY0fFmO4xTuEjLAUNEE=
选择决策平台>管理系统>模板认证-设置,开启模板认证,认证方式选择【数字签名认证】,将生成的密钥输入到文本框中并保存。如下图所示:
4. 操作步骤编辑
4.1 新建filter
首先,在工程所在的WEB-INF目录下,新建web.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<filter>
<filter-name>digitalAuthDemo</filter-name>
<filter-class>com.fr.decision.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>digitalAuthDemo</filter-name>
<!--FineReport view report URL-->
<url-pattern>/decision/view/report</url-pattern>
</filter-mapping>
</web-app>
4.2 生成class
然后,编译class文件,内容如下:
package com.fr.decision;
import com.fr.cert.token.JwtBuilder;
import com.fr.cert.token.Jwts;
import com.fr.cert.token.SignatureAlgorithm;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Date;
/**
* 数字签名拦截器demo,用于url拼接数字签名证书
*/
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
//数字签名有效时长
long validTime = 30 * 60 * 1000;
//数字签名内容,以访问资源的相对路径作为内容
String path = req.getParameter("viewlet");
//数字签名用的HS256的密钥
String key = createSecret();
req.setAttribute("fine_digital_signature", createJwt("", "", path, validTime, key));
filterChain.doFilter(req, res);
}
@Override
public void destroy() {
}
private String createJwt(String issuer, String id, String subject, long validTime, String key) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
Date currentTime = new Date();
Date expirationTime = new Date(currentTime.getTime() + validTime);
JwtBuilder builder = Jwts.builder()
.setIssuer(issuer)
.setSubject(subject)
.setIssuedAt(currentTime)
.setExpiration(expirationTime)
.setId(id)
.signWith(signatureAlgorithm, key);
return builder.compact();
}
private String createSecret() {
try {
//secret可以自定义的
String secret = "123456";
String message = "";
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256Hmac.init(secret_key);
BASE64Encoder encoder = new BASE64Encoder();
String hash = encoder.encode(sha256Hmac.doFinal(message.getBytes()));
return hash;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return "";
}
}
编译出来的class,放到WEB-INF/classes/com/fr/decision目录下。
点击下载数字签名认证文件。
4.3 重启服务器
重启服务器,即可实现数字签名认证,平台根据签名来进行数字签名认证的判断
若通过认证,则显示模板:
若认证不通过,显示无权限:
注:修改秘钥地址,即可测试数字签名认证不通过的情况。