Android开发实战班 - 数据持久化 - 数据加密与安全
在 Android 应用开发中,数据安全至关重要,尤其是在处理敏感信息(如用户密码、支付信息、个人隐私数据等)时。数据加密是保护数据安全的重要手段,可以有效防止数据泄露、篡改和未经授权的访问。本章节将介绍 Android 开发中常用的数据加密方法、加密库的使用、安全存储方案以及最佳实践,帮助学员掌握数据加密与安全的实现。
-
什么是数据加密:
- 数据加密是指将明文数据通过加密算法转换为密文数据,只有持有正确密钥的人才能解密并读取数据。
-
数据加密的目的:
- 保密性: 防止数据泄露,确保只有授权用户才能读取数据。
- 完整性: 防止数据被篡改,确保数据的完整性和一致性。
- 身份验证: 验证数据的来源,确保数据来自可信的发送者。
-
加密类型:
- 对称加密: 使用相同的密钥进行加密和解密,例如 AES。
- 非对称加密: 使用一对公钥和私钥进行加密和解密,例如 RSA。
- 哈希加密: 将数据转换为固定长度的哈希值,例如 SHA-256。
18.2 常用加密算法
18.2.1 对称加密
-
AES (Advanced Encryption Standard):
- 高级加密标准,是目前最常用的对称加密算法。
- 密钥长度可以是 128、192 或 256 位。
- 适用于加密大量数据,加密和解密速度快。
import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.SecretKey import javax.crypto.spec.SecretKeySpec// 生成 AES 密钥 fun generateAesKey(): SecretKey {val keyGenerator = KeyGenerator.getInstance("AES")keyGenerator.init(256)return keyGenerator.generateKey() }// AES 加密 fun encryptAes(data: ByteArray, key: SecretKey): ByteArray {val cipher = Cipher.getInstance("AES")cipher.init(Cipher.ENCRYPT_MODE, key)return cipher.doFinal(data) }// AES 解密 fun decryptAes(encryptedData: ByteArray, key: SecretKey): ByteArray {val cipher = Cipher.getInstance("AES")cipher.init(Cipher.DECRYPT_MODE, key)return cipher.doFinal(encryptedData) }
18.2.2 非对称加密
-
RSA (Rivest–Shamir–Adleman):
- RSA 是一种常用的非对称加密算法。
- 使用一对公钥和私钥进行加密和解密。
- 适用于加密少量数据,例如加密对称密钥。
import java.security.KeyPairGenerator import java.security.PrivateKey import java.security.PublicKey import javax.crypto.Cipher// 生成 RSA 密钥对 fun generateRsaKeyPair(): KeyPair {val keyPairGenerator = KeyPairGenerator.getInstance("RSA")keyPairGenerator.initialize(2048)return keyPairGenerator.generateKeyPair() }// RSA 加密 fun encryptRsa(data: ByteArray, publicKey: PublicKey): ByteArray {val cipher = Cipher.getInstance("RSA")cipher.init(Cipher.ENCRYPT_MODE, publicKey)return cipher.doFinal(data) }// RSA 解密 fun decryptRsa(encryptedData: ByteArray, privateKey: PrivateKey): ByteArray {val cipher = Cipher.getInstance("RSA")cipher.init(Cipher.DECRYPT_MODE, privateKey)return cipher.doFinal(encryptedData) }
18.2.3 哈希加密
-
SHA-256 (Secure Hash Algorithm 256):
- SHA-256 是一种常用的哈希加密算法。
- 将任意长度的数据转换为 256 位的哈希值。
- 适用于数据完整性校验和密码存储。
import java.security.MessageDigest// SHA-256 哈希 fun sha256(data: String): String {val md = MessageDigest.getInstance("SHA-256")val hashBytes = md.digest(data.toByteArray())return hashBytes.joinToString("") { "%02x".format(it) } }
18.3 Android 中的安全存储
-
Keystore 系统:
- Android 提供了 Keystore 系统,用于安全地存储和管理密钥。
- Keystore 可以生成密钥,并提供安全的密钥存储和加密操作。
- 密钥存储在设备的硬件安全模块中,无法被提取。
import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import java.security.KeyStore// 生成 Keystore 密钥 fun generateKeystoreKey(alias: String) {val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")val keyGenParameterSpec = KeyGenParameterSpec.Builder(alias,KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT).setBlockModes(KeyProperties.BLOCK_MODE_GCM).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE).setKeySize(256).build()keyGenerator.init(keyGenParameterSpec)keyGenerator.generateKey() }// 获取 Keystore 密钥 fun getKeystoreKey(alias: String): SecretKey {val keyStore = KeyStore.getInstance("AndroidKeyStore")keyStore.load(null)return keyStore.getKey(alias, null) as SecretKey } -
EncryptedFile 和 EncryptedSharedPreferences:
- Android Jetpack 提供了
EncryptedFile和EncryptedSharedPreferences,用于加密文件和数据存储。 EncryptedFile可以对文件进行加密和解密。EncryptedSharedPreferences可以在 SharedPreferences 中存储加密数据。
import androidx.security.crypto.EncryptedFile import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKeys// 使用 EncryptedFile 加密文件 fun writeEncryptedFile(context: Context, fileName: String, content: String) {val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES_256_GCM_SPEC)val file = File(context.filesDir, fileName)val encryptedFile = EncryptedFile.Builder(file,context,masterKeyAlias,EncryptedFile.FileEncryptionScheme.AES256_SIV).build()encryptedFile.openFileOutput().bufferedWriter().use { writer ->writer.write(content)} }// 使用 EncryptedSharedPreferences 加密 SharedPreferences fun getEncryptedSharedPreferences(context: Context): SharedPreferences {val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES_256_GCM_SPEC)return EncryptedSharedPreferences.create("secret_shared_prefs",masterKeyAlias,context,EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM) } - Android Jetpack 提供了
18.4 数据加密最佳实践
-
使用强加密算法:
- 使用经过验证的强加密算法,例如 AES, RSA, SHA-256 等。
-
保护密钥:
- 密钥是加密安全的核心,必须妥善保护。
- 使用 Android Keystore 系统存储和管理密钥,避免密钥泄露。
-
最小权限原则:
- 只存储和传输必要的数据,避免存储敏感信息。
- 最小化权限申请,只申请应用所需的最低权限。
-
安全存储:
- 使用加密存储方案,例如 EncryptedFile, EncryptedSharedPreferences 等。
- 避免在代码中硬编码密钥或敏感信息。
-
数据备份:
- 对敏感数据进行加密备份,避免备份数据泄露。
-
错误处理:
- 妥善处理加密操作中的异常,避免敏感信息泄露。
相关文章:
Android开发实战班 - 数据持久化 - 数据加密与安全
在 Android 应用开发中,数据安全至关重要,尤其是在处理敏感信息(如用户密码、支付信息、个人隐私数据等)时。数据加密是保护数据安全的重要手段,可以有效防止数据泄露、篡改和未经授权的访问。本章节将介绍 Android 开…...
EDA实验设计-led灯管动态显示;VHDL;Quartus编程
EDA实验设计-led灯管动态显示;VHDL;Quartus编程 引脚配置实现代码RTL引脚展示现象记录效果展示 引脚配置 #------------------GLOBAL--------------------# set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" set_…...
Eclipse 查找功能深度解析
Eclipse 查找功能深度解析 Eclipse 是一款广受欢迎的集成开发环境(IDE),它为各种编程语言提供了强大的开发工具。在本文中,我们将深入探讨 Eclipse 的查找功能,这是开发者日常工作中不可或缺的一部分。无论是查找代码中的特定字符串,还是进行更复杂的搜索,如正则表达式…...
第三百二十九节 Java网络教程 - Java网络UDP套接字
Java网络教程 - Java网络UDP套接字 TCP套接字是面向连接的,基于流。基于UDP的套接字是无连接的,基于数据报。 使用UDP发送的数据块称为数据报或UDP数据包。每个UDP分组具有数据,目的地IP地址和目的地端口号。 无连接套接字在通信之前不建立…...
Leetcode215. 数组中的第K个最大元素(HOT100)
链接 第一次: class Solution { public:int findKthLargest(vector<int>& nums, int k) {sort(nums.begin(),nums.end());int n nums.size();return nums[n-k];} }; 这显然不能出现在面试中,因为面试官考察的不是这个。 正确的代码&#…...
QT与嵌入式——搭建串口
1、源码 由于我需要不止一个串口来进行数据交互,所以简单的封装了一下 void Usb_Init(QString portName, QSerialPort *Port) {Port->setPortName(portName);Port->setBaudRate(QSerialPort::Baud115200); // 设置波特率,根据你的开发板配置修改…...
Shell编程-6
声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:shell(6)if条件判断与for循环结构_哔哩哔哩_bilibili 一、if条件判断 在Shell脚本中,if语句用于基于条件的评估来执行不同的代码块。…...
使用 Postman 设置 Bearer Token 进行身份验证
学习笔记 1. 打开 Postman 并创建新请求 打开 Postman。 在左上角点击 按钮,创建一个新的请求。 2. 选择 HTTP 方法 在请求类型(默认为 GET)旁边的下拉菜单中,选择你需要的 HTTP 方法,如 POST、GET、PUT 等。 3…...
现在转前端怎么样?
互联网技术日新月异,软件开发者追逐技术浪潮的脚步从未停歇。在这个快速发展的行业中,如何规划自己的职业道路,选择合适的技术方向,成为了许多开发者面临的重要抉择。本文将围绕技术选择这个话题,分享一些深入的思考和…...
【算法一周目】滑动窗口(1)
目录 长度最小的子数组 解题思路 代码实现 无重复字符的最大字串 解题思路 代码实现 最大连续1的个数l l l 解题思路 代码实现 将x减到0的最小操作数 解题思路 代码实现 长度最小的子数组 题目链接:209. 长度最小的子数组题目描述: 给定一个…...
React Native 基础
React 的核心概念 定义函数式组件 import组件 要定义一个Cat组件,第一步要使用 import 语句来引入React以及React Native的 Text 组件: import React from react; import { Text } from react-native; 定义函数作为组件 const CatApp = () => {}; 渲染Text组件...
【C++笔记】list使用详解及模拟实现
前言 各位读者朋友们大家好!上期我们讲了vector的使用以及底层的模拟实现,这期我们来讲list。 目录 前言一. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.…...
【机器学习】机器学习中用到的高等数学知识-7.信息论 (Information Theory)
熵 (Entropy):用于评估信息的随机性,常用于决策树和聚类算法。交叉熵 (Cross-Entropy):用于衡量两个概率分布之间的差异,在分类问题中常用。 信息论作为处理信息量和信息传输的数学理论,在机器学习中具有广泛的应用。…...
《现代制造技术与装备》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答 问:《现代制造技术与装备》是不是核心期刊? 答:不是,是知网收录的第二批认定学术期刊。 问:《现代制造技术与装备》级别? 答:省级。主管单位:齐鲁工业大学࿰…...
09 - Clickhouse的SQL操作
目录 1、Insert 1.1、标准 1.2、从表到表的插入 2、Update和Delete 2.1、删除操作 2.2、修改操作 3、查询操作 3.1、with rollup:从右至左去掉维度进行小计 3.2、with cube : 从右至左去掉维度进行小计,再从左至右去掉维度进行小计 3.3、with …...
如何解决pdf.js跨域从url动态加载pdf文档
摘要 当我们想用PDF.js从URL加载文档时,将会因遇到跨域问题而中断,且是因为会触发了PDF.js和浏览器的双重CORS block,这篇文章将会介绍:①如何禁用pdf.js的跨域?②如何绕过浏览器的CORS加载URL文件?②如何使…...
深入理解TTY体系:设备节点与驱动程序框架详解
往期内容 本专栏往期内容:Uart子系统 UART串口硬件介绍 interrupt子系统专栏: 专栏地址:interrupt子系统Linux 链式与层级中断控制器讲解:原理与驱动开发 – 末片,有专栏内容观看顺序 pinctrl和gpio子系统专栏…...
库的操作(MySQL)
1.创建数据库 语法: CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification:[DEFAULT] CHARACTER SET charset_name[DEFAULT] COLLATE collation_name说明: 大写的表示关键字 [ ] 是可…...
在 for 循环中,JVM可能会将 arr.length 提升到循环外部,仅计算一次。可能会将如何解释 详解
在 Java 的 for 循环中,JVM 有能力进行优化,将 arr.length 的访问提升到循环外部,避免每次迭代都重新计算 arr.length。这种优化主要是由于 JVM 的 即时编译器(JIT) 和 逃逸分析(Escape Analysis࿰…...
回溯--数据在内存中的存储:整数、大小端和浮点数的深度解析
目录 引言 1. 整数在内存中的存储 1.1 原码、反码和补码 1.2 为什么使用补码? 1.3 示例代码:整数的存储 2. 大小端字节序和字节序判断 2.1 什么是大端和小端? 2.2 为什么会有大端和小端之分? 2.3 字节序的判断小程序 2.…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
