安卓中JSON数据的加密与解密全解析
在安卓开发中,JSON作为一种轻量级的数据交换格式,因其可读性强、解析方便而被广泛应用于客户端与服务器之间的数据传输,JSON数据本身是明文传输的,若涉及敏感信息(如用户密码、身份证号、支付数据等),直接传输存在安全风险,对JSON数据进行加密与解密是保障数据安全的重要环节,本文将详细介绍安卓中JSON加密解密的实现方法,包括常见加密算法的选择、具体代码示例及注意事项。
JSON加密解密的必要性
JSON数据明文传输时,可能面临以下安全威胁:
- 中间人攻击:攻击者在数据传输过程中窃听、篡改JSON内容;
- 数据泄露:若客户端本地存储的JSON文件(如缓存、配置文件)被恶意读取,敏感信息可能暴露;
- 身份伪造:攻击者通过篡改JSON数据伪造用户身份或操作指令。
通过对JSON数据进行加密,可以确保数据的机密性(只有合法接收者能解密)和完整性(数据未被篡改),从而提升应用安全性。
安卓中JSON加密解密的常见方案
根据安全需求不同,安卓中JSON加密解密可分为对称加密、非对称加密和混合加密三大类,下面分别介绍其实现方式。
(一)对称加密:使用AES加密JSON数据
对称加密是指加密与解密使用相同密钥的加密方式,具有加解密速度快、适合大数据量加密的优点,常见的对称加密算法包括AES(高级加密标准)、DES等,其中AES因安全性高、性能优,成为安卓开发中的首选。
AES加密原理
AES加密需要三个核心要素:密钥(Key)、初始化向量(IV)和加密模式。
- 密钥:用于加密和解密的秘钥,长度通常为128/192/256位(16/24/32字节);
- 初始化向量(IV):增加加密的随机性,避免相同明文生成相同密文,长度需与加密块大小一致(AES为16字节);
- 加密模式:常见的有ECB(电子密码本,不推荐,因安全性较低)、CBC(密码分组链接,需IV)、GCM(伽罗瓦/计数器模式,支持加密认证,安全性更高)。
具体实现步骤
(1)添加依赖
在app/build.gradle中添加加密库依赖(如conscrypt,提供更安全的加密实现):
implementation 'org.conscrypt:conscrypt-android:2.5.2'
(2)生成密钥和IV
AES密钥可通过KeyGenerator生成,IV可通过SecureRandom生成随机数:
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
public class AESUtils {
// AES密钥长度(256位)
private static final int KEY_SIZE = 256;
// IV长度(AES块大小为128位,即16字节)
private static final int IV_SIZE = 16;
// 生成AES密钥
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(KEY_SIZE);
return keyGenerator.generateKey();
}
// 生成随机IV
public static IvParameterSpec generateIv() {
byte[] iv = new byte[IV_SIZE];
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
}
(3)加密JSON字符串
将JSON字符串转换为字节数组,使用AES加密:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class AESUtils {
// 加密
public static String encrypt(String jsonStr, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 加密模式:CBC,填充方式:PKCS5Padding
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv);
byte[] encryptedBytes = cipher.doFinal(jsonStr.getBytes(StandardCharsets.UTF_8));
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT); // Base64编码,便于传输/存储
}
}
(4)解密密文字符串
将Base64解码后的字节数组通过AES解密:
public class AESUtils {
// 解密
public static String decrypt(String encryptedStr, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getEncoded(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
byte[] decodedBytes = Base64.decode(encryptedStr, Base64.DEFAULT);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
}
(5)使用示例
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// 1. 生成密钥和IV
SecretKey key = AESUtils.generateKey();
IvParameterSpec iv = AESUtils.generateIv();
// 2. 准备JSON数据
JSONObject json = new JSONObject();
json.put("username", "zhangsan");
json.put("password", "123456");
String jsonStr = json.toString();
// 3. 加密
String encryptedStr = AESUtils.encrypt(jsonStr, key, iv);
Log.d("加密结果", encryptedStr);
// 4. 解密
String decryptedStr = AESUtils.decrypt(encryptedStr, key, iv);
Log.d("解密结果", decryptedStr);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意事项
- 密钥管理:对称加密的密钥需要安全存储(如安卓
Keystore系统),避免硬编码在代码中; - IV的使用:IV无需保密,但必须是随机且唯一的,建议每次加密都生成新的IV;
- 填充方式:AES需填充数据至16字节的整数倍,PKCS5Padding是常用填充方式;
- 模式选择:优先选择GCM模式(如
AES/GCM/NoPadding),支持加密认证,可防止数据篡改。
(二)非对称加密:使用RSA加密JSON数据
对称加密的密钥分发问题(如何安全地将密钥传给接收方)可通过非对称加密解决,非对称加密使用公钥加密、私钥解密(或私钥签名、公钥验证),常见算法有RSA、ECC等。
RSA加密原理
RSA算法有一对密钥:公钥(Public Key)(公开,用于加密)和私钥(Private Key)(保密,用于解密),由于公钥加密的内容只能被私钥解密,因此适合传输对称加密的密钥(即“密钥加密”场景)。
具体实现步骤
(1)生成RSA密钥对
通过KeyPairGenerator生成RSA公钥和私钥:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
public class RSAUtils {
// RSA密钥长度(2048位或更高)
private static final int KEY_SIZE = 2048;
// 生成RSA密钥对
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(KEY_SIZE);
return keyPairGenerator.generateKeyPair();
}
}
(2)获取公钥和私钥
// 获取公钥(Base64编码,便于传输)
public static String getPublicKey(KeyPair keyPair) {
return Base64.encodeToString(keyPair.getPublic().getEncoded(), Base64.DEFAULT);
}
// 获取私钥(Base64编码,建议存储在Keystore中)
public static String getPrivateKey(KeyPair keyPair) {
return Base64.encodeToString(keyPair.getPrivate().getEncoded(), Base64.DEFAULT);
}
(3)使用公钥加密JSON数据
RSA加密有长度限制(2048位密钥最多加密245字节),因此需加密“对称加密的密钥”,而非直接加密JSON(JSON通常较长),以下示例演示用RSA加密AES密钥:
import javax.crypto.Cipher;
import java.security.PublicKey;
public class RSAUtils {
// 公钥加密(加密AES密钥)
public static String encryptWithPublicKey(String data, String publicKeyStr) throws Exception {
byte[] publicKeyBytes = Base64.decode(public


还没有评论,来说两句吧...