环境:springboot2.2.6.RELEASE,Vue+axios通过继承RequestBodyAdviceAdapter实现对请求内容的解密操作,并实现ResponseBodyAdvice对相应内容进行加密。定义加解密接口:SecretProcess.javapublicinterfaceSecretProcess{/***
数据加密
*时间:2020年12月24日-12:22:13pm
*@authorxg*@paramdata待加密数据*@returnString加密结果*/Stringencrypt(Stringdata);/***数据解密
*时间:2020年12月24日-12:23:20pm
*@authorxg*@paramdata待解密数据*@returnString解密数据*/Stringdecrypt(Stringdata);/***加密算法格式:algorithm[/mode/fill]
*时间:2020年12月24日-下午12:32:49
*@authorxg*@returnString*/StringgetAlgorithm();publicstaticclassHex{privatestaticfinalchar[]HEX={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};publicstaticbyte[]decode(CharSequences){intnChars=s.length();if(nChars%2!=0){thrownewIllegalArgumentException("十六进制数据错误");}byte[]result=newbyte[nChars/2];for(inti=0;i根据key生成不同的密钥材料
*目前支持:AES,DES
*时间:2020年12月25日-下午1:02:54
*@authorxg*@paramsecretKeyKey*@paramalgorithmAlgorithm*@returnKey*/publicKeygetKeySpec(Stringalgorithm){if(algorithm==null||algorithm.trim().length()==0){返回ull;}StringsecretKey=props.getKey();switch(algorithm.toUpperCase()){case"AES":returnnewSecretKeySpec(secretKey.getBytes(),"AES");case"DES":Keykey=null;try{DESKeySpecdesKeySpec=newDESKeySpec(secretKey.getBytes());SecretKeyFactorysecretKeyFactory=SecretKeyFactory.getInstance("DES");key=secretKeyFactory.generateSecret(desKeySpec);}catch(Exceptione){thrownewRuntimeException(e);}returnkey;default:returnull;}}/***生成密钥材料
*时间:2020-12-25-11:35:03
*@authorxg*@returnKey密钥材料*/publicabstractKeykeySpec();}该抽象类为2中的对称加密提供密钥恢复。分表是AES和DES算法的抽象方法。抽象方法keySpec需要通过子类实现(具体使用哪个对称加密算法)。具体加密算法AESAlgorithm.javapublicclassAESAlgorithmextendsAbstractSecretProcess{@OverridepublicStringgetAlgorithm(){return"AES/ECB/PKCS5Padding";}@OverridepublicKeykeySpec(){returnthis.getKeySpec("AES");}}SecretProperties.java属性配置类@的实现类配置@Bean@ConditionalOnMissingBean(SecretProcess.class)publicSecretProcesssecretProcess(){returnnewAESAlgorithm();}@Component@ConfigurationProperties(prefix="secret")publicstaticclassSecretProperties{privateBooleanenabled;privateStringkey;publicBooleangetEnabled(){returnenabled;}publicvoidsetEnabled(Booleanenabled){this.enabled=enabled;}publicStringgetKey(){returnkey;}publicvoidsetKey(Stringkey){this.key=key;}}}配置文件配置如下:secret:key:aaaabbbbbccccdddd#keyenabled:true#是否开启加密和项目中的解密函数数据中的所有方法不一定都可以加解密,所以定义一个注解接下来,只能使用Controller类或者带有注解的具体接口方法对数据进行加解密,如下:运行时)@映射@Documentedpublic@interfaceSIProtection{}对请求内容进行解密出来,通过RequestBodyAdviceDecryptRequestBodyAdivce.java@ControllerAdvice@ConditionalOnProperty(name="secret.enabled",havingValue="true")publicclassDecryptRequestBodyAdivceextendsRequestBodyAdviceAdapter{@ResourceprivateSecretProcesssecretProcess;@Overridepublicbooleansupports(MethodParametermethodParameter,TypetargetType,Class>converterType){returnmethodParameter.getMethod().isAnnotationPresent(SIProtection.class)||methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(SIProtection.class);}@OverridepublicHttpInputMessagebeforeBodyRead(HttpInputMessageinputMessage,MethodParameterparameter,TypetargetType,类>converterType)throwsIOException{Stringbody=secretProcess.decrypt(inToString(inputMessage.getBody()));returnnewHttpInputMessage(){@OverridepublicHttpHeadersgetHeaders(){returninputMessage.getHeaders();}@OverridepublicInputStreamgetBody()throwsIOException{returnnewByteArrayInputStream(body.getBytes());}};}privateStringinToString(InputStreamis){byte[]buf=newbyte[10*1024];intleng=-1;StringBuildersb=newStringBuilder();try{while((leng=is.read(buf))!=-1){sb.append(newString(buf,0,leng));}returnsb.toString();}catch(IOExceptione){thrownewRuntimeException(e);}}}这里注意:@ConditionalOnProperty(name="secret.enabled",havingValue="true")注解只有开启加解密功能才会生效注意这里的supports方法对响应内容加密出来EncryptResponseBodyAdivce.java@ControllerAdvice@ConditionalOnProperty(name="secret.enabled",havingValue="true")publicclassEncryptResponseBodyAdivceimplementsResponseBodyAdvice