springboot接口签名(Signature)实现方案

1|0一、前言  

       由于之前写过的一片文章 (java接口签名(Signature)实现方案 )收获了很多好评,此次来说一下另一种简单粗暴的签名方案。相对于之前的签名方案,对body、paramenter、path variable的获取都做了简化的处理。也就是说这种方式针所有数据进行了签名,并不能指定某些数据进行签名。

2|0二、签名规则

  1、线下分配appid和appsecret,针对不同的调用方分配不同的appid和appsecret

  2、加入timestamp(时间戳),10分钟内数据有效

  3、加入流水号nonce(防止重复提交),至少为10位。针对查询接口,流水号只用于日志落地,便于后期日志核查。 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。

  4、加入signature,所有数据的签名信息。

  以上红色字段放在请求头中。

3|0三、签名的生成

  signature 字段生成规则如下。

3|1   1、数据部分

  Path Variable:按照path中的字典顺序将所有value进行拼接

  Parameter:按照key=values(多个value按照字典顺序拼接)字典顺序进行拼接

  Body:从request inputstream中获取保存为String形式

       

  如果存在多种数据形式,则按照body、parameter、path variable的顺序进行再拼接,得到所有数据的拼接值。

  上述拼接的值记作 Y。

3|2  2、请求头部分

  X=”appid=xxxnonce=xxxtimestamp=xxx”

3|3  3、生成签名

  最终拼接值=XY

  最后将最终拼接值按照如下方法进行加密得到签名。

  signature=org.apache.commons.codec.digest.HmacUtils.AesEncodeUtil(app secret, 拼接的值);

4|0四、签名算法实现

  注:省去了X=”appid=xxxnonce=xxxtimestamp=xxx”这部分。

4|1  1、自定义Request对象

  为什么要自定义request对象,因为我们要获取request inputstream(默认只能获取一次)。

 

public class BufferedHttpServletRequest extends HttpServletRequestWrapper {

 private ByteBuf buffer;

 private final AtomicBoolean isCached = new AtomicBoolean();

public BufferedHttpServletRequest(HttpServletRequest request, int initialCapacity) {                    super(request);

int contentLength = request.getContentLength();

int min = Math.min(initialCapacity, contentLength);

if (min < 0) {

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 可以使用 iText 库来实现 PDF 签名。以下是添加数字签名的基本步骤: 1. 导入 iText 和 BC 签名库的 Maven 依赖。 ``` xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.61</version> </dependency> ``` 2. 配置密钥库和证书。 ``` java KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream("path/to/keystore.p12"), "keystorePassword".toCharArray()); String alias = (String) ks.aliases().nextElement(); PrivateKey privateKey = (PrivateKey) ks.getKey(alias, "keyPassword".toCharArray()); Certificate[] chain = ks.getCertificateChain(alias); ``` 3. 创建 PdfReader 对象并打开文档。 ``` java PdfReader reader = new PdfReader("path/to/pdf"); PdfStamper stamper = PdfStamper.createSignature(reader, outputStream, '\0'); PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); ``` 4. 设置签名外观。 ``` java appearance.setReason("Reason for signing"); appearance.setLocation("Location of signing"); appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS); appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "signature"); ``` 5. 创建数字签名。 ``` java ExternalSignature es = new PrivateKeySignature(privateKey, "SHA-256", "BC"); ExternalDigest digest = new BouncyCastleDigest(); MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, MakeSignature.CryptoStandard.CMS); ``` 6. 关闭文档和输出流。 ``` java stamper.close(); outputStream.close(); ``` 以上步骤仅作为示例,具体实现可能因为证书类型、签名算法等不同而有所区别。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值