目录

Android-加解密算法工具类封装AESRSAMD5-一站式解决方案

目录

/weixin_miniapp.png

Android 加解密算法工具类封装:AES、RSA、MD5 一站式解决方案

在 Android 开发中,数据的安全性非常重要,尤其是敏感数据的存储和传输。为了实现数据加密和解密,我们可以封装一个通用的加解密工具类,支持常见的加密算法(如 AES、RSA、DES 等)。以下是一个基于 AES 对称加密算法的工具类封装示例,同时提供扩展性以支持其他算法。

  1. AES 加解密工具类封装

    AES(Advanced Encryption Standard)是一种对称加密算法,加密和解密使用相同的密钥。以下是封装好的工具类:

import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class AESUtil {

    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; // AES 加密模式和填充方式

    /**
     * 加密
     *
     * @param data 待加密的数据
     * @param key  密钥(必须是 16、24 或 32 字节)
     * @return 加密后的 Base64 编码字符串
     */
    public static String encrypt(String data, String key) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密
     *
     * @param encryptedData 加密后的 Base64 编码字符串
     * @param key           密钥(必须是 16、24 或 32 字节)
     * @return 解密后的原始数据
     */
    public static String decrypt(String encryptedData, String key) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.decode(encryptedData, Base64.DEFAULT));
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

使用示例

public class Main {
    public static void main(String[] args) {
        String originalData = "Hello, AES Encryption!";
        String key = "1234567890123456"; // 密钥必须是 16、24 或 32 字节

        // 加密
        String encryptedData = AESUtil.encrypt(originalData, key);
        System.out.println("加密后的数据: " + encryptedData);

        // 解密
        String decryptedData = AESUtil.decrypt(encryptedData, key);
        System.out.println("解密后的数据: " + decryptedData);
    }
}

2.RSA 加解密工具类封装

RSA 是一种非对称加密算法,使用公钥加密、私钥解密。以下是 RSA 工具类的简单实现:

import android.util.Base64;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;

public class RSAUtil {

    private static final String ALGORITHM = "RSA";

    /**
     * 生成 RSA 密钥对
     *
     * @return 生成的密钥对
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(2048); // 密钥长度
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 使用公钥加密
     *
     * @param data      待加密的数据
     * @param publicKey 公钥
     * @return 加密后的 Base64 编码字符串
     */
    public static String encrypt(String data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        return Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
    }

    /**
     * 使用私钥解密
     *
     * @param encryptedData 加密后的 Base64 编码字符串
     * @param privateKey    私钥
     * @return 解密后的原始数据
     */
    public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.decode(encryptedData, Base64.DEFAULT));
        return new String(decryptedBytes);
    }

    /**
     * 将 Base64 编码的公钥字符串转换为 PublicKey 对象
     *
     * @param base64PublicKey Base64 编码的公钥字符串
     * @return PublicKey 对象
     */
    public static PublicKey getPublicKey(String base64PublicKey) throws Exception {
        byte[] keyBytes = Base64.decode(base64PublicKey, Base64.DEFAULT);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    /**
     * 将 Base64 编码的私钥字符串转换为 PrivateKey 对象
     *
     * @param base64PrivateKey Base64 编码的私钥字符串
     * @return PrivateKey 对象
     */
    public static PrivateKey getPrivateKey(String base64PrivateKey) throws Exception {
        byte[] keyBytes = Base64.decode(base64PrivateKey, Base64.DEFAULT);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 将公钥对象转换为 Base64 编码字符串
     *
     * @param publicKey 公钥对象
     * @return Base64 编码的公钥字符串
     */
    public static String getPublicKeyString(PublicKey publicKey) {
        return Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT);
    }

    /**
     * 将私钥对象转换为 Base64 编码字符串
     *
     * @param privateKey 私钥对象
     * @return Base64 编码的私钥字符串
     */
    public static String getPrivateKeyString(PrivateKey privateKey) {
        return Base64.encodeToString(privateKey.getEncoded(), Base64.DEFAULT);
    }
}

使用示例:

import java.security.KeyPair;

public class Main {
    public static void main(String[] args) {
        try {
            // 1. 生成密钥对
            KeyPair keyPair = RSAUtil.generateKeyPair();
            String publicKeyString = RSAUtil.getPublicKeyString(keyPair.getPublic());
            String privateKeyString = RSAUtil.getPrivateKeyString(keyPair.getPrivate());

            System.out.println("公钥: " + publicKeyString);
            System.out.println("私钥: " + privateKeyString);

            // 2. 加密数据
            String originalData = "Hello, RSA Encryption!";
            String encryptedData = RSAUtil.encrypt(originalData, keyPair.getPublic());
            System.out.println("加密后的数据: " + encryptedData);

            // 3. 解密数据
            String decryptedData = RSAUtil.decrypt(encryptedData, keyPair.getPrivate());
            System.out.println("解密后的数据: " + decryptedData);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出示例:

公钥: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1X7...
私钥: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBA...
加密后的数据: jKlQmZ2P3X7v...
解密后的数据: Hello, RSA Encryption!

工具类的功能说明

生成密钥对 :

使用 generateKeyPair() 方法生成 RSA 密钥对(公钥和私钥)。

公钥用于加密,私钥用于解密。

加密数据 :

使用 encrypt() 方法,传入原始数据和公钥,返回加密后的 Base64 编码字符串。

解密数据 :

使用 decrypt() 方法,传入加密后的 Base64 编码字符串和私钥,返回解密后的原始数据。

密钥转换 :

支持将 PublicKey 和 PrivateKey 对象转换为 Base64 编码字符串,便于存储和传输。

支持将 Base64 编码的密钥字符串转换回 PublicKey 或 PrivateKey 对象。

注意事项

密钥长度 :

RSA 密钥长度通常为 2048 位或更高,以确保安全性。

加密数据大小限制 :

RSA 加密的数据大小受密钥长度限制。例如,2048 位密钥最多只能加密 245 字节的数据。如果需要加密更大的数据,可以结合对称加密(如 AES)使用。

密钥存储 :

私钥必须妥善保存,避免泄露。可以使用 Android Keystore 系统来安全存储密钥。

性能 :

RSA 加密和解密速度较慢,适合加密小数据(如密钥或敏感信息)。

3. MD5 工具类封装

MD5 是一种广泛使用的哈希算法,通常用于生成数据的唯一摘要(哈希值)。虽然 MD5 不再推荐用于加密(因为它容易受到碰撞攻击),但它仍然可以用于校验数据完整性或生成唯一标识。以下是 MD5 工具类的封装,并附带使用示例。

代码 :

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

    /**
     * 生成字符串的 MD5 哈希值
     *
     * @param input 输入字符串
     * @return MD5 哈希值(32 位十六进制字符串)
     */
    public static String md5(String input) {
        try {
            // 创建 MessageDigest 实例,指定使用 MD5 算法
            MessageDigest digest = MessageDigest.getInstance("MD5");
            // 将输入字符串转换为字节数组并计算哈希值
            byte[] hashBytes = digest.digest(input.getBytes());

            // 将字节数组转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成文件的 MD5 哈希值
     *
     * @param filePath 文件路径
     * @return 文件的 MD5 哈希值(32 位十六进制字符串)
     */
    public static String md5File(String filePath) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            FileInputStream fis = new FileInputStream(filePath);
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                digest.update(buffer, 0, bytesRead);
            }
            fis.close();

            // 将字节数组转换为十六进制字符串
            byte[] hashBytes = digest.digest();
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

使用示例

示例 1:计算字符串的 MD5 哈希值

public class Main {
    public static void main(String[] args) {
        String input = "Hello, MD5!";
        String md5Hash = MD5Util.md5(input);
        System.out.println("MD5 哈希值: " + md5Hash);
    }
}

输出结果:

MD5 哈希值: ed076287532e86365e841e92bfc50d8c

示例 2:计算文件的 MD5 哈希值:

public class Main {
    public static void main(String[] args) {
        String filePath = "path/to/your/file.txt";
        String md5Hash = MD5Util.md5File(filePath);
        System.out.println("文件的 MD5 哈希值: " + md5Hash);
    }
}

输出结果:

文件的 MD5 哈希值: d41d8cd98f00b204e9800998ecf8427e

**工具类的功能说明

字符串 MD5 哈希:**

md5(String input) 方法用于计算输入字符串的 MD5 哈希值。

返回一个 32 位的十六进制字符串。

文件 MD5 哈希:

md5File(String filePath) 方法用于计算文件的 MD5 哈希值。

适用于校验文件完整性或生成文件的唯一标识。

异常处理:

如果算法不可用(NoSuchAlgorithmException),会捕获异常并返回 null。

文件操作异常(如文件不存在)也会被捕获并返回 null。

/weixin_miniapp.png