加签验签是为了验证接收到的数据的真实性问题,但此次我的应用场景是这样的:
因为要从一个系统发送Http请求到另一个系统的域名上去获取相应的数据,但是被请求的这个域名是外网域名(任何人都能通过请求这个域名地址来获取数据),所以简单的使用签名来做一下校验,验签不通过的请求则不允许获取数据。下面是具体的实践:
1.先使用java原生类生成一对密钥,数据请求段处理:
其中公钥是用来验签,私钥用来加签,在上图中我在获取公私钥之后都对其进行了base64编码,转成String类型,这样做的原因是就可以保存在你想要保存的地方了,我是存储在了公司的配置中心上,通过配置中心获取的,当然也可以存储在静态变量中,但是建议设置为final,毕竟这个密钥对生成之后就不会再变化了。否则不配对的密钥对是无法进行正确的加签验签操作的。
由于我这只是实验代码,就简单的设置一个变量来存放了:
由于之前对密钥做了Base64的编码,首先要做的就是先将其解码
还原公钥(保存在数据提供方,用于验签):
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec (pubKeyBytes);
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
还原私钥(保存在数据请求方,用于加签):
PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(priKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(priKeySpec);
使用私钥对请求参数进行加签操作(这里模仿的是Http,application/x-www-form-urlencoded,key=value&key=value形式的请求):
因为要将生成的签名也当作参数传到数据提供端,故对sign进行Base64编码。
2.数据提供端验签处理:
3.注意点
这里有一个注意点,在做数据传输的过程中会存在一个转义问题,因为在进行数据请求端做完加签得到的签名中往往都会包含有‘+’号字符,通过http传输过来的时候往往会将'+'号转义为空格,导致验签始终是失败的(你想想,长度不一样怎么可能验签成功),所以在生成签名之后,需要对'+'号做一下特殊处理:
signStr.replaceAll("\\+", "%2B");