活动介绍
file-type

SafeRequest加密库:AES与RSA加密解密功能介绍

ZIP文件

下载需积分: 9 | 7KB | 更新于2024-11-18 | 70 浏览量 | 0 下载量 举报 收藏
download 立即下载
该库设计的初衷是为了在安全文件共享服务中提供安全的数据加密和解密功能。它封装了AES和RSA两种加密算法,且与特定的框架有着紧密的依赖关系。库中重要的功能包括使用RSA-OAEP算法生成密钥对,以及使用公钥对字符串进行加密和使用私钥进行解密。此外,文档中提到了一些待完成的任务,如添加单元测试、改善自述文件等,说明库的完整性和用户体验仍在优化中。" 知识点详细说明: 1. 加密与解密基础概念: 加密是将明文数据转换为密文数据的过程,以防止未授权的访问和理解。解密则是将密文还原为明文的过程。加密和解密通常依赖于密钥,这些密钥是确保数据安全的关键因素。 2. AES加密算法: AES(高级加密标准)是一种对称密钥加密算法,广泛用于各种安全通信协议。AES加密使用同一个密钥进行加密和解密。对称加密的优点是速度快,效率高,但密钥的管理和分发需要安全的保障。 3. RSA加密算法: RSA是一种非对称加密算法,使用一对密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据。RSA算法依赖于数学中的大数分解问题,因此提供较高的安全性。该库中提到使用SHA-256摘要算法和4096位密钥长度,表明了较高的安全标准。 4. CryptoKey对象: CryptoKey是Web加密API中的一个接口,用于表示密钥。在Web加密API中,密钥可以以多种格式存在,而CryptoKey对象可以用来表示这些密钥。在JavaScript中操作加密功能时,CryptoKey对象扮演了非常重要的角色。 5. 应用场景: 安全文件共享服务需要对文件内容进行加密,以防止敏感信息在传输和存储过程中的泄露。使用加密库可以有效保护数据安全,使得只有拥有正确密钥的用户才能解密文件,进而访问其内容。 6. 文件加密与解密函数: - generateKeyPair() 函数用于生成RSA密钥对,返回一个Promise对象,该对象中包含了生成的公钥和私钥,以及它们的PEM格式字符串。这使得密钥的管理更为方便,并且PEM格式适用于多种加密工具和服务。 - encryptStringWithPublicKey() 函数接受公钥和明文字符串作为参数,返回一个Promise对象,该对象包含base64编码的加密字符串。Base64是一种编码方式,它不是加密方法,但常用于将二进制数据编码为文本数据。 - decryptStringWithPrivateKey() 函数用于使用私钥解密之前使用公钥加密的数据。由于函数未在描述中详细说明,我们可以假设它接受一个加密的字符串和对应的私钥,返回一个Promise对象,该对象包含解密后的明文数据。 7. 开发与完善中的库: 库的开发状态为“进行中”表示开发者仍在积极开发和更新功能。文档提到需要增加的单元测试和自述文件的改善,反映了开发者对于代码质量、可测试性、文档完整性的重视。 8. 技术栈与依赖: 描述中提到该库高度依赖于特定的框架,这可能意味着库的某些功能或API是为特定的开发环境定制的。了解库依赖的具体框架对于开发者来说是必要的,以确保库能够与他们现有的项目兼容。 总体来说,SafeRequest加密库提供了一个在安全文件共享服务中使用加密和解密功能的高效解决方案。随着项目的不断完善,它将成为JavaScript开发中一个强大的工具。

相关推荐

filetype

<template> <view class="container"> <view class="header"> <view class="title">{{ formData.dcWjTitle }}</view> <view class="info"> <text>被测评人员:{{ formData.dcName }}</text> <text style="margin-left: 20rpx;">部门:{{ formData.dcDept }}</text> </view> </view> </view> </template> <script> export default { data() { return { formData: { dcWjTitle: '加载中...', dcName: '加载中...', dcDept: '加载中...' }, token: '' } }, onLoad(options) { const wjId = options.id console.log('接收到的问卷ID:', wjId) this.getTokenAndLoadData(wjId) }, methods: { async getTokenAndLoadData(id) { try { this.token = uni.getStorageSync('token') if (!this.token) { throw new Error('未找到认证令牌,请重新登录') } await this.loadQuestionnaireData(id) } catch (error) { console.error('获取token失败:', error) uni.showToast({ title: error.message || '请先登录', icon: 'none', duration: 3000 }) setTimeout(() => { uni.reLaunch({ url: '/pages/login/login' }) }, 1500) } }, async loadQuestionnaireData(id) { try { console.log('开始请求问卷数据,ID:', id) // 修复1: 使用正确的URL路径 const response = await uni.request({ url: `http://172.26.26.43/dev-api/wjdc/wj/${id}`, // 注意路径大小写 method: 'GET', header: { 'Authorization': `Bearer ${this.token}` }, timeout: 10000 // 添加超时设置 }) // 修复2: 正确处理uni.request返回结构 const [error, result] = response; if (error) { console.error('请求错误:', error) throw new Error(`网络请求失败: ${error.errMsg}`) } // 修复3: 检查状态码和业务码 if (result.statusCode !== 200) { throw new Error(`服务器返回错误状态: ${result.statusCode}`) } // 修复4: 根据接口格式获取数据 const responseData = result.data; if (responseData.code !== 200) { throw new Error(`接口错误: ${responseData.msg || '未知错误'}`) } // 修复5: 正确提取数据 const data = responseData.data console.log('接口返回数据:', data) // 更新表单数据 - 使用实际字段名 this.formData = { dcWjTitle: data.dcWjTitle || '无标题', dcName: data.dcName || '未知人员', dcDept: data.dcDept || '未知部门' } } catch (error) { console.error('请求失败:', error) // 显示错误信息 uni.showToast({ title: error.message || '数据加载失败', icon: 'none', duration: 3000 }) // 更新为错误状态 this.formData = { dcWjTitle: '数据加载失败', dcName: error.message || '请检查网络', dcDept: '或联系管理员' } // 认证错误处理 if (error.message.includes('401') || error.message.includes('认证')) { uni.removeStorageSync('token') setTimeout(() => { uni.reLaunch({ url: '/pages/login/login' }) }, 1500) } } } } } </script> <style scoped> .container { padding: 20rpx; } .header { padding: 30rpx; background-color: #f8f8f8; border-radius: 12rpx; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); margin-bottom: 30rpx; } .title { font-size: 36rpx; font-weight: bold; margin-bottom: 20rpx; color: #333; text-align: center; } .info { display: flex; justify-content: center; font-size: 28rpx; color: #666; } .info text { margin: 0 10rpx; padding: 5rpx 15rpx; background-color: #eef7ff; border-radius: 8rpx; } </style> 报错:17:26:02.824 请求失败:, TypeError: response is not iterable at pages/operation/operation.vue:103

filetype

import org.owasp.esapi.ESAPI; import org.owasp.esapi.Encoder; import org.owasp.esapi.Validator; import org.owasp.esapi.errors.ValidationException; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Stack; public class UnifiedXSSFilter implements Filter { private Encoder encoder; private Validator validator; @Override public void init(FilterConfig filterConfig) { encoder = ESAPI.encoder(); validator = ESAPI.validator(); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 1. 创建安全的请求包装器 SafeRequestWrapper safeRequest = new SafeRequestWrapper((HttpServletRequest) request); // 2. 创建响应包装器(用于捕获输出) ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response); // 3. 执行过滤器链(使用安全请求和响应包装器) chain.doFilter(safeRequest, responseWrapper); // 4. 获取原始响应内容 String content = responseWrapper.toString(); // 5. 应用上下文感知编码 String safeContent = contextAwareEncode(content); // 6. 写回安全内容 response.getWriter().write(safeContent); } // ================ 请求处理部分 ================ private class SafeRequestWrapper extends HttpServletRequestWrapper { private final Map<String, String[]> sanitizedParams = new HashMap<>(); public SafeRequestWrapper(HttpServletRequest request) { super(request); sanitizeParameters(request); } private void sanitizeParameters(HttpServletRequest request) { Enumeration<String> paramNames = request.getParameterNames(); while (paramNames.hasMoreElements()) { String paramName = paramNames.nextElement(); String[] values = request.getParameterValues(paramName); String[] sanitizedValues = new String[values.length]; for (int i = 0; i < values.length; i++) { sanitizedValues[i] = sanitizeInput(values[i]); } sanitizedParams.put(paramName, sanitizedValues); } } @Override public String getParameter(String name) { String[] values = getParameterValues(name); return (values != null && values.length > 0) ? values[0] : null; } @Override public String[] getParameterValues(String name) { return sanitizedParams.get(name); } @Override public Map<String, String[]> getParameterMap() { return sanitizedParams; } // 输入清理方法 private String sanitizeInput(String input) { if (input == null) return null; try { // 1. 规范化输入 String canonical = encoder.canonicalize(input); // 2. 验证输入 if (validator.isValidInput("Parameter", canonical, "SafeString", 2000, false)) { return canonical; } // 3. 验证失败时进行安全编码 return encoder.encodeForHTML(canonical); } catch (ValidationException e) { ESAPI.getLogger(getClass()).warning( "Input validation failed: " + e.getMessage()); return encoder.encodeForHTML(input); } } } // ================ 响应处理部分 ================ // 上下文感知编码方法 private String contextAwareEncode(String html) { if (html == null || html.isEmpty()) return ""; StringBuilder result = new StringBuilder(html.length() + 100); Stack<String> tagStack = new Stack<>(); int index = 0; int length = html.length(); while (index < length) { char current = html.charAt(index); // 处理标签开始 if (current == '<') { int tagStart = index; int tagEnd = html.indexOf('>', tagStart); if (tagEnd == -1) { // 未闭合的标签,直接编码剩余内容 result.append(encoder.encodeForHTML(html.substring(tagStart))); break; } String tag = html.substring(tagStart + 1, tagEnd).trim(); String tagName = getTagName(tag); // 处理结束标签 if (tag.startsWith("/")) { if (!tagStack.isEmpty() && tagStack.peek().equals(tagName)) { tagStack.pop(); } result.append(html.substring(tagStart, tagEnd + 1)); index = tagEnd + 1; continue; } // 处理自闭合标签 boolean selfClosing = tag.endsWith("/"); if (selfClosing) { tag = tag.substring(0, tag.length() - 1).trim(); } // 提取标签属性 String tagContent = tag; int spaceIndex = tag.indexOf(' '); if (spaceIndex != -1) { tagName = tag.substring(0, spaceIndex); tagContent = tag.substring(spaceIndex + 1); } // 处理标签属性 String safeTag = encodeTagAttributes(tagName, tagContent); // 构建安全标签 result.append('<').append(safeTag); if (selfClosing) result.append('/'); result.append('>'); // 压入标签栈(非自闭合标签) if (!selfClosing && !"meta".equalsIgnoreCase(tagName) && !"link".equalsIgnoreCase(tagName) && !"img".equalsIgnoreCase(tagName)) { tagStack.push(tagName.toLowerCase()); } index = tagEnd + 1; continue; } // 处理标签内容(根据上下文编码) if (!tagStack.isEmpty()) { String currentTag = tagStack.peek(); int contentEnd = html.indexOf('<', index); if (contentEnd == -1) contentEnd = length; String contentPart = html.substring(index, contentEnd); // 根据当前标签类型进行不同编码 if ("script".equals(currentTag)) { result.append(encodeJavaScriptContent(contentPart)); } else if ("style".equals(currentTag)) { result.append(encodeCSSContent(contentPart)); } else { result.append(encoder.encodeForHTML(contentPart)); } index = contentEnd; } else { // 非标签内容直接编码 int nextTag = html.indexOf('<', index); if (nextTag == -1) nextTag = length; String text = html.substring(index, nextTag); result.append(encoder.encodeForHTML(text)); index = nextTag; } } return result.toString(); } // 获取标签名 private String getTagName(String tag) { int spaceIndex = tag.indexOf(' '); if (spaceIndex != -1) { return tag.substring(0, spaceIndex).toLowerCase(); } return tag.toLowerCase(); } // 编码标签属性 private String encodeTagAttributes(String tagName, String attributes) { if (attributes == null || attributes.isEmpty()) { return tagName; } StringBuilder result = new StringBuilder(tagName); int index = 0; int length = attributes.length(); while (index < length) { // 跳过空白字符 while (index < length && Character.isWhitespace(attributes.charAt(index))) { index++; } if (index >= length) break; // 获取属性名 int nameStart = index; while (index < length && !Character.isWhitespace(attributes.charAt(index)) && attributes.charAt(index) != '=') { index++; } String attrName = attributes.substring(nameStart, index); // 处理等号 if (index < length && attributes.charAt(index) == '=') { index++; // 跳过空白 while (index < length && Character.isWhitespace(attributes.charAt(index))) { index++; } // 获取属性值 char quote = '\0'; if (index < length && (attributes.charAt(index) == '"' || attributes.charAt(index) == '\'')) { quote = attributes.charAt(index); index++; } int valueStart = index; while (index < length) { if (quote != '\0' && attributes.charAt(index) == quote) { break; } if (quote == '\0' && Character.isWhitespace(attributes.charAt(index))) { break; } index++; } String attrValue = (valueStart < index) ? attributes.substring(valueStart, index) : ""; // 根据属性上下文编码 String encodedValue = encodeAttributeValue(tagName, attrName, attrValue); // 添加属性 result.append(' ').append(attrName).append("=\"") .append(encodedValue).append('\"'); if (quote != '\0' && index < length && attributes.charAt(index) == quote) { index++; // 跳过结束引号 } } else { // 没有值的属性 result.append(' ').append(attrName); } } return result.toString(); } // 根据属性上下文编码 private String encodeAttributeValue(String tagName, String attrName, String value) { // 处理特殊属性(href, src, style, event handlers) String lowerAttr = attrName.toLowerCase(); String lowerTag = tagName.toLowerCase(); if ("href".equals(lowerAttr) || "src".equals(lowerAttr)) { // URL属性 return encoder.encodeForHTMLAttribute(encoder.encodeForURL(value)); } else if ("style".equals(lowerAttr)) { // CSS属性 return encoder.encodeForCSS(value); } else if (lowerAttr.startsWith("on") && lowerAttr.length() > 2) { // 事件处理属性 return encoder.encodeForJavaScript(value); } else if ("value".equals(lowerAttr) && "input".equals(lowerTag)) { // 输入框的value属性 return encoder.encodeForHTMLAttribute(value); } else { // 普通属性 return encoder.encodeForHTMLAttribute(value); } } // JavaScript内容编码 private String encodeJavaScriptContent(String content) { // 保留合法JavaScript,仅编码危险部分 return encoder.encodeForJavaScript(content) .replace("\\u003C", "<") // 恢复合法比较操作符 .replace("\\u003E", ">"); } // CSS内容编码 private String encodeCSSContent(String content) { return encoder.encodeForCSS(content); } // ================ 响应包装器 ================ private static class ResponseWrapper extends HttpServletResponseWrapper { private final CharArrayWriter charWriter = new CharArrayWriter(); public ResponseWrapper(HttpServletResponse response) { super(response); } @Override public PrintWriter getWriter() { return new PrintWriter(charWriter); } @Override public String toString() { return charWriter.toString(); } } } 代码中可能存在outStrmes输出 String content = responseWrapper.toString(); 无法获原始响应 如何更改在我的代码里修改

filetype

import App from './App' import store from './store'; import Vue from 'vue' import { registerRouterInterceptor } from './utils/router'; import './uni.promisify.adaptor' import uView from 'uview-ui' import http from '@/utils/http' Vue.use(uView) // 挂载到Vue原型 Vue.prototype.$http = http Vue.prototype.$store = store uni.$u.config.unit = 'rpx' Vue.config.productionTip = false Vue.prototype.$store = store; // 注册路由拦截器 // registerRouterInterceptor(); App.mpType = 'app' const app = new Vue({ store, ...App }) app.$mount() 这是main.js 的代码 import store from '@/store' import { baseURL } from './request.js' // 创建uView请求实例 const http = uni.$u.http // 请求拦截器 http.setConfig((config) => { config.baseURL = baseURL // 设置基础URL config.header['tenant-id'] = 0 return config }) http.interceptors.request.use( (config) => { console.log(config, "config") if (!config.url.includes('/app-api')) { // 如果URL不包含/app-api,添加前缀 config.url = '/app-api' + config.url; console.log("添加前缀后的URL:", config.url); } else { console.log("URL包含/app-api,不做处理"); } // 添加token到请求头 const token = store.state.token if (token) { config.header = { ...config.header, 'Authorization': `Bearer ${token}` } } return config }, (error) => { return Promise.reject(error) } ) // 响应拦截器 http.interceptors.response.use( (response) => { const { data, statusCode } = response if (statusCode === 200) { // 业务成功处理 return data } else if (statusCode === 401) { // token过期处理 store.dispatch('logout') uni.$u.toast('登录已过期,请重新登录') return Promise.reject('登录过期') } else { // 其他错误处理 uni.$u.toast(data.message || '请求失败') return Promise.reject(data) } }, (error) => { // 网络错误处理 uni.$u.toast('网络连接失败') return Promise.reject(error) } ) export default http 这是封装的请求的代码 import http from '@/utils/http' export default { // 密码登录接口 login(data) { return http.post('/member/auth/login', data) }, // 验证码登录接口 checkLogin(data) { return http.post('/member/auth/sms-login', data) } // // 获取用户信息 // getUserInfo() { // return http.get('/app-api/member/profile') // }, // // 更新用户信息 // updateUserInfo(data) { // return http.put('/app-api/member/update', data) // } }这个封装接口的代码,为什么会报app.js错误: TypeError: Cannot read property 'http' of undefined at Object.<anonymous> (http.js:7) at Object.<anonymous> (vendor.js:11628) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (user.js:1) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (user.js:1) at Object.<anonymous> (vendor.js:11141) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (index.js:3) at __webpack_require__ (bootstrap:91)(env: Windows,mp,1.06.2503300; lib: 3.8.12) TypeError: Cannot read property 'http' of undefined at Object.<anonymous> (http.js:7) at Object.<anonymous> (vendor.js:11628) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (user.js:1) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (user.js:1) at Object.<anonymous> (vendor.js:11141) at __webpack_require__ (bootstrap:91) at Object.<anonymous> (index.js:3) at __webpack_require__ (bootstrap:91)(env: Windows,mp,1.06.2503300; lib: 3.8.12)这个错