赞
踩
在 Android 开发中,KeyStore 是一个用于存储密钥和证书的安全容器。它提供了一种安全的方式来存储敏感信息,如密钥对、数字证书等,以防止它们被未授权的应用或攻击者访问。
KeyStore 通常用于加密数据、数字签名、TLS/SSL 连接等场景。
Android 开发中使用 KeyStore 的常见场景:
存储密钥对:可以使用 KeyStore 来生成和存储公钥和私钥的密钥对。这些密钥对通常用于数据加密、数字签名等操作。
存储数字证书:可以使用 KeyStore 来存储数字证书,用于验证身份、建立安全连接等场景。
安全存储密码:可以使用 KeyStore 来安全地存储密码、凭证、API 密钥等敏感信息,以防止它们被未授权的应用或攻击者访问。
TLS/SSL 连接:可以使用 KeyStore 来管理客户端证书和受信任的 CA 证书,用于安全通信、建立 TLS/SSL 连接等操作。
双因素身份验证:可以使用 KeyStore 来存储和管理双因素身份验证所需的密钥和证书,用于提高身份验证的安全性。
在 Android 中,KeyStore 是通过 java.security.KeyStore
类来实现的。可以使用该类来创建、加载、存储和检索密钥和证书。Android 提供了特定于 Android 平台的 KeyStore 实现,称为 AndroidKeyStore,它提供了更高级的安全功能,如硬件支持、密钥链随机生成等。
- // 密钥库类型
- private const val PP_KEYSTORE_TYPE = "AndroidKeyStore"
- // 密钥库别名
- private const val PP_KEYSTORE_ALIAS = "pp_keystore_alias"
- // 加密算法标准算法名称
- private const val PP_TRANSFORMATION = "RSA/ECB/PKCS1Padding"
- /**
- * 触发生成密钥对.
- *
- * 生成RSA 密钥对,包括公钥和私钥
- *
- * @return KeyPair 密钥对,包含公钥和私钥
- */
- private fun generateKey(): KeyPair {
- // 创建密钥生成器
- val keyPairGenerator = KeyPairGenerator.getInstance(
- KeyProperties.KEY_ALGORITHM_RSA,
- PP_KEYSTORE_TYPE
- )
- // 配置密钥生成器参数
- KeyGenParameterSpec.Builder(
- PP_KEYSTORE_ALIAS,
- KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
- )
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
- .setDigests(KeyProperties.DIGEST_SHA256)
- .build().run {
- keyPairGenerator.initialize(this)
- }
- // 生成密钥对
- return keyPairGenerator.generateKeyPair()
- }
通过上述代码使用“AndroidKeyStore”类型的密钥库,生成 RSA 密钥对,包括公钥和私钥。
后续针对数据的加密和解密就需要使用此时密钥库中生成的 公钥和私钥。
- /**
- * 获取公钥.
- *
- * @return 公钥
- */
- private fun getPublicKey(): PublicKey? {
- val keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE).apply {
- load(null)
- }
- // 判断密钥是否存在
- if (!keyStore.containsAlias(PP_KEYSTORE_ALIAS)) {
- return generateKey().public
- }
- val entry = keyStore.getEntry(PP_KEYSTORE_ALIAS, null)
- if (entry !is KeyStore.PrivateKeyEntry) {
- return null
- }
- return entry.certificate.publicKey
- }
- /**
- * 获取私钥.
- *
- * @return 密钥
- */
- private fun getPrivateKey(): PrivateKey? {
- val keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE).apply {
- load(null)
- }
- // 判断密钥是否存在
- if (!keyStore.containsAlias(PP_KEYSTORE_ALIAS)) {
- return generateKey().private
- }
- val entry = keyStore.getEntry(PP_KEYSTORE_ALIAS, null)
- if (entry !is KeyStore.PrivateKeyEntry) {
- return null
- }
- return entry.privateKey
- }
- /**
- * 数据加密.
- *
- * @param data 原始数据,字符串
- * @return 加密数据,字节数组
- */
- fun encryptData(data: String): ByteArray {
- return encryptDataInternal(data.toByteArray())
- }
-
-
- /**
- * 数据加密.
- *
- * @param bytes 原始数据
- * @return 加密数据
- */
- private fun encryptDataInternal(bytes: ByteArray): ByteArray {
- return getPublicKey()?.run {
- val cipher = Cipher.getInstance(PP_TRANSFORMATION)
- cipher.init(Cipher.ENCRYPT_MODE, this)
- cipher.doFinal(bytes)
- } ?: byteArrayOf()
- }
- /**
- * 数据解密.
- *
- * @param bytes 加密数据
- * @return 原始数据,字符串
- */
- fun decryptData(bytes: ByteArray): String {
- return String(decryptDataInternal(bytes))
- }
-
- /**
- * 数据解密.
- *
- * @param bytes 加密数据
- * @return 原始数据
- */
- private fun decryptDataInternal(bytes: ByteArray): ByteArray {
- return getPrivateKey()?.run {
- val cipher = Cipher.getInstance(PP_TRANSFORMATION)
- cipher.init(Cipher.DECRYPT_MODE, this)
- cipher.doFinal(bytes)
- } ?: byteArrayOf()
- }
描述下Cipher对象参数:
Cipher.getInstance(String transformation)
是用于获取 Cipher 对象的静态方法。它接受一个字符串参数 transformation
,该参数指定了要使用的加密算法、模式和填充方式
transformation介绍
transformation
参数的格式通常为 "algorithm/mode/padding"
,其中:
例如我们当前工具类,要使用 RSA 算法、ECB 模式和 PKCS5Padding 填充方式进行加密,你可以使用如下的 transformation
参数:
private const val PP_TRANSFORMATION = "RSA/ECB/PKCS1Padding"
然后调用 Cipher.getInstance(transformation)
方法来获取对应的 Cipher 对象,用于执行加密和解密操作。
在 Android 中,常见的加密算法和模式包括:
transformation类型,参考Cipher文档:
使用
OAEP填充方式private const val PP_TRANSFORMATION = "RSA/ECB/OAEPwithSHA-512andMGF1Padding"
如果填充模式为OAEP,需要修改的代码如下
- // padding: 主要是生成KeySotre密钥对,填充模式:ENCRYPTION_PADDING_RSA_OAEP
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
- // mode: ECB
- .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
- // 消息摘要只支持512和256,OAEPwithSHA-512andMGF1Padding
- .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
- /**
- * 数据加密.
- *
- * @param bytes 原始数据
- * @return 加密数据
- */
- private fun encryptDataInternal(bytes: ByteArray): ByteArray {
- return getPublicKey()?.run {
- val cipher = Cipher.getInstance(TRANSLATOR_TRANSFORMATION)
- cipher.init(
- Cipher.ENCRYPT_MODE, this,
- OAEPParameterSpec(
- "SHA-512",
- "MGF1",
- MGF1ParameterSpec.SHA1,
- PSource.PSpecified.DEFAULT
- )
- )
- cipher.doFinal(bytes)
- } ?: byteArrayOf()
- }
Android平台在使用RSA/ECB/OAEPWithSHA-256AndMGF1Padding加密模式时,对MGF1摘要算法的支持存在一些限制。
java.security.InvalidAlgorithmParameterException
异常。提示:正常我们需要对加密的数据进行本地存储,上述加密数据是ByteArray,字节数组不太适合本地存储,因此我们可以通过Base64将ByteArray数据转换为字符串进行保存,取出数据之时再做Base64解码。
- // ByteArray转Base64字符串
- Base64.encodeToString(encryptedBytes, Base64.DEFAULT)
-
- // Base64字符串转ByteArray
- Base64.decode(encryptedString, Base64.DEFAULT)
到此为止,基本的使用和简单的参数描述已经完成。
- object KeyStoreHelper {
- // 密钥库类型
- private const val PP_KEYSTORE_TYPE = "AndroidKeyStore"
- // 密钥库别名
- private const val PP_KEYSTORE_ALIAS = "pp_keystore_alias"
- // 加密算法标准算法名称
- private const val PP_TRANSFORMATION = "RSA/ECB/PKCS1Padding"
-
- /**
- * 数据加密.
- *
- * @param data 原始数据,字符串
- * @return 加密数据,字节数组
- */
- fun encryptData(data: String): ByteArray {
- return encryptDataInternal(data.toByteArray())
- }
-
- /**
- * 数据解密.
- *
- * @param bytes 加密数据
- * @return 原始数据,字符串
- */
- fun decryptData(bytes: ByteArray): String {
- return String(decryptDataInternal(bytes))
- }
-
- /**
- * 数据加密.
- *
- * @param bytes 原始数据
- * @return 加密数据
- */
- private fun encryptDataInternal(bytes: ByteArray): ByteArray {
- return getPublicKey()?.run {
- val cipher = Cipher.getInstance(PP_TRANSFORMATION)
- cipher.init(Cipher.ENCRYPT_MODE, this)
- cipher.doFinal(bytes)
- } ?: byteArrayOf()
- }
-
- /**
- * 数据解密.
- *
- * @param bytes 加密数据
- * @return 原始数据
- */
- private fun decryptDataInternal(bytes: ByteArray): ByteArray {
- return getPrivateKey()?.run {
- val cipher = Cipher.getInstance(PP_TRANSFORMATION)
- cipher.init(Cipher.DECRYPT_MODE, this)
- cipher.doFinal(bytes)
- } ?: byteArrayOf()
- }
-
- /**
- * 获取公钥.
- *
- * @return 公钥
- */
- private fun getPublicKey(): PublicKey? {
- val keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE).apply {
- load(null)
- }
- // 判断密钥是否存在
- if (!keyStore.containsAlias(PP_KEYSTORE_ALIAS)) {
- return generateKey().public
- }
- val entry = keyStore.getEntry(PP_KEYSTORE_ALIAS, null)
- if (entry !is KeyStore.PrivateKeyEntry) {
- return null
- }
- return entry.certificate.publicKey
- }
-
- /**
- * 获取私钥.
- *
- * @return 密钥
- */
- private fun getPrivateKey(): PrivateKey? {
- val keyStore = KeyStore.getInstance(PP_KEYSTORE_TYPE).apply {
- load(null)
- }
- // 判断密钥是否存在
- if (!keyStore.containsAlias(PP_KEYSTORE_ALIAS)) {
- return generateKey().private
- }
- val entry = keyStore.getEntry(PP_KEYSTORE_ALIAS, null)
- if (entry !is KeyStore.PrivateKeyEntry) {
- return null
- }
- return entry.privateKey
- }
-
- /**
- * 触发生成密钥对.
- *
- * 生成RSA 密钥对,包括公钥和私钥
- *
- * @return KeyPair 密钥对,包含公钥和私钥
- */
- private fun generateKey(): KeyPair {
- // 创建密钥生成器
- val keyPairGenerator = KeyPairGenerator.getInstance(
- KeyProperties.KEY_ALGORITHM_RSA,
- PP_KEYSTORE_TYPE
- )
- // 配置密钥生成器参数
- KeyGenParameterSpec.Builder(
- PP_KEYSTORE_ALIAS,
- KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
- )
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
- .setDigests(KeyProperties.DIGEST_SHA256)
- .build().run {
- keyPairGenerator.initialize(this)
- }
- // 生成密钥对
- return keyPairGenerator.generateKeyPair()
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。