Android RSA和AES对称加密工具

前言

最近开发 用到数据加密 研究后要用RSA和AES对称加密工具
以前没搞过 记录一下心酸过程

说明

客户端和服务端的加密代码是不同的 即使都是java语言 只有一些模式和参数需要同步设置
比如字节码和加密模式

RSAUtils

package com.mob.common.utils;


import android.util.Base64;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 * RSA加密工具
 */
public class RSAUtils {
    
    

    //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"
    private static String sTransform = "RSA/NONE/PKCS1Padding";

    //进行Base64转码时的flag设置,默认为Base64.DEFAULT
    private static int sBase64Mode = Base64.DEFAULT;

    //初始化方法,设置参数
    public static void init(String transform, int base64Mode) {
    
    
        sTransform = transform;
        sBase64Mode = base64Mode;
    }


    /*
        产生密钥对
        @param keyLength
        密钥长度,小于1024长度的密钥已经被证实是不安全的,通常设置为1024或者2048,建议2048
     */
    public static KeyPair generateRSAKeyPair(int keyLength) {
    
    
        KeyPair keyPair = null;
        try {
    
    

            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            //设置密钥长度
            keyPairGenerator.initialize(keyLength);
            //产生密钥对
            keyPair = keyPairGenerator.generateKeyPair();

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

        return keyPair;
    }

    /*
        加密或解密数据的通用方法
        @param srcData
        待处理的数据
        @param key
        公钥或者私钥
        @param mode
        指定是加密还是解密,值为Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE

     */
    private static byte[] processData(byte[] srcData, Key key, int mode) {
    
    

        //用来保存处理结果
        byte[] resultBytes = null;

        try {
    
    

            //获取Cipher实例
            Cipher cipher = Cipher.getInstance(sTransform);
            //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥
            cipher.init(mode, key);
            //处理数据
            resultBytes = cipher.doFinal(srcData);

        } catch (NoSuchAlgorithmException
         | NoSuchPaddingException | InvalidKeyException 
         | BadPaddingException | IllegalBlockSizeException e) {
    
    
            e.printStackTrace();
        }

        return resultBytes;
    }


    /*
        使用公钥加密数据,结果用Base64转码
     */
    public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) {
    
    

        byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE);
        if (resultBytes != null && resultBytes.length > 0) {
    
    
            return Base64.encodeToString(resultBytes, sBase64Mode);
        }

        return "";

    }

    /*
        使用私钥解密,返回解码数据
     */
    public static byte[] decryptDataByPrivate(String encryptedData, PrivateKey privateKey) {
    
    

        byte[] bytes = Base64.decode(encryptedData, sBase64Mode);

        return processData(bytes, privateKey, Cipher.DECRYPT_MODE);
    }

    /*
        使用私钥进行解密,解密数据转换为字符串,使用utf-8编码格式
     */
    public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey) {
    
    
        return new String(decryptDataByPrivate(encryptedData, privateKey));
    }

    /*
        使用私钥解密,解密数据转换为字符串,并指定字符集
     */
    public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey, String charset) {
    
    
        try {
    
    

            return new String(decryptDataByPrivate(encryptedData, privateKey), charset);

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

        return null;
    }


    /*
        使用私钥加密,结果用Base64转码
     */

    public static String encryptDataByPrivateKey(byte[] srcData, PrivateKey privateKey) {
    
    

        byte[] resultBytes = processData(srcData, privateKey, Cipher.ENCRYPT_MODE);

        return Base64.encodeToString(resultBytes, sBase64Mode);
    }

    /*
        使用公钥解密,返回解密数据
     */

    public static byte[] decryptDataByPublicKey(String encryptedData, PublicKey publicKey) {
    
    

        byte[] bytes = Base64.decode(encryptedData, sBase64Mode);

        return processData(bytes, publicKey, Cipher.DECRYPT_MODE);

    }

    /*
        使用公钥解密,结果转换为字符串,使用默认字符集utf-8
     */
    public static String decryptedToStrByPublicKey(String encryptedData, PublicKey publicKey) {
    
    
        return new String(decryptDataByPublicKey(encryptedData, publicKey));
    }


    /*
        使用公钥解密,结果转换为字符串,使用指定字符集
     */

    public static String decryptedToStrByPublicKey(String encryptedData, PublicKey publicKey, String charset) {
    
    
        try {
    
    

            return new String(decryptDataByPublicKey(encryptedData, publicKey), charset);

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

        return null;
    }




    /*
        将字符串形式的公钥转换为公钥对象
     */

    public static PublicKey keyStrToPublicKey(String publicKeyStr) {
    
    

        PublicKey publicKey = null;

        byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode);

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        try {
    
    

            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            publicKey = keyFactory.generatePublic(keySpec);

        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
    
    
            e.printStackTrace();
        }

        return publicKey;

    }

    /*
        将字符串形式的私钥,转换为私钥对象
     */

    public static PrivateKey keyStrToPrivate(String privateKeyStr) {
    
    

        PrivateKey privateKey = null;

        byte[] keyBytes = Base64.decode(privateKeyStr, sBase64Mode);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

        try {
    
    

            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            privateKey = keyFactory.generatePrivate(keySpec);

        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
    
    
            e.printStackTrace();
        }

        return privateKey;

    }

}

AESUtils

package com.mob.common.utils;


import android.util.Base64;


import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES加密工具
 */
public class AESUtils {
    
    

    /**
     * 加密算法
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * AES 的 密钥长度,32 字节,范围:16 - 32 字节
     */
    public static final int SECRET_KEY_LENGTH = 16;

    /**
     * 字符编码
     */
    private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8;

    /**
     * 秘钥长度不足 16 个字节时,默认填充位数
     */
    private static final String DEFAULT_VALUE = "0";
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * AES 加密
     *
     * @param data      待加密内容
     * @param secretKey 加密密码,长度:16 或 32 个字符
     * @return 返回Base64转码后的加密数据
     */
    public static String encrypt(String data, String secretKey) {
    
    
        try {
    
    
            //创建密码器
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            //初始化为加密密码器
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(secretKey));
            byte[] encryptByte = cipher.doFinal(data.getBytes(CHARSET_UTF8));
            // 将加密以后的数据进行 Base64 编码
            return base64Encode(encryptByte);
        } catch (Exception e) {
    
    
            handleException(e);
        }
        return null;
    }

    /**
     * AES 解密
     *
     * @param base64Data 加密的密文 Base64 字符串
     * @param secretKey  解密的密钥,长度:16 或 32 个字符
     */
    public static String decrypt(String base64Data, String secretKey) {
    
    
        try {
    
    
            byte[] data = base64Decode(base64Data);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            //设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(secretKey));
            //执行解密操作
            byte[] result = cipher.doFinal(data);
            return new String(result, CHARSET_UTF8);
        } catch (Exception e) {
    
    
            handleException(e);
        }
        return null;
    }

    /**
     * 使用密码获取 AES 秘钥
     */
    public static SecretKeySpec getSecretKey(String secretKey) {
    
    
        secretKey = toMakeKey(secretKey, SECRET_KEY_LENGTH, DEFAULT_VALUE);
        return new SecretKeySpec(secretKey.getBytes(CHARSET_UTF8), KEY_ALGORITHM);
    }

    /**
     * 如果 AES 的密钥小于 {@code length} 的长度,就对秘钥进行补位,保证秘钥安全。
     *
     * @param secretKey 密钥 key
     * @param length    密钥应有的长度
     * @param text      默认补的文本
     * @return 密钥
     */
    private static String toMakeKey(String secretKey, int length, String text) {
    
    
        // 获取密钥长度
        int strLen = secretKey.length();
        // 判断长度是否小于应有的长度
        if (strLen < length) {
    
    
            // 补全位数
            StringBuilder builder = new StringBuilder();
            // 将key添加至builder中
            builder.append(secretKey);
            // 遍历添加默认文本
            for (int i = 0; i < length - strLen; i++) {
    
    
                builder.append(text);
            }
            // 赋值
            secretKey = builder.toString();
        }
        return secretKey;
    }

    /**
     * 将 Base64 字符串 解码成 字节数组
     */
    public static byte[] base64Decode(String data) {
    
    
        return Base64.decode(data, Base64.NO_WRAP);
    }

    /**
     * 将 字节数组 转换成 Base64 编码
     */
    public static String base64Encode(byte[] data) {
    
    
        return Base64.encodeToString(data, Base64.NO_WRAP);
    }

    /**
     * 处理异常
     */
    private static void handleException(Exception e) {
    
    
        e.printStackTrace();
    }


}

测试代码

    //字符串公钥
    public static final String PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHhR8P0HdnoXXvgeH2DIIxHWrI\n" +
            "bfH4+rr3sqJ5z/mkBcYu7+n2f74CZABZGXyNyVMZgGB8giPKijBxjZuMAevqHxuR\n" +
            "Yi22DxyOnP3kQXQVaHv9XukPpZXpDsxj6jb1ngy8rRrw2Zb1ofGLDicM2IVB9Ma8\n" +
            "G8wdIPu10qrVytYsLwIDAQAB";

    //字符串密钥
    public static final String PRIVATE_KEY_STR = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJK3E8oqdY/AfV71/Dx+RaYhTV52hdkPgPfTAAyvH5doQvHG0WrgfGoona410P45/6NJ8w02BTWaU3wOwBR082mnmNk18edwb2vi+2RrYhO4micTfNRq5jFwapvh+FqYCJLe1VDWNwQtdLaf7b7OrqG9sZ2vMDyw8bujhdRkOvenAgMBAAECgYAZspV1yKAU0Ltk4aMPmXJrmdOqYwoorc2CGuQcVKQs6ecn4BIYLT+9fGW5+NUlYlVDbZVzz+1zqRdMWG0OaDmmFoyqzZ0te+vwekzdniCBkGK+1i9nSyR6ix9zdmXLxPlh4qxYZ0kiBwPtCKsb1RddlmBEneMGiCtLxe62b0TmQQJBAP1UGTiMOPi+X4i2/PTfBC99fKv/6trXmcczgdJmdS9ThfsO3y9sQbIdwXaR/z6eBKCLb9QYYrNSrFeWUZHj9KECQQCUQyifZXqGYP+5fMMZsKE2RuZf8dQ1OknK73S+EvlaDTvmd/DNGB3v9Kxmh0rJgmdUA6gK9drEVRYuxs1rvr9HAkBHCfBQpTHMv0X3BqmE2Y1I6/2sFgX7/H3JGK6NG+I8tUVbE96OY+NAWYvI/kP/gTx28OMZLQVwl/xwS1zwdmZBAkAn08ak0vjQAlyPslEipI0Z7H/URD0yMz9BcYPVz3kGVMnDhnK8VX8tR3fMbwmLCinBqt3IW/Txir3TwPnLuMjfAkAcbOPSFt0ebHYdKU9aeoFsBnDycT7GYYLWl4h1bZ+TAWcsnp46s1IJLVPIscwOOlIsxgd2+OX2OOSgxXPlT3RD";

    public static final String CONTENT = "TI3b7oglaExMRLZ+2XZrNBW+ExMmbPk+Js9SAKt4xuf1UfGrYIYInQkMUPIt1D4QnOyvnblUfle54B9/IAMNefban5IRBmh4dPKd/c7yqVIGPzWeVujfWJZjFw8owNX0gwNcixb7fbIDk16ZRpZHoqtHLsCzMLljCMYHqHhkwY4=";
               /**
                 * Rsa测试代码
                 */
                String s = RSAUtils.decryptedToStrByPrivate(CONTENT, RSAUtils.keyStrToPrivate(PRIVATE_KEY_STR));
                Log.e("RSA解密:", s);            

                //获取公钥
                PublicKey publicKey = RSAUtils.keyStrToPublicKey(PUBLIC_KEY_STR);
                //获取私钥
                PrivateKey privateKey = RSAUtils.keyStrToPrivate(PRIVATE_KEY_STR);

                //需要加密的数据
                String clearText01 = "123";

                //公钥加密结果
                String publicEncryptedResult = RSAUtils.encryptDataByPublicKey(clearText01.getBytes(), publicKey);
                //私钥解密结果
                String privateDecryptedResult = RSAUtils.decryptedToStrByPrivate(publicEncryptedResult, privateKey);

                Logger.d("公钥加密,私钥解密测试:\n"
                        + "原文:\n" + clearText01 + "\n"
                        + "公钥加密结果:\n" + publicEncryptedResult + "\n"
                        + "私钥解密结果:\n" + privateDecryptedResult
                );


                //需要加密的数据
                String clearText02 = "456";
                //私钥加密结果
                String privateEncryptedResult = RSAUtils.encryptDataByPrivateKey(clearText02.getBytes(), privateKey);
                //公钥解密结果
                String publicDecryptedResult = RSAUtils.decryptedToStrByPublicKey(privateEncryptedResult, publicKey);

                Logger.d("私钥加密,公钥解密测试:\n"
                        + "原文:\n" + clearText02 + "\n"
                        + "私钥加密结果:\n" + privateEncryptedResult + "\n"
                        + "公钥解密结果:\n" + publicDecryptedResult
                );


                /**
                 * AES测试代码
                 */
                try {
    
    
                    String encrypt = AESUtils.decrypt( "jpgg/hUUtntX3D6VAnA7LWw9eGkdfp1WIjtBKnOWOjY=","wyq6hxm1cqmq4w8r");
                    Log.e("AES-解密:", encrypt);

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

猜你喜欢

转载自blog.csdn.net/Life_s/article/details/131330260