uni-app数据加密:跨端敏感信息保护
【免费下载链接】uni-app A cross-platform framework using Vue.js 项目地址: https://gitcode.com/dcloud/uni-app
前言:移动应用数据安全的严峻挑战
在移动应用开发中,数据安全一直是开发者面临的核心挑战。随着uni-app跨端开发框架的普及,如何在多个平台(微信小程序、支付宝小程序、App、H5等)上统一实现敏感信息的保护,成为了开发者必须面对的技术难题。
你是否曾经遇到过这些问题?
- 用户登录凭证在本地存储中被轻易获取
- 敏感配置信息在代码中明文暴露
- 不同平台的安全机制差异导致加密方案难以统一
- 加解密性能影响用户体验
本文将为你全面解析uni-app中的数据加密最佳实践,帮助你构建安全可靠的跨端应用。
uni-app数据存储安全架构
核心加密方案实现
1. 基础加密工具类
首先创建一个统一的加密工具类,支持多种加密算法:
// utils/crypto.js
import { md5, sha256 } from 'crypto-js'
import AES from 'crypto-js/aes'
import Base64 from 'crypto-js/enc-base64'
import Utf8 from 'crypto-js/enc-utf8'
class UniAppCrypto {
constructor() {
this.key = this.generateAppKey()
this.iv = this.generateIV()
}
// 生成应用唯一密钥
generateAppKey() {
// 结合设备信息和应用特征生成唯一密钥
const deviceInfo = uni.getSystemInfoSync()
const appInfo = require('../package.json')
const rawKey = `${deviceInfo.platform}-${deviceInfo.model}-${appInfo.version}`
return sha256(rawKey).toString().substring(0, 32)
}
generateIV() {
return md5(Date.now().toString()).toString().substring(0, 16)
}
// AES加密
encryptAES(data) {
try {
if (typeof data === 'object') {
data = JSON.stringify(data)
}
const encrypted = AES.encrypt(data, this.key, {
iv: this.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.toString()
} catch (error) {
console.error('AES加密失败:', error)
return null
}
}
// AES解密
decryptAES(encryptedData) {
try {
const decrypted = AES.decrypt(encryptedData, this.key, {
iv: this.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
const result = decrypted.toString(Utf8)
// 尝试解析JSON
try {
return JSON.parse(result)
} catch {
return result
}
} catch (error) {
console.error('AES解密失败:', error)
return null
}
}
// 哈希函数
hashMD5(data) {
return md5(data).toString()
}
hashSHA256(data) {
return sha256(data).toString()
}
// Base64编码解码
base64Encode(data) {
return Base64.stringify(Utf8.parse(data))
}
base64Decode(encoded) {
return Base64.parse(encoded).toString(Utf8)
}
}
export default new UniAppCrypto()
2. 安全存储封装
对uni-app的存储API进行安全封装:
// utils/secureStorage.js
import crypto from './crypto'
class SecureStorage {
// 加密存储
setItem(key, value, encrypt = true) {
try {
let storageValue = value
if (encrypt) {
storageValue = crypto.encryptAES(value)
if (!storageValue) {
throw new Error('加密失败')
}
}
uni.setStorageSync(key, storageValue)
return true
} catch (error) {
console.error('安全存储失败:', error)
return false
}
}
// 解密读取
getItem(key, decrypt = true) {
try {
const encryptedValue = uni.getStorageSync(key)
if (encryptedValue === null || encryptedValue === undefined) {
return null
}
if (decrypt) {
return crypto.decryptAES(encryptedValue)
}
return encryptedValue
} catch (error) {
console.error('安全读取失败:', error)
return null
}
}
// 批量加密存储
setMultiple(items, encrypt = true) {
const results = {}
Object.keys(items).forEach(key => {
results[key] = this.setItem(key, items[key], encrypt)
})
return results
}
// 删除项
removeItem(key) {
try {
uni.removeStorageSync(key)
return true
} catch (error) {
console.error('删除存储项失败:', error)
return false
}
}
// 清空存储
clear() {
try {
uni.clearStorageSync()
return true
} catch (error) {
console.error('清空存储失败:', error)
return false
}
}
}
export default new SecureStorage()
3. 跨平台安全适配器
// utils/securityAdapter.js
class SecurityAdapter {
constructor() {
this.platform = uni.getSystemInfoSync().platform
this.securityLevel = this.getSecurityLevel()
}
getSecurityLevel() {
const levels = {
'android': 'high', // Android提供硬件级加密
'ios': 'high', // iOS有Keychain保护
'devtools': 'low', // 开发工具环境
'windows': 'medium', // Windows平台
'mac': 'medium', // Mac平台
}
return levels[this.platform] || 'medium'
}
// 平台特定的加密增强
enhanceEncryption(data, context = 'storage') {
switch (this.platform) {
case 'android':
return this.androidEncrypt(data, context)
case 'ios':
return this.iosEncrypt(data, context)
default:
return data
}
}
androidEncrypt(data, context) {
// Android平台使用硬件加密增强
if (context === 'storage' && this.securityLevel === 'high') {
// 添加Android特有的安全标记
return {
_android_secure: true,
_timestamp: Date.now(),
data: data
}
}
return data
}
iosEncrypt(data, context) {
// iOS平台使用Keychain相关增强
if (context === 'storage' && this.securityLevel === 'high') {
return {
_ios_secure: true,
_keychain_compatible: true,
data: data
}
}
return data
}
// 安全传输配置
getSecurityHeaders() {
return {
'X-Security-Level': this.securityLevel,
'X-Platform': this.platform,
'X-Timestamp': Date.now(),
'X-Request-ID': this.generateRequestId()
}
}
generateRequestId() {
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
}
}
export default new SecurityAdapter()
实战应用场景
场景1:用户登录凭证保护
// services/authService.js
import secureStorage from '@/utils/secureStorage'
import crypto from '@/utils/crypto'
class AuthService {
// 安全存储登录令牌
async secureLogin(credentials) {
try {
const response = await uni.request({
url: '/api/auth/login',
method: 'POST',
data: {
username: credentials.username,
password: crypto.hashSHA256(credentials.password),
deviceId: this.getDeviceId()
},
header: {
'Content-Type': 'application/json',
...securityAdapter.getSecurityHeaders()
}
})
if (response.data.success) {
// 加密存储token和用户信息
const authData = {
token: response.data.token,
refreshToken: response.data.refreshToken,
userInfo: response.data.user,
expiresAt: Date.now() + response.data.expiresIn * 1000
}
secureStorage.setItem('auth_data', authData)
secureStorage.setItem('last_login', Date.now())
return { success: true, data: authData }
}
return { success: false, error: response.data.message }
} catch (error) {
console.error('登录失败:', error)
return { success: false, error: '网络错误' }
}
}
// 获取设备唯一标识
getDeviceId() {
const systemInfo = uni.getSystemInfoSync()
const appInfo = require('@/package.json')
const deviceData = {
platform: systemInfo.platform,
model: systemInfo.model,
version: systemInfo.version,
appVersion: appInfo.version
}
return crypto.hashSHA256(JSON.stringify(deviceData))
}
// 检查登录状态
checkAuthStatus() {
const authData = secureStorage.getItem('auth_data')
if (!authData || !authData.token) {
return false
}
// 检查token是否过期
if (authData.expiresAt < Date.now()) {
this.refreshToken()
return false
}
return true
}
// token刷新
async refreshToken() {
const authData = secureStorage.getItem('auth_data')
if (!authData || !authData.refreshToken) {
this.logout()
return
}
try {
const response = await uni.request({
url: '/api/auth/refresh',
method: 'POST',
data: {
refreshToken: authData.refreshToken
},
header: securityAdapter.getSecurityHeaders()
})
if (response.data.success) {
authData.token = response.data.token
authData.expiresAt = Date.now() + response.data.expiresIn * 1000
secureStorage.setItem('auth_data', authData)
} else {
this.logout()
}
} catch (error) {
console.error('token刷新失败:', error)
this.logout()
}
}
// 安全退出
logout() {
secureStorage.removeItem('auth_data')
secureStorage.removeItem('last_login')
// 其他清理操作...
}
}
export default new AuthService()
场景2:敏感配置信息保护
// config/secureConfig.js
import crypto from '@/utils/crypto'
import secureStorage from '@/utils/secureStorage'
// 敏感配置项
const SENSITIVE_CONFIG = {
apiKeys: {
map: 'your_map_api_key',
push: 'your_push_service_key',
analytics: 'your_analytics_key'
},
endpoints: {
auth: 'https://api.example.com/auth',
payment: 'https://api.example.com/payment'
},
security: {
encryptionKey: 'default_encryption_key_backup'
}
}
class SecureConfig {
constructor() {
this.config = {}
this.loadConfig()
}
// 加载并解密配置
loadConfig() {
// 尝试从安全存储加载
const storedConfig = secureStorage.getItem('app_config')
if (storedConfig) {
this.config = storedConfig
} else {
// 首次运行,加密存储默认配置
this.config = this.encryptConfig(SENSITIVE_CONFIG)
secureStorage.setItem('app_config', this.config)
}
}
encryptConfig(config) {
const encrypted = { ...config }
// 对敏感字段进行加密
if (encrypted.apiKeys) {
Object.keys(encrypted.apiKeys).forEach(key => {
encrypted.apiKeys[key] = crypto.encryptAES(encrypted.apiKeys[key])
})
}
if (encrypted.security && encrypted.security.encryptionKey) {
encrypted.security.encryptionKey = crypto.encryptAES(
encrypted.security.encryptionKey
)
}
return encrypted
}
// 获取解密后的配置值
get(keyPath, defaultValue = null) {
const keys = keyPath.split('.')
let value = this.config
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = value[key]
} else {
return defaultValue
}
}
// 如果是加密的值,尝试解密
if (typeof value === 'string' && value.length > 50) {
try {
const decrypted = crypto.decryptAES(value)
return decrypted || defaultValue
} catch {
return defaultValue
}
}
return value || defaultValue
}
// 更新配置
update(keyPath, value) {
const keys = keyPath.split('.')
let config = this.config
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i]
if (!config[key] || typeof config[key] !== 'object') {
config[key] = {}
}
config = config[key]
}
const lastKey = keys[keys.length - 1]
// 对敏感字段自动加密
if (keyPath.includes('apiKeys') || keyPath.includes('security')) {
config[lastKey] = crypto.encryptAES(value)
} else {
config[lastKey] = value
}
// 保存更新后的配置
secureStorage.setItem('app_config', this.config)
}
}
export default new SecureConfig()
性能优化与最佳实践
加密性能优化策略
代码实现示例
// utils/performanceCrypto.js
import crypto from './crypto'
class PerformanceCrypto {
constructor() {
this.cache = new Map()
this.cacheTimeout = 5 * 60 * 1000 // 5分钟缓存
}
// 带缓存的加密
encryptWithCache(key, data, forceUpdate = false) {
const cacheKey = `encrypt_${key}`
if (!forceUpdate) {
const cached = this.getFromCache(cacheKey)
if (cached) {
return cached
}
}
const encrypted = crypto.encryptAES(data)
this.setToCache(cacheKey, encrypted)
return encrypted
}
// 带缓存的解密
decryptWithCache(encryptedData, originalKey) {
const cacheKey = `decrypt_${originalKey}`
const cached = this.getFromCache(cacheKey)
if (cached) {
return cached
}
const decrypted = crypto.decryptAES(encryptedData)
this.setToCache(cacheKey, decrypted)
return decrypted
}
getFromCache(key) {
const item = this.cache.get(key)
if (item && Date.now() - item.timestamp < this.cacheTimeout) {
return item.data
}
return null
}
setToCache(key, data) {
this.cache.set(key, {
data: data,
timestamp: Date.now()
})
}
// 清空缓存
clearCache() {
this.cache.clear()
}
// 批量加密优化
batchEncrypt(items) {
const results = {}
const promises = []
Object.keys(items).forEach(key => {
promises.push(
new Promise(resolve => {
setTimeout(() => {
results[key] = this.encryptWithCache(key, items[key])
resolve()
}, 0)
})
)
})
return Promise.all(promises).then(() => results)
}
}
export default new PerformanceCrypto()
安全检测与监控
运行时安全检测
// utils/securityMonitor.js
class SecurityMonitor {
constructor() {
this.threatsDetected = 0
this.lastCheckTime = Date.now()
this.setupMonitoring()
}
setupMonitoring() {
// 定时安全检查
setInterval(() => {
this.runSecurityChecks()
}, 30000) // 每30秒检查一次
// 监听存储变化
this.setupStorageMonitoring()
}
runSecurityChecks() {
this.checkDebugMode()
this.checkStorageTampering()
this.checkNetworkSecurity()
}
checkDebugMode() {
// 检查是否处于调试模式
try {
【免费下载链接】uni-app A cross-platform framework using Vue.js 项目地址: https://gitcode.com/dcloud/uni-app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



