对外接口,需要校验一下是否有相应权限,简单的一个小代码。

res加密util;

/*** @description: AES加密解密工具* @author:mic* @create: **/
public class AESUtil {/*** AES加密字符串** @param content*            需要被加密的字符串* @param  password*            加密需要的密钥  String password = "123654";* @return 密文*/public static String encrypt(String content ,String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出// 128位的key生产者//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回// null。SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES");// 创建密码器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器byte[] result = cipher.doFinal(byteContent);// 加密return parseByte2HexStr(result);//将二进制密文转换成16进制字符串} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/*** 解密AES加密过的字符串** @param content*            AES加密过过的内容* @param password*            加密时的密钥* @return 明文*/public static String decrypt(String content, String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者kgen.init(128, new SecureRandom(password.getBytes()));SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器byte[] bytesContent = parseHexStr2Byte(content);byte[] result = cipher.doFinal(bytesContent);return new String(result); // 明文} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/**将二进制转换成16进制* @param buf* @return*/public static String parseByte2HexStr(byte buf[]) {StringBuffer sb = new StringBuffer();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/**将16进制转换为二进制* @param hexStr* @return*/public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1)return null;byte[] result = new byte[hexStr.length()/2];for (int i = 0;i< hexStr.length()/2; i++) {int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);result[i] = (byte) (high * 16 + low);}return result;}public static void main(String[] args) {System.out.println(JSON.parseObject("{\"stationId\":1, \"stationName\":\"test\"}"));System.out.println(AESUtil.encrypt("{\"stationId\":1}", "test"));}
}

验签切面类:

@Aspect
@Component
public class SignAspect {Logger logger = LoggerFactory.getLogger(this.getClass());private static final Map<String, String> accessKeyMap = new HashMap<String, String>(){{put("test", "test2021");}};/*** 切入点*/@Pointcut(value = "@annotation(com.sc.Test.support.annotation.Sign)") //对应的sign注解类private void pointcut() {}@Around("pointcut()")public Object Around(ProceedingJoinPoint pjp) throws Throwable {ResultBean result = new ResultBean();HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();// 验证签名,在目标方法前执行//获取请求头中信息,生成密钥,用于解密参数String signApp = request.getHeader("sign");String accessKey = request.getHeader("accessKey");if (StringUtils.isEmpty(accessKey) ) {result.setResultMsgEnum(ResultMsgEnum.RESULT_MSG_UNAUTHORITY);throw new RuntimeException(result.getMsg());}// 1.先根据access_key做一个简单的判断,判断当前用户是否可以访问此接口//不存在当前access_key直接返回结果if (accessKeyMap.get(accessKey) == null) {result.setResultMsgEnum(ResultMsgEnum.RESULT_MSG_UNAUTHORITY);throw new RuntimeException(result.getMsg());}String password = accessKeyMap.get(accessKey);//2.获取请求体的明文String param = JSONObject.toJSONString(pjp.getArgs()).replace("[", "").replace("]", "");//解密参数String paramContent = AESUtil.decrypt(signApp, password);//3.验签Map<String, Object> paramMap = JSON.parseObject(param, Map.class);Map<String, Object> paramContentMap = JSON.parseObject(paramContent, Map.class);for (Map.Entry<String, Object> entry : paramMap.entrySet()){if (entry.getKey().toLowerCase().contains("time")){String tempTime = DateUtil.timeStamp2Date((long)entry.getValue());if (!tempTime.equals(paramContentMap.get(entry.getKey()))){result.setResultMsgEnum(ResultMsgEnum.RESULT_MSG_UNAUTHORITY);//权限不足throw new RuntimeException(result.getMsg());}}else {if (!entry.getValue().equals(paramContentMap.get(entry.getKey()))){result.setResultMsgEnum(ResultMsgEnum.RESULT_MSG_UNAUTHORITY);//权限不足throw new RuntimeException(result.getMsg());}}}return pjp.proceed();}}

@Sign 注解类

/*** 方法签名加密的注解,供接口对拿有密钥第三方用户开放* * @author test**/
@Target(value = { ElementType.METHOD })
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
public @interface Sign {  }  

需要校验的地方加上sign注解即可:

@Sign
@PostMapping("/stationTest")
@ResponseBody
public ResultBean<String> saveOrUpdateStationTest(@RequestBody Station station){return  stationService.saveOrUpdateStationTest(station);
}

第三方调用时,需要按照相关规定将对应类容加密,将密文和秘钥放在heard中,还有当前的明文放在请求体中传过来。

public static void main(String[] args) {try {System.out.println(AESUtil.encrypt("{\"stationId\":2,\"stationName\":\"211\"}", "test2021"));} catch (Exception e) {e.printStackTrace();System.out.print("加解密异常");}
}

Java简单的对外接口验签相关推荐

  1. 基于appKey和md5算法的接口验签方式

    1.为什么要接口验签? 平常我们开发的时候,系统都会有个登录功能,登录的账号可能是公司内部的OA系统账号,通过登录得到的token,可以进行验证接口请求者的身份. 当我们提供一些接口给其它公司的时候, ...

  2. aop java 接口_Spring AOP实现接口验签

    因项目需要与外部对接,为保证接口的安全性需要使用aop进行方法的验签; 在调用方法的时候,校验外部传入的参数进行验证, 验证通过就执行被调用的方法,验证失败返回错误信息: 不是所有的方法都需要进行验签 ...

  3. 企业微信回调接口验签

    文章目录 一.企业微信配置参数 二.验签 三.企业微信客户联系回调 四.相关工具类 企业微信提供了回调接口,允许企业服务商和企业应用接收到企业微信的事件通知和用户操作通知.在接收到回调通知时,需要进行 ...

  4. JAVA/PHP/C#版RSA验签--转

    本文是上一篇文章的兄弟篇,上篇文章介绍了客户端的sdk中如何基于JAVA/PHP/C#使用RSA私钥签名,然后服务端基于JAVA使用RSA公钥验签,客户端签名/服务端验签的模式只能帮助服务端检查客户端 ...

  5. php支付接口验签,银联支付接口开发php版

    官方文档:https://open.unionpay.com/ajweb/help/file/techFile?productId=1 api辅助工具:https://open.unionpay.co ...

  6. 新版支付宝WAP支付成功回调接口验签失败问题解决办法

    支付宝旧版回调验签使用的是  AlipayNotify.verify(params),新版本采用的是AlipaySignature.rsaCheckV1,AlipaySignature类在新版SDK包 ...

  7. java 国密p7验签_go/Java 国密sm2签名验签

    近期go项目对接第三方Java服务,第三方要求使用国密sm3/sm2算法进行数据签名验签,特记录go端开发注意事项 1 关于密钥对 密钥生成可以使用openssl库,openssl版本至少是1.1.1 ...

  8. 关于淘宝奇门接口验签问题

    最近做了一个奇门接口对接问题.遇到了验签问题,特和大家分享下. 目前的需求是在奇门发布一个接口.本地接口是post请求,参数在body中存储. 奇门的接口配置流程可以参考官方文档如下链接内容: 开放平 ...

  9. 支付宝回调接口验签失败

    按照支付宝的文档,调用rsaCheckV1的方法,他已经把方法封装的很透彻了,只需要将取到的参数Map(request.getParameterMap())集合放入即可. 但是验签一直不通过,查了很多 ...

最新文章

  1. python爬取糗事百科
  2. vb6 combo根据index显示选项内容_按指定次数重复显示,两种方法随意选
  3. ThinkPHP3.2.3快速入门 · 看云
  4. sharepoint服务器安装已安装netframework4.5,仍提示未安装
  5. PDF控件Aspose.Pdf 12月新版17.12发布 | 附下载
  6. GlobalMapper--去除tif影像黑边
  7. 从算法原理到应用部署!微信「扫一扫识物」 的背后技术揭秘
  8. 学计算机拼音摇号,拼音真的很难教?要不要提前学?我们一起陪娃做好这些就够了!...
  9. centos启动停留在started GNOME display manager
  10. 特岗计算机考试面试,你应该知道的特岗教师面试注意事项!快来收藏吧!
  11. 图片不超过200kb怎么调整?一分钟学会图片压缩到指定大小
  12. 3d可视化虚拟建模vr展示三维模型方案
  13. .基金从业资格考试信息
  14. idea 导入halo报错
  15. 在个人网站里搭建了自己的随机图片接口~
  16. 图片文字怎么转换成文本?可以试试这三种途径
  17. 【编程随想】聊聊分布式散列表(DHT)的原理——以 Kademlia(Kad) 和 Chord 为例
  18. 虚拟机克隆后MAC地址IP地址修改
  19. 软件质量管理的方法、工具和保证
  20. 转:为什么内向的人,更适合当领导?

热门文章

  1. html设置表格点击变色,js实现表格变色点击行颜色改变
  2. 计算机不小心办公软件,电脑表格不小心删除怎么恢复-互盾数据恢复软件
  3. 服务器指令显示字幕,gdc服务器字幕设置
  4. 我又来分享来了,发现一个好的ide,免费的国产的,优秀的,自带md阅读器.那就是uni-app
  5. android连接雷电模拟器,android studio连接雷电模拟器 【AS 模拟器】
  6. 如何破解软件狗,dongle
  7. CSS设置表格行列,给bootstrap table设置行列单元格样式
  8. Gameplay - 设计使命召唤类型的关卡
  9. ipad协议临时号828版
  10. c语言多组变量输入数据,C/C++中输入多组数据的方法