城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

SpringBoot接口加解密全过程详解

6月10日 老巫婆投稿
  一、接口为什么要加密
  接口加密传输,主要作用:敏感数据防止泄漏、保护隐私、防伪装攻击、防篡改攻击、防重放攻击等等4个字概括:保护数据!
  当然不是说接口加密后,就能完完全全的保护我们的数据,但至少能防一部分人拿到我们的数据。
  而且接口加密感觉逼格是不是高过一点!!!二、加密思路1、加密简介
  加密算法有很多,在能加密又能解密的算法可分为:非对称加密算法,常见:RSA、DSA、ECC
  特点:算法复杂,加解密速度慢,但安全性高,一般与对称加密结合使用(对称加密对内容加密,非对称对对称所使用的密钥加密)对称加密算法,常见:DES、3DES、AES、Blowfish、IDEA、RC5、RC6
  特点:加密解密效率高,速度快,适合进行大数据量的加解密2、加密流程
  思路:
  假设现在客户端是A,服务端是B,现在A要去B请求接口1、A要向B发送信息,A和B都要产生一对用于加密的非对称加密公私钥(AB各自生成自己的公私钥)2、A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。(AB互换公钥)3、A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。(公钥加密只有私钥能解)4、A将这个消息发给B(已经用B的公钥加密消息)。5、B收到这个消息后,B用自己的私钥解密A的消息。其他人收到这个报文都无法解密,因为只有B才有B的私钥。
  虽然这样就实现了接口的加密方式,但是呢,非对称加密的加解密速度相比对称加密速度很慢,当传输的数据很大时就更加明显了。
  所以我们对称与非对称一起用,理解上面的流程之后,我们在其基础稍微改下:在A给B发信息的时候,随机生成一个对称加密的密钥,然后用刚生成的密钥加密信息,然后用B的公钥加密刚生成的对称密钥。A把加密的两个信息发送给B。B收到数据之后,先用自己的私钥解开得到对称密钥,然后再用解开的对称密钥解开对称加密的信息,最终得到A传来的信息。三、代码实现在当下Java还是SpringBoot为主流框架工作面试必备,今天还是以它来举例。加解密代码怎么写,这个时候网上已经有很多现成的库了,不用我们操心,我们想的是如何在接口加解密的时候不影响我们自己的业务,也就是不用更改我们已经写好的代码。很多人的第一反应应该就是AOP吧,对的没错可以使用AOP进行环绕增强。也可以使用ControllerAdvice对Controller进行增强(本文以它来做为例子)。Spring提供两个接口RequestBodyAdvice、ResponseBodyAdvice。实现它们,即可对Controller进行增强,第一个是在controller之前增强,第二个就是对controller的返回值进行增强。在spring启动的时候会对RequestMappingHandlerAdapter的initControllerAdviceCache()方法进行初始化。会去把有ControllerAdvice的类进行注入。1、自定义类
  下面就来实现上面的两个接口实现类代码EncryptRequestAdvice。java这个类的功能就是在请求到controller之前就把前端传上来的数据解密好我们还要校验是否有必要解密ControllerAdvice(basePackages{top。lrshuai。encrypt。controller})publicclassEncryptRequestAdviceimplementsRequestBodyAdvice{AutowiredprivateKeyConfigkeyC是否需要解码privatebooleanisDOverridepublicbooleansupports(MethodParametermethodParameter,Typetype,C?extendsHttpMessageC?aClass){方法或类上有注解if(Utils。hasMethodAnnotation(methodParameter,newClass〔〕{Encrypt。class,Decode。class})){isD这里返回true才支持}}OverridepublicHttpInputMessagebeforeBodyRead(HttpInputMessagehttpInputMessage,MethodParametermethodParameter,Typetype,C?extendsHttpMessageC?aClass)throwsIOException{if(isDecode){returnnewDecodeInputMessage(httpInputMessage,keyConfig);}returnhttpInputM}OverridepublicObjectafterBodyRead(Objectobj,HttpInputMessagehttpInputMessage,MethodParametermethodParameter,Typetype,C?extendsHttpMessageC?aClass){这里就是已经读取到body了,obj就是}OverridepublicObjecthandleEmptyBody(Objectobj,HttpInputMessagehttpInputMessage,MethodParametermethodParameter,Typetype,C?extendsHttpMessageC?aClass){body为空的时候调用}}在上面实现类中需要重写:supports()、beforeBodyRead()、afterBodyRead()、handleEmptyBody()方法只有在supports()返回true后面的方法才会支持执行。在RequestResponseBodyAdviceChain有判断我们可以在beforeBodyRead()这个方法进行解密处理。在上面的代码中,我加了自定义注解,因为可能需求是这样的,有些接口加密有些接口不加密,用自定义注解比较方便。然后DecodeInputMessage这个类是自定义实现了HttpInputMessage接口,解码逻辑都在里面。如下:DecodeInputMessage。java
  这个类就是具体的解码逻辑了publicclassDecodeInputMessageimplementsHttpInputMessage{privateHttpHprivateInputSpublicDecodeInputMessage(HttpInputMessagehttpInputMessage,KeyConfigkeyConfig){这里是body读取之前的处理this。headershttpInputMessage。getHeaders();StringencodeAesKListStringkeysthis。headers。get(Result。KEY);if(keys!nullkeys。size()0){encodeAesKeykeys。get(0);}try{1、解码得到aes密钥StringdecodeAesKeyRsaUtils。decodeBase64ByPrivate(keyConfig。getRsaPrivateKey(),encodeAesKey);2、从inputStreamReader得到aes加密的内容StringencodeAesContentnewBufferedReader(newInputStreamReader(httpInputMessage。getBody()))。lines()。collect(Collectors。joining(System。lineSeparator()));3、AES通过密钥CBC解码StringaesDecodeAesUtils。decodeBase64(encodeAesContent,decodeAesKey,keyConfig。getAesIv()。getBytes(),AesUtils。CIPHERMODECBCPKCS5PADDING);if(!StringUtils。isEmpty(aesDecode)){4、重新写入到controllerthis。bodynewByteArrayInputStream(aesDecode。getBytes());}}catch(Exceptione){e。printStackTrace();}}OverridepublicInputStreamgetBody()throwsIOException{}OverridepublicHttpHeadersgetHeaders(){}}上面的代码注释我觉得都写的清楚了,不多介绍。EncryptResponseAdvice。java这个类的主要功能就是对返回值进行加密操作直接在beforeBodyWrite()里面执行具体的加密操作即可supports()方法也是需要返回true,在RequestResponseBodyAdviceChain。processBody()中有个判断只有supports()返回true才会执行beforeBodyWrite()Slf4jControllerAdvice(basePackages{top。lrshuai。encrypt。controller})publicclassEncryptResponseAdviceimplementsResponseBodyAdviceObject{AutowiredprivateKeyConfigkeyCOverridepublicbooleansupports(MethodParametermethodParameter,C?extendsHttpMessageC?aClass){returntrue有效}返回结果加密paramobj接口返回的对象parammethodParametermethodparammediaTypemediaTypeparamaClassHttpMessageConverterclassparamserverHttpRequestrequestparamserverHttpResponseresponsereturnobjOverridepublicObjectbeforeBodyWrite(Objectobj,MethodParametermethodParameter,MediaTypemediaType,C?extendsHttpMessageC?aClass,ServerHttpRequestserverHttpRequest,ServerHttpResponseserverHttpResponse){方法或类上有注解if(Utils。hasMethodAnnotation(methodParameter,newClass〔〕{Encrypt。class,Encode。class})){这里假设已经定义好返回的model就是Resultif(objinstanceofResult){try{1、随机aes密钥StringrandomAesKeyAesUtils。generateSecret(256);2、数据体Objectdata((Result)obj)。getData();3、转json字符串StringjsonStringJSON。toJSONString(data);4、aes加密数据体StringaesEncodeAesUtils。encodeBase64(jsonString,randomAesKey,keyConfig。getAesIv()。getBytes(),AesUtils。CIPHERMODECBCPKCS5PADDING);5、重新设置数据体((Result)obj)。put(Result。DATA,aesEncode);6、使用前端的rsa公钥加密aes密钥返回给前端((Result)obj)。put(Result。KEY,RsaUtils。encodeBase64PublicKey(keyConfig。getFrontRsaPublicKey(),randomAesKey));7、返回}catch(Exceptione){log。error(加密失败:,e);}}}}}
  看代码注释,不说了。2、加密工具类
  加密工具类,我在网上收集整理了一下,搞了个jar。直接在pom。xml引入即可。如下:dependencygroupIdtop。lrshuai。encryptiongroupIdencryptiontoolsartifactIdversion1。0。3versiondependency
  自此核心代码都讲完了,这里只是给出了个demo,可以参考一下(代码写的也不是很好,很多地方也没有封装),加密方式多种多样,都是可以自由更改,这种加密方式不喜欢就改。
  差点忘记了,前端代码呢。3、前端代码
  前端也是在Github分别找了两个库:jsencrypt
  这个是RSA加密库,这个是在原版的jsencrypt进行增强修改,原版的我用过太长数据加密失败,多此加密解密失败,所以就用了这个库。CryptoJS
  AES加密库,这个库是Google开源的,有AES、MD5、SHA等加密方法
  然后我使用的是Vue写的简单页面(业余前端)html!DOCTYPEhtmlhtmllangenxmlns:thhttp:www。thymeleaf。orgheadmetacharsetUTF8title请求titlestyleapp{width:500height:500margin:100}。mytable{border:1pxsolidA6C1E4;fontfamily:Abordercollapse:}tableth{border:1backgroundcolor:71c1width:100height:20fontsize:15}tabletd{border:1pxsolidA6C1E4;textalign:height:15paddingtop:5fontsize:12}。double{backgroundcolor:c7dff6;}input{width:95;paddingleft:10}styleheadbodytableclassmytabletrclassdoubleth字段:ththValue:thtrtrclassdoubletduserId:tdtdinputvmodeluserInfo。userIdtdtrtrclassdoubletduserName:tdtdinputvmodeluserInfo。userNametdtrtrclassdoubletdage:tdtdinputvmodeluserInfo。agetdtrtrclassdoubletdinfo:tdtdtextareavmodeluserInfo。infocols50rows5placeholder随便输一点textareatdtrtrclassdoubletdAES密钥:tdtdtextareavmodelaes。keycols50rows2placeholderAES密钥textareatdtrtrclassdoubletdAES向量:tdtdtextareavmodelaes。ivcols50rows1placeholder向量的长度为16位textareatdtrtablebuttonclicktestRequest发送测试请求button
  p要发送的数据:span{{parameter}}spanp加密后的数据:{{encodeContent}}
  p收到服务端的内容:{{result}}p解密服务端AES密钥内容:{{decodeAes}}p最终拿到服务端的内容:{{decodeContent}}bodyhtml
  主要看testRequest()这个方法就行了,都有代码注释。注意点后端需要注意的就是,controller参数需要用RequestBody包起来,如下:PostMapping(test1)
  ResponseBody
  publicObjecttest1(RequestBody(requiredfalse)TestDtodto){
  System。out。println(dtodto);
  returnResult。ok(dto);
  }而前端传上来的时候header需要设置ContentType:charsetutf8最终效果
  在上面的postman中data:里面的数据就是aes加密后的数据key:里面就是前端RSA公钥加密后的AES密钥(前端需要用私钥解密得到aes密钥,然后再用密钥解开data里面的数据)status:这个是状态码,如果报错了就不是200,不然报错了返回的数据,前端解几百年都解不开。4、源码地址https:gitee。comrstyrospringboottreemasterSpringboot2apiencrypt作者:rstyro来源:https:rstyro。github。ioblog20201022Springboot2接口加解密全过程详解(含前端代码)
投诉 评论 转载

莫让劳动实践基地成为花瓶近年来,不论规模大小、地处城镇还是乡村,大部分学校都为学生开辟了劳动实践基地,瓜果蔬菜排列有序、布阵整齐。然而,对比不同规模的劳动实践基地,发现这样一种奇怪的现象:学校的……SpringBoot接口加解密全过程详解一、接口为什么要加密接口加密传输,主要作用:敏感数据防止泄漏、保护隐私、防伪装攻击、防篡改攻击、防重放攻击等等4个字概括:保护数据!当然不是说接口加密后,就能完完全……只需一秒微信就能把纸上的文字复制到手机平时我们在整理资料的时候,经常需要把资料上的文字转成电子档。最通常的办法,就是直接对着文字在电脑上打出来,但这种方法太累,又耗时间。今天给大家分享一个可以,把书里面……资料员技术工作总结精选多篇第一篇:资料员专业技术工作总结资料员专业技术工作总结2014年7月毕业于大学环境工程专业,2014年10月进入公司工作,现就职于公司部。自参加工作以来,遵守公……人工智能很能搞创意,大力出奇迹!AIGC你用了吗?最近,美国《科学》杂志发布了2022年度科学十大突破,评选过去一年重大的科学发现、进展与趋势。在入选的科学突破中,AIGC作为人工智能领域的重要突破赫然在列。AIGC全称……回答一下网友的私信提问我发的这篇文章处于如下几个目的性:1。回答一下曾经私信咨询我的问题。2。曝光一下网络上虚假宣传的卖家。事情的起因也是在今年过年期间,各大网购平台多次的给我推荐……网站建设行业会伴随互联网的变化而变化现在互联网的时代已经到来。网站建设会发生什么样的变化?在这种环境下,将消除对公约的遵守。只有变革和创新才能带来新的突破。网站建设的未来发展趋势是什么?1、安全性在网站建设……老人每天要多摸摸自己个小动作透露心脑血管疾病信息高血压、脑梗等已成为威胁老年人健康的重大杀手,其实,日常通过检查身体的一些表征,就可以自我发现疾病的潜在征兆,达到早预防、早发现、早治疗的目的。下面和小编一起来看看具体哪些表征……镜面草长虫怎么办镜面草可能会长出蚜虫、介壳虫、吹绵蚧、红蜘蛛等虫,首先需要判断是长什么虫害,然后用刷子给其进行人工去虫,减少虫害给植株的危害,并将发黄的枝叶剪掉,喷洒对应的杀虫药剂防治,改善其……时评非婚生育,应以孩子为重钱江晚报小时新闻评论员戎国强近日,四川省卫健委宣布生育登记取消了结婚限制,把夫妻应当在生育前进行生育登记改成了凡生育子女的公民,均应办理生育登记。这一改变,意味着生育不再……热辐射对人体有害的吗辐射是一种我们看不见摸不到的东西,而且在我们生活当中随处可有,辐射是一种对人身体有着危害的情况,平时的时候一定要注意,特别是热辐射对我们的身体同样存在着危害性,在平时的时候我们……步长制药跌停预计2022年亏损约15。84亿元19。36亿元1月31日早盘,步长制药大幅低开,截至发稿已封死跌停报19。18元,成交金额超3亿元。消息面,步长制药1月30日晚间公告,预计2022年公司亏损约15。84亿元19。36……
如何预防儿童抽动症加拿大入籍考试考些什么以及考前准备怎么我们为什么应该了解一下特斯拉和马斯克阿里资深架构师三年整理分享java面试核心知识点原理篇文档白塔湖湿地迎来大批越冬候鸟生物多样性不断丰富感冒时跑步有哪些危害京东方将超越Samsung成为iPhone最大屏幕供应商世界上最纯种的藏獒海蓝兽菩萨的坐骑有钱也买不到学生冬季体育锻炼注意事项沃恩我们一直在谈论精彩的世界杯决赛我们今天让比赛更刺激了爱祖国爱家乡冬至吃什么
多姿多彩的云这6个女性文案,很强硬会计职业道德教育要从学生抓起大灰狼和迷路的孩子希腊驻华大使乔治伊利奥普洛斯能够参与火炬接力深感自豪憨憨是什么意思,铁憨憨什么梗来源哪里呢?冬季潮流烫发发型塑造魅力气质女神老舍的原名叫什么老舍笔名的由来老舍笔名的含义动物世界蛇的天敌大盘点蛇獴只能算第二第一竟是它教大家360英文搜索怎么用大学生表白墙翻车,同学看后礼貌提醒,你找的是我对象四年级写字的教学工作计划

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁