当前位置: 首页 > news >正文

青岛网站制作套餐网站搭建后显示建设中

青岛网站制作套餐,网站搭建后显示建设中,网站目录创建下载链接,物联网今天正式开网目录 1、加密解密原理2、项目示例2.1、项目结构2.2、常规业务代码2.3、加密的实现 2.4、接口测试2.5、总结 1、加密解密原理 客户端和服务端都可以加密和解密#xff0c;使用base64进行网络传输 加密方 字符串 - AES加密 - base64解密方 base64 - AES解密 -使用base64进行网络传输 加密方 字符串 - AES加密 - base64解密方 base64 - AES解密 - 字符串2、项目示例 2.1、项目结构 $ tree -I target -I test . ├── pom.xml └── src└── main├── java│ └── com│ └── example│ └── demo│ ├── Application.java│ ├── annotation│ │ └── SecretData.java│ ├── config│ │ ├── CrossConfig.java│ │ ├── DecryptRequestBodyAdvice.java│ │ ├── EncryptResponseBodyAdvice.java│ │ ├── SecretConfig.java│ │ └── WebMvcConfig.java│ ├── controller│ │ ├── IndexController.java│ │ └── UserController.java│ ├── request│ │ └── JsonRequest.java│ ├── response│ │ ├── JsonResult.java│ │ └── JsonResultVO.java│ ├── service│ │ ├── SecretDataService.java│ │ └── impl│ │ └── SecretDataServiceImpl.java│ └── utils│ └── CipherUtil.java└── resources├── application.yml├── static│ ├── axios.min.js│ └── crypto-js.min.js└── templates└── index.html2.2、常规业务代码 pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.7/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.example/groupIdartifactIddemo/artifactIdversion0.0.1-SNAPSHOT/versionnamedemo/namedescriptionDemo project for Spring Boot/descriptionpropertiesjava.version1.8/java.versionmybatis-plus.version3.5.2/mybatis-plus.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcommons-codec/groupIdartifactIdcommons-codec/artifactIdversion1.15/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependency!-- test --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configuration/plugin/plugins/build/project Application.java package com.example.demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} } WebMvcConfig.java package com.example.demo.config;import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;Slf4j Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {// 设置静态资源映射Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler(/static/**).addResourceLocations(classpath:/static/);} }CrossConfig.java package com.example.demo.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;/*** 处理跨域问题*/ Configuration public class CrossConfig {Beanpublic CorsFilter corsFilter() {CorsConfiguration config new CorsConfiguration();config.addAllowedOrigin(*);config.setAllowCredentials(false);config.addAllowedMethod(*);config.addAllowedHeader(*);config.setMaxAge(3600L);UrlBasedCorsConfigurationSource configSource new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration(/**, config);return new CorsFilter(configSource);} }JsonRequest.java package com.example.demo.request;import lombok.Data;/*** 统一的请求体数据*/ Data public class JsonRequest {/*** 未加密数据*/private Object data;/*** 加密数据*/private String encryptData; } JsonResult.java package com.example.demo.response;import lombok.Data;/*** 统一的返回体数据 不加密*/ Data public class JsonResultT {private String message;private T data;private Integer code;public static T JsonResult success(T data){JsonResultT jsonResult new JsonResult();jsonResult.setCode(0);jsonResult.setData(data);jsonResult.setMessage(success);return jsonResult;} } JsonResultVO.java package com.example.demo.response;import lombok.Data;/*** 统一的返回体数据 加密*/ Data public class JsonResultVO {private String message;private String encryptData;private Integer code; } IndexController.java package com.example.demo.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping;Controller public class IndexController {GetMapping(/)public String index(){return index;} } UserController.java package com.example.demo.controller;import com.example.demo.annotation.SecretData; import com.example.demo.response.JsonResult; import org.springframework.web.bind.annotation.*;import java.util.HashMap; import java.util.Map;/*** 对该Controller中的所有方法进行加解密处理*/ RestController SecretData public class UserController {GetMapping(/user/getUser)public JsonResult getUser() {MapString, String user new HashMap();user.put(name, Tom);user.put(age, 18);return JsonResult.success(user);}PostMapping(/user/addUser)public Object addUser(RequestBody MapString, String data) {System.out.println(data);return data;} } 2.3、加密的实现 application.yml secret:key: 1234567890123456 # 密钥位数为16位enabled: true # 开启加解密功能SecretData.java package com.example.demo.annotation;import org.springframework.web.bind.annotation.Mapping;import java.lang.annotation.*;/*** 只有添加有该注解的Controller类或是具体接口方法才进行数据的加密解密*/ Target({ElementType.METHOD, ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Mapping Documented public interface SecretData {}DecryptRequestBodyAdvice.java package com.example.demo.config;import com.example.demo.annotation.SecretData; import com.example.demo.request.JsonRequest; import com.example.demo.service.SecretDataService; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type;/*** 对请求内容进行解密* 只有开启了加解密功能才会生效* 仅对使用了RqestBody注解的生效* https://blog.csdn.net/xingbaozhen1210/article/details/98189562*/ ControllerAdvice // ConditionalOnProperty(name secret.enabled, havingValue true) public class DecryptRequestBodyAdvice extends RequestBodyAdviceAdapter {Resourceprivate SecretDataService secretDataService;Overridepublic boolean supports(MethodParameter methodParameter, Type targetType,Class? extends HttpMessageConverter? converterType) {return methodParameter.getMethod().isAnnotationPresent(SecretData.class)|| methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(SecretData.class);}Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,Class? extends HttpMessageConverter? converterType) throws IOException {System.out.println(beforeBodyRead);String body inToString(inputMessage.getBody());System.out.println(body);ObjectMapper objectMapper new ObjectMapper();JsonRequest jsonRequest objectMapper.readValue(body, JsonRequest.class);// 默认取data数据如果提交加密数据则解密String decryptData null;if (jsonRequest.getEncryptData() ! null) {decryptData secretDataService.decrypt(jsonRequest.getEncryptData());} else{decryptData objectMapper.writeValueAsString(jsonRequest.getData());}String data decryptData;// 解密后的数据System.out.println(data);return new HttpInputMessage() {Overridepublic HttpHeaders getHeaders() {return inputMessage.getHeaders();}Overridepublic InputStream getBody() throws IOException {return new ByteArrayInputStream(data.getBytes());}};}/*** 读取输入流为字符串** param is* return*/private String inToString(InputStream is) {byte[] buf new byte[10 * 1024];int length -1;StringBuilder sb new StringBuilder();try {while ((length is.read(buf)) ! -1) {sb.append(new String(buf, 0, length));}return sb.toString();} catch (IOException e) {throw new RuntimeException(e);}}}EncryptResponseBodyAdvice.java package com.example.demo.config;import com.example.demo.annotation.SecretData; import com.example.demo.response.JsonResult; import com.example.demo.response.JsonResultVO; import com.example.demo.service.SecretDataService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import org.springframework.beans.BeanUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import javax.annotation.Resource;/*** 对响应内容加密*/ ControllerAdvice ConditionalOnProperty(name secret.enabled, havingValue true) public class EncryptResponseBodyAdvice implements ResponseBodyAdviceObject {Resourceprivate SecretDataService secretDataService;Overridepublic boolean supports(MethodParameter returnType, Class? extends HttpMessageConverter? converterType) {return returnType.getMethod().isAnnotationPresent(SecretData.class)|| returnType.getMethod().getDeclaringClass().isAnnotationPresent(SecretData.class);}SneakyThrowsOverridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class? extends HttpMessageConverter? selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {System.out.println(beforeBodyWrite);// 仅对JsonResult对象数据加密if (body instanceof JsonResult) {JsonResult jsonResult (JsonResult) body;JsonResultVO jsonResultVO new JsonResultVO();BeanUtils.copyProperties(jsonResult, jsonResultVO);String jsonStr new ObjectMapper().writeValueAsString(jsonResult.getData());jsonResultVO.setEncryptData(secretDataService.encrypt(jsonStr));return jsonResultVO;} else {return body;}} } SecretConfig.java package com.example.demo.config;import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration;Configuration ConfigurationProperties(prefix secret) public class SecretConfig {private Boolean enabled;private String key;public Boolean getEnabled() {return enabled;}public void setEnabled(Boolean enabled) {this.enabled enabled;}public String getKey() {return key;}public void setKey(String key) {this.key key;}} SecretDataService.java package com.example.demo.service;/*** 加密解密的接口*/ public interface SecretDataService {/*** 数据加密** param data 待加密数据* return String 加密结果*/String encrypt(String data);/*** 数据解密** param data 待解密数据* return String 解密后的数据*/String decrypt(String data); } SecretDataServiceImpl.java package com.example.demo.service.impl;import com.example.demo.config.SecretConfig; import com.example.demo.service.SecretDataService; import com.example.demo.utils.CipherUtil; import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** 具体的加解密实现*/ Service public class SecretDataServiceImpl implements SecretDataService {Resourceprivate SecretConfig secretConfig;Overridepublic String decrypt(String data) {return CipherUtil.decrypt(secretConfig.getKey(), data);}Overridepublic String encrypt(String data) {return CipherUtil.encrypt(secretConfig.getKey(), data);} } CipherUtil.java package com.example.demo.utils;import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.Charset; import java.util.Base64;/*** 数据加密解密工具类* 加密后返回base64*/ public class CipherUtil {/*** 定义加密算法*/private static final String ALGORITHM AES/ECB/PKCS5Padding;/*** 解密** param secretKey* param cipherText base64* return*/public static String decrypt(String secretKey, String cipherText) {// 将Base64编码的密文解码byte[] encrypted Base64.getDecoder().decode(cipherText);try {Cipher cipher Cipher.getInstance(ALGORITHM);SecretKeySpec key new SecretKeySpec(secretKey.getBytes(), AES);cipher.init(Cipher.DECRYPT_MODE, key);return new String(cipher.doFinal(encrypted));} catch (Exception e) {throw new RuntimeException(e);}}/*** 加密** param secretKey* param plainText base64* return*/public static String encrypt(String secretKey, String plainText) {try {Cipher cipher Cipher.getInstance(ALGORITHM);SecretKeySpec key new SecretKeySpec(secretKey.getBytes(), AES);cipher.init(Cipher.ENCRYPT_MODE, key);return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes(Charset.forName(UTF-8))));} catch (Exception e) {throw new RuntimeException(e);}} } 浏览器中实现加密解密 templates/index.html !DOCTYPE html html langzh xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8 /title接口数据加密解密/title/headbody!-- 引入依赖 --!-- script srchttps://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js/script --script src/static/crypto-js.min.js/script!-- script srchttps://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.min.js/script --script src/static/axios.min.js/scripth1查看控制台/h1!-- 加密解密模块 --script typetext/javascriptconst SECRET_KEY 1234567890123456;/*** 加密方法* param data 待加密数据* returns {string|*}*/function encrypt(data) {let key CryptoJS.enc.Utf8.parse(SECRET_KEY);if (typeof data object) {data JSON.stringify(data);}let plainText CryptoJS.enc.Utf8.parse(data);let secretText CryptoJS.AES.encrypt(plainText, key, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}).toString();return secretText;}/*** 解密数据* param data 待解密数据*/function decrypt(data) {let key CryptoJS.enc.Utf8.parse(SECRET_KEY);let result CryptoJS.AES.decrypt(data, key, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);return JSON.parse(result);}/script!-- http请求模块 --script typetext/javascript// 获取加密数据并解密axios.get(http://127.0.0.1:8080/user/getUser).then((res) {console.log(接收到api返回加密数据);console.log(decrypt(res.data.encryptData));});// 提交加密参数const data {name: Tom,age: 18,};axios.post(http://127.0.0.1:8080/user/addUser, {encryptData: encrypt(data),}).then((res) {console.log(接收到api返回未加密数据);console.log(res.data);});/script/body /html2.4、接口测试 开发环境不加密更易于开发调试生产环境需要数据加密 前后端都可以通过参数 encryptData 判断对方提交/返回的数据是否为加密数据如果是加密数据则进行解密操作 接口返回加密数据 GET http://127.0.0.1:8080/user/getUser未加密的数据 {message: success,data: {name: Tom,age: 18},code: 0 }返回数据 {message: success,encryptData: kun2Wvk2LNKICaXIeIExA7jKRyqOV0qCv5KQXFOzfpQ,code: 0 }客户端提交参数 POST http://127.0.0.1:8080/user/addUser提交数据 {data: {name: Tom,age: 18} }提交加密数据 {encryptData: kun2Wvk2LNKICaXIeIExA7jKRyqOV0qCv5KQXFOzfpQ }2.5、总结 服务端 全局开关通过控制secret.enabledtrue全局开启返回数据加密全局局部可以通过SecretData或者自定义PassSecretData来控制单个控制器或者单个接口的需要或不需要加密 客户端 可以根据开发环境、测试环境、生产环境来控制是否开启加密需要注意FormData传输文件的数据格式可以考虑不加密 相同点 服务端和客户端都通过对方传输的encryptData来判断是否为加密数据服务端和客户端都可以根据自己的环境来决定是否开启数据加密 完整代码https://github.com/mouday/spring-boot-demo/tree/master/SpringBoot-Secret 参考文章 详解API接口如何安全的传输数据
http://www.hkea.cn/news/14456825/

相关文章:

  • 珠海网站建设联系方式大气html5网络公司网站源码
  • 商户如何做h5商城网站是什么意思二维码生成器怎么使用
  • h5页面制作网站官网宁金诚信建设网站
  • 九江市建设工程门户网站竞价托管是什么意思
  • sns网站设计制作网站和制作网页的分别
  • 网站正在建设中的英文wordpress 摘要显示
  • 禅城网站建设联系电话贵州网站制作品牌公司
  • 男人做爽的免费网站网站建设工作室深圳
  • 用iis制作简单网站微博推广费用
  • 网站内部优化方法手机商城 手机网站建设多少钱
  • 合肥行业网站建设网站解决访问量超载
  • html企业整站模板网站php网站费用
  • 建设银行投诉网站传奇手游代理平台价格表
  • 旅行社建设网站网页开发定制
  • 给网站怎么做tag标签单页营销网站设计
  • 自己建网站的优势网页编辑可视化软件
  • 网站开发岗位需求分析凡客诚品售后服务官方
  • 给缅甸公司网站做维护工作时间段如何看网站是不是织梦做的
  • 网站开发的一般过程外销网站建设
  • w网站建设搜索指数
  • 南宁网站优化公司哪家好东莞营销网站建
  • 做珠宝网站价格多少怎样增加网站收录量
  • 集团网站安徽省质量提升工程建设网站
  • 网站开发的几个步骤建站快车的应用场景
  • 做门的网站查wordpress模板
  • 怎么把代码添加网站wordpress留言页
  • 网站重复重庆网站建设哪家好
  • 邮票上的化学史网站开发网站建设前十名
  • 沈阳制作公司网站网站代码怎么优化
  • 实验教学网站建设策划方案大钢模板相关信息圆柱钢模板优势是什么?企业网站建设模板和定制化有什么区别呢?人工费多少钱一平方