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

玉树市公司网站建设快速搭建网站的工具有哪些

玉树市公司网站建设,快速搭建网站的工具有哪些,手机网站一键分享到微信,访问国外网站很慢api接口加密 1.为什么需要api接口加密呢#xff1f; 1.防止爬虫 2.防止数据被串改 3.确保数据安全 2.如何实现接口加密呢#xff1f; 3.我们可以使用哪些加密算法来加密呢#xff1f; AES 密码学中的高级加密标准#xff08;Advanced Encryption Standard#xff0c;…api接口加密 1.为什么需要api接口加密呢 1.防止爬虫 2.防止数据被串改 3.确保数据安全 2.如何实现接口加密呢 3.我们可以使用哪些加密算法来加密呢 AES 密码学中的高级加密标准Advanced Encryption StandardAES又称Rijndael加密法是美国联邦政府采用的一种区块加密标准。 SM4 SM4.0原名SMS4.0是中华人民共和国政府采用的一种分组密码标准由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》原SMS4分组密码算法”。在商用密码体系中SM4主要用于数据加密其算法公开分组长度与密钥长度均为128bit加密算法与密钥扩展算法都采用32轮非线性迭代结构S盒为固定的8比特输入8比特输出。SM4.0中的指令长度被提升到大于64K即64×1024的水平这是SM 3.0规格渲染指令长度允许大于512的128倍。 4.具体实现 4.1后端 在这之前我们先了解一个类RequestBodyAdviceAdapter主要通过该类实现~ RequestBodyAdviceAdapter 官网解释RequestBodyAdviceAdapter (Spring Framework 6.2.1 API) ‌RequestBodyAdviceAdapter‌是Spring MVC中用于增强请求体处理的一个工具类它实现了RequestBodyAdvice接口。RequestBodyAdviceAdapter提供了三个主要方法beforeBodyRead、afterBodyRead和handleEmptyBody。 ‌beforeBodyRead‌这个方法在请求体被读取之前调用主要用于预处理请求体。默认实现是直接返回传入的HttpInputMessage对象。 ‌afterBodyRead‌在请求体被读取并转换为对象之后调用用于对读取到的对象进行进一步处理。默认实现是直接返回转换后的对象。 ‌handleEmptyBody‌当请求体为空时调用用于处理这种情况。默认实现是直接返回null。 代码实现 这里我们使用类似Aop的思想实现定义对应的注解 Retention(RetentionPolicy.RUNTIME) Target({ElementType.TYPE, ElementType.METHOD}) public interface ApiDecrypt { //解密 } Retention(RetentionPolicy.RUNTIME) Target({ElementType.TYPE, ElementType.METHOD}) public interface ApiEncrypt {//加密 } ​ Slf4j ControllerAdvice public class DecryptRequestAdvice extends RequestBodyAdviceAdapter { ​private static final String ENCODING UTF-8; ​Resourceprivate ApiEncryptService apiEncryptService; ​Overridepublic boolean supports(MethodParameter methodParameter, Type targetType, Class? extends HttpMessageConverter? converterType) {return methodParameter.hasMethodAnnotation(ApiDecrypt.class) || methodParameter.hasParameterAnnotation(ApiDecrypt.class)|| methodParameter.getContainingClass().isAnnotationPresent(ApiDecrypt.class);} ​Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,Type targetType, Class? extends HttpMessageConverter? converterType) {try {String bodyStr IOUtils.toString(inputMessage.getBody(), ENCODING);ApiEncryptForm apiEncryptForm JSONObject.parseObject(bodyStr, ApiEncryptForm.class);if (StrUtil.isEmpty(apiEncryptForm.getEncryptData())) {return inputMessage;}String decrypt apiEncryptService.decrypt(apiEncryptForm.getEncryptData());return new DecryptHttpInputMessage(inputMessage.getHeaders(), IOUtils.toInputStream(decrypt, ENCODING));} catch (Exception e) {return inputMessage;} ​} ​Overridepublic Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class? extends HttpMessageConverter? converterType) {return body;} ​Overridepublic Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class? extends HttpMessageConverter? converterType) {return body;} ​static class DecryptHttpInputMessage implements HttpInputMessage {private final HttpHeaders headers; ​private final InputStream body; ​public DecryptHttpInputMessage(HttpHeaders headers, InputStream body) {this.headers headers;this.body body;} ​Overridepublic InputStream getBody() {return body;} ​Overridepublic HttpHeaders getHeaders() {return headers;}} ​ } Slf4j ControllerAdvice public class EncryptResponseAdvice implements ResponseBodyAdviceResponseDTO { ​Resourceprivate ApiEncryptService apiEncryptService; ​Resourceprivate ObjectMapper objectMapper; ​Overridepublic boolean supports(MethodParameter returnType, Class? extends HttpMessageConverter? converterType) {return returnType.hasMethodAnnotation(ApiEncrypt.class) || returnType.getContainingClass().isAnnotationPresent(ApiEncrypt.class);} ​Overridepublic ResponseDTO beforeBodyWrite(ResponseDTO body, MethodParameter returnType, MediaType selectedContentType, Class? extends HttpMessageConverter? selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body.getData() null) {return body;} ​String encrypt null;try {encrypt apiEncryptService.encrypt(objectMapper.writeValueAsString(body.getData()));} catch (JsonProcessingException e) {throw new RuntimeException(e);}body.setData(encrypt);body.setDataType(DataTypeEnum.ENCRYPT.getValue());return body;} } 实现类 /*** AES 加密和解密* 1、AES加密算法支持三种密钥长度128位、192位和256位这里选择128位* 2、AES 要求秘钥为 128bit转化字节为 16个字节* 3、js前端使用 UCS-2 或者 UTF-16 编码字母、数字、特殊符号等 占用1个字节* 4、所以秘钥Key 组成为字母、数字、特殊符号 一共16个即可*/ Slf4j public class ApiEncryptServiceAesImpl implements ApiEncryptService { ​private static final String CHARSET UTF-8; ​private static final String AES_KEY 1024lab__1024lab; ​static {Security.addProvider(new BouncyCastleProvider());} ​Overridepublic String encrypt(String data) {try {// AES 加密 并转为 base64AES aes new AES(hexToBytes(stringToHex(AES_KEY)));return aes.encryptBase64(data);} catch (Exception e) {log.error(e.getMessage(), e);return StringConst.EMPTY;}} ​Overridepublic String decrypt(String data) {try {// 第一步 Base64 解码byte[] base64Decode Base64.getDecoder().decode(data);// 第二步 AES 解密AES aes new AES(hexToBytes(stringToHex(AES_KEY)));byte[] decryptedBytes aes.decrypt(base64Decode);return new String(decryptedBytes, CHARSET);} catch (Exception e) {log.error(e.getMessage(), e);return StringConst.EMPTY;}} ​/*** 16 进制串转字节数组** param hex 16进制字符串* return byte数组*/public static byte[] hexToBytes(String hex) {int length hex.length();byte[] result;if (length % 2 1) {length;result new byte[(length / 2)];hex 0 hex;} else {result new byte[(length / 2)];}int j 0;for (int i 0; i length; i 2) {result[j] hexToByte(hex.substring(i, i 2));j;}return result;} ​public static String stringToHex(String input) {char[] chars input.toCharArray();StringBuilder hex new StringBuilder();for (char c : chars) {hex.append(Integer.toHexString((int) c));}return hex.toString();} ​/*** 16 进制字符转字节** param hex 16进制字符 0x00到0xFF* return byte*/private static byte hexToByte(String hex) {return (byte) Integer.parseInt(hex, 16);} ​public static void main(String[] args) { //       System.out.println(new ApiEncryptServiceAesImpl().encrypt({\name\:\chen\,\age\:18}));System.out.println(new ApiEncryptServiceAesImpl().decrypt(MWFjZTI3MDA0ZDcxY2RlM2U4YTY5NDU3MjE3MmE0YzlhOTI0OTVhOTBiM2VmYzYwZjgxZTlmMjRmNDVkMWNlMg));} } ​ ​ Slf4j Service public class ApiEncryptServiceSmImpl implements ApiEncryptService { ​private static final String CHARSET UTF-8;private static final String SM4_KEY 1024lab__1024lab; ​static {Security.addProvider(new BouncyCastleProvider());} ​ ​Overridepublic String encrypt(String data) {try { ​// 第一步 SM4 加密SM4 sm4 new SM4(hexToBytes(stringToHex(SM4_KEY)));String encryptHex sm4.encryptHex(data); ​// 第二步 Base64 编码return new String(Base64.getEncoder().encode(encryptHex.getBytes(CHARSET)), CHARSET); ​} catch (Exception e) {log.error(e.getMessage(), e);return StringConst.EMPTY;}} ​ ​Overridepublic String decrypt(String data) {try { ​// 第一步 Base64 解码byte[] base64Decode Base64.getDecoder().decode(data); ​// 第二步 SM4 解密SM4 sm4 new SM4(hexToBytes(stringToHex(SM4_KEY)));return sm4.decryptStr(new String(base64Decode)); ​} catch (Exception e) {log.error(e.getMessage(), e);return StringConst.EMPTY;}} ​ ​public static String stringToHex(String input) {char[] chars input.toCharArray();StringBuilder hex new StringBuilder();for (char c : chars) {hex.append(Integer.toHexString((int) c));}return hex.toString();} ​ ​/*** 16 进制串转字节数组** param hex 16进制字符串* return byte数组*/public static byte[] hexToBytes(String hex) {int length hex.length();byte[] result;if (length % 2 1) {length;result new byte[(length / 2)];hex 0 hex;} else {result new byte[(length / 2)];}int j 0;for (int i 0; i length; i 2) {result[j] hexToByte(hex.substring(i, i 2));j;}return result;} ​/*** 16 进制字符转字节** param hex 16进制字符 0x00到0xFF* return byte*/private static byte hexToByte(String hex) {return (byte) Integer.parseInt(hex, 16);} ​ } 4.2前端 axios.js import axios from axios import { decryptData, encryptData } from ./encrypt.js; ​ const requests axios.create({//共同的接口前缀baseURL: http://localhost:8881,//超时时间timeout: 2000 }); ​ //请求拦截器再发请求之前请求拦截器可以检查到可以在请求发出去之前做一些事情 requests.interceptors.request.use(config {return config }), err {return Promise.reject(err) } ​ //响应拦截器 requests.interceptors.response.use(response {// 如果是加密数据if (response.data.dataType 10) {response.data.encryptData response.data.data;let decryptStr decryptData(response.data.data);if (decryptStr) {response.data.data JSON.parse(decryptStr);}}return response.data }, err {return Promise.reject(err) }) ​ // 加密 /*** 加密请求参数的post请求*/ export const postEncryptRequest (url, data) {return requests({data: { encryptData: encryptData(data) },url,method: post,}); }; ​ ​ /*** post请求*/ export const postRequest (url, data) {return requests({data,url,method: post,}); }; ​ /*** get请求 /api?encryptDataxxx*/ export const getEncryptRequest (url, data) {return requests({params: { encryptData: encryptData(data) },url,method: get,}); }; 前端加密 import CryptoJS from crypto-js; import CryptoSM from sm-crypto; ​ function object2string(data) {if (typeof data object) {return JSON.stringify(data);} ​let str JSON.stringify(data);if (str.startsWith() || str.startsWith()) {str str.substring(1);}if (str.endsWith() || str.endsWith()) {str str.substring(0, str.length - 1);}return str; } /*** 字符串转为数字*/ function stringToHex(str) {let hex ;for (let i 0; i str.length; i) {hex str.charCodeAt(i).toString(16).padStart(2, 0);}return hex; } ​ /** -------------------- ※ AES 加密、解密 begin ※ --------------------** 1、AES加密算法支持三种密钥长度128位、192位和256位这里选择128位* 2、AES 要求秘钥为 128bit转化字节为 16个字节* 3、js前端使用 UCS-2 或者 UTF-16 编码字母、数字、特殊符号等 占用1个字节* 4、所以秘钥Key 组成为字母、数字、特殊符号 一共16个即可** -------------------- ※ AES 加密、解密 end ※ --------------------*/ const AES_KEY 1024lab__1024lab; const AES {encryptData: function (data) {// AES 加密 并转为 base64let utf8Data CryptoJS.enc.Utf8.parse(object2string(data));const key CryptoJS.enc.Utf8.parse(AES_KEY);const encrypted CryptoJS.AES.encrypt(utf8Data, key, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7,});return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);}, ​decryptData: function (data) {// 第一步Base64 解码let words CryptoJS.enc.Base64.parse(data); ​// 第二步AES 解密const key CryptoJS.enc.Utf8.parse(AES_KEY);return CryptoJS.AES.decrypt({ ciphertext: words }, key, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7,}).toString(CryptoJS.enc.Utf8);}, }; ​ /** -------------------- ※ 国密SM4算法 加密、解密 begin ※ --------------------** 1、国密SM4 要求秘钥为 128bit转化字节为 16个字节* 2、js前端使用 UCS-2 或者 UTF-16 编码字母、数字、特殊符号等 占用1个字节* 3、java中 每个 字母数字 也是占用1个字节* 4、所以前端和后端的 秘钥Key 组成为字母、数字、特殊符号 一共16个即可** -------------------- ※ 国密SM4算法 加密、解密 end ※ --------------------*/ ​ // 秘钥Key 组成为字母、数字、特殊符号 一共16个即可 const SM4_KEY 1024lab__1024lab; ​ const SM4 {encryptData: function (data) {// 第一步SM4 加密let encryptData CryptoSM.sm4.encrypt(object2string(data), stringToHex(SM4_KEY));// 第二步 Base64 编码return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(encryptData));}, ​decryptData: function (data) {// 第一步Base64 解码let words CryptoJS.enc.Base64.parse(data);let decode64Str CryptoJS.enc.Utf8.stringify(words); ​// 第二步SM4 解密return CryptoSM.sm4.decrypt(decode64Str, stringToHex(SM4_KEY));}, }; ​ ​ ​ // ----------------------- 对外暴露 加密、解密 ----------------------- ​ // 默认使用SM4算法 const EncryptObject SM4; // const EncryptObject AES; ​ /*** 加密*/ export const encryptData function (data) {return !data ? null : EncryptObject.encryptData(data); }; /*** 解密*/ export const decryptData function (data) {return !data ? null : EncryptObject.decryptData(data); }; api.js import { postRequest, postEncryptRequest, getEncryptRequest } from /utils/axios.js; // 测试获取列表 双向加密 export const getList (data) {return postEncryptRequest(/api/test/getList,data) } ​ export const getListOfTetsGet (data) {return getEncryptRequest(/api/testget/getList,data) } ​ // 请求加密paramsAes export const getListParamsAes (data) {return postEncryptRequest(/api/paramsAes/getList,data) } ​ // 响应加密 /resAes/getList export const getListResAes (data) {return postRequest(/api/resAes/getList,data) } vue界面 templatedivel-button typeprimary clickaes发送加密请求/el-buttonel-button typeprimary clickparamsAsc请求体加密/el-buttonel-button typeprimary clickreqAsc返回加密/el-button ​divel-table :datatableData border stylewidth: 100%el-table-column proptitle label书标题/el-table-columnel-table-column propauthor label作者/el-table-columnel-table-column propprice label价格/el-table-columnel-table-column fixedright label操作 width100template slot-scopescopeel-button clickhandleClick(scope.row) typetext sizesmall查看/el-buttonel-button typetext sizesmall编辑/el-button/template/el-table-column/el-table/div/div /template ​ scriptimport { getList, getListParamsAes, getListResAes, getListOfTetsGet } from /api/test.jsexport default {name: HelloWorld,props: {msg: String},data() {return {tableData: []}},mounted() {this.aes()},methods: {aes() {getList({ pageNum: 1, pageSize: 3 }).then(res {if (res.code 0) {this.tableData res.data}})},paramsAsc() {getListParamsAes({ pageNum: 1, pageSize: 3 }).then(res {console.log(res);})},reqAsc() {getListResAes({ pageNum: 1, pageSize: 3 }).then(res {console.log(res);})}},} /script 5.测试结果 双向加密 请求体加密 响应体加密 6.声明 该案例参考于开源的smartadmin项目该项目类似于若依整体代码比较规范推荐使用~ 官网地址SmartAdmin | 1024创新实验室 gitee地址smart-adminMIT协议-免费任意商用: SmartAdmin以「高质量代码」为核心「简洁、高效、安全」的快速开发平台基于SpringBoot2/3Sa-TokenMybatis-Plus和Vue3 Ant Design VueUniApp (提供JavaScript和TypeScript双版本、Java8和java17双版本)满足三级等保、网络安全、数据安全等功能要求。并重磅开源千余家企业在使用的《高质量代码规范》等
http://www.eeditor.cn/news/119431/

相关文章:

  • 聊城公司网站建设帮朋友做网站 知乎
  • 抽奖的网站怎么做的网站建设一般预付比例多少
  • 毕业设计网站模板微信公众号的网站超链接怎么做
  • 献县做网站广东网站建设哪家专业
  • 济南网站搜索排名app开发比较好的公司
  • 大庆企业做网站东莞网站建设制作公司
  • 网站效果图设计方案wordpress默认主题12
  • 做网站界面重庆专业微信网站制作
  • 钓鱼网站怎么制作html教做布艺的网站
  • 怎样创建网站发招聘信息wordpress快速建站
  • 住房和城乡建设部网站唐山建设商城网站公司
  • 眼镜网站源码哪个网站做外贸零售比较好呢
  • 行业自建网站营销型网站建设公司比较专业
  • 体育网站界面该怎样做网站 盈利模式
  • 购物网站 系统设计wordpress网站运行时间代码
  • 东莞东城网站建设公司做团购网站哪家好些
  • 手机网站设计尺寸网页制作人员的工作内容
  • 做网站需完成的软件wordpress网址导航页面
  • 抚州网站开发机构企业网站建设商城
  • 360提示危险的网站大数据对网站建设教育的影响
  • 德阳建设公司网站网站建设的难点
  • 东莞网站推广营销软件开发网站开发
  • 廊坊怎么做网站免费域名申请方法
  • 官方网站制作河南省汝州市建设网站
  • 网盘网站开发做营销网站应该要注意些什么
  • 外贸导向企业网站深圳外贸公司有哪些公司
  • 网站建设 加强宣传鲜花网网站建设的目的
  • 哈尔滨网站建设招聘电子商务平台运营是做什么的
  • 免费网络电话呼叫系统搜索引擎优化是什么?
  • 企业网站推广排名合肥免费做网站