一个聚合的加解密工具类

来源:互联网 发布:linux下载mysql的命令 编辑:程序博客网 时间:2024/05/22 05:13

小序

字符串,byte[],文件等对象的加密和解密,是开发当中必不可少的操作。这里仅基于不同方式的加解密实现,为方便使用固聚合为一个工具类使用,且代码实现与前辈们的实现并没有什么太大的差别。有需要的亲可直接带走,如若有不正确的地方还望指正。

代码

import android.annotation.SuppressLint;import android.text.TextUtils;import android.util.Base64;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.security.InvalidKeyException;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.SecretKeySpec;/** * 加解密工具 */public class EncryptUtil {    private EncryptUtil() {        throw new UnsupportedOperationException("cannot be instantiated");    }    /**     * 二进位组转十六进制字符串     *     * @param buf 二进位组     * @return 十六进制字符串     */    private static String parseByte2HexStr(byte buf[]) {        StringBuilder sb = new StringBuilder();        for (byte b : buf) {            String hex = Integer.toHexString(b & 0xFF);            if (hex.length() == 1) {                hex = '0' + hex;            }            sb.append(hex.toUpperCase());        }        return sb.toString();    }    /**     * 十六进制字符串转二进位组     *     * @param hexStr 十六进制字符串     * @return 二进位组     */    private static byte[] parseHexStr2Byte(String hexStr) {        if (hexStr.length() < 1) return null;        byte[] result = new byte[hexStr.length() / 2];        for (int i = 0; i < hexStr.length() / 2; i++) {            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);            result[i] = (byte) (high * 16 + low);        }        return result;    }    /**     * MD5加密     *     * @param string 加密字符串     * @param slat   加密盐值key     * @return 加密结果字符串     */    public static String md5(String string, String slat) {        if (TextUtils.isEmpty(string)) return "";        try {            MessageDigest md5 = MessageDigest.getInstance("MD5");            byte[] bytes = md5.digest((string + slat).getBytes());            String result = "";            for (byte b : bytes) {                String temp = Integer.toHexString(b & 0xff);                if (temp.length() == 1) {                    temp = "0" + temp;                }                result += temp;            }            return result;        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        return "";    }    /**     * MD5加密     *     * @param string 加密字符串     * @return 加密结果字符串     * @see #md5(String, String)     */    public static String md5(String string) {        return TextUtils.isEmpty(string) ? "" : md5(string, "");    }    /**     * MD5的IO文件加密类型     */    public static final int MD5_TYPE_IO = 0;    /**     * MD5的NIO文件加密类型     */    public static final int MD5_TYPE_NIO = 1;    /**     * MD5加密     *     * @param file  加密文件     * @param style 加密文件类型:{@link #MD5_TYPE_NIO} ,{@link #MD5_TYPE_IO}     * @return 加密结果字符串     */    public static String md5(File file, int style) {        if (file == null || !file.isFile() || !file.exists()) return "";        FileInputStream in = null;        String result = "";        byte buffer[] = new byte[8192];        int len;        try {            in = new FileInputStream(file);            MessageDigest md5 = MessageDigest.getInstance("MD5");            byte[] bytes = md5.digest();            if (style == MD5_TYPE_IO) {                while ((len = in.read(buffer)) != -1) {                    md5.update(buffer, 0, len);                }            } else {                MappedByteBuffer byteBuffer = in.getChannel().map(                        FileChannel.MapMode.READ_ONLY, 0, file.length());                md5.update(byteBuffer);            }            for (byte b : bytes) {                String temp = Integer.toHexString(b & 0xff);                if (temp.length() == 1) {                    temp = "0" + temp;                }                result += temp;            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != in) {                try {                    in.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return result;    }    /**     * MD5加密     *     * @param string 加密字符串     * @param times  重复加密次数     * @return 加密结果字符串     */    public static String md5(String string, int times) {        if (TextUtils.isEmpty(string)) return "";        String md5 = md5(string);        for (int i = 0; i < times; i++) md5 = md5(md5);        return md5;    }    /**     * Base64加密     *     * @param string 加密字符串     * @return 加密结果字符串     */    public static String base64EncodeStr(String string) {        if (TextUtils.isEmpty(string)) return "";        return Base64.encodeToString(string.getBytes(), Base64.DEFAULT);    }    /**     * Base64解密     *     * @param string 解密字符串     * @return 解密结果字符串     */    public static String base64DecodedStr(String string) {        if (TextUtils.isEmpty(string)) return "";        return new String(Base64.decode(string, Base64.DEFAULT));    }    /**     * Base64加密     *     * @param file 加密文件     * @return 加密结果字符串     */    public static String base64EncodeFile(File file) {        if (null == file) return "";        try {            FileInputStream inputFile = new FileInputStream(file);            byte[] buffer = new byte[(int) file.length()];            inputFile.read(buffer);            inputFile.close();            return Base64.encodeToString(buffer, Base64.DEFAULT);        } catch (IOException e) {            e.printStackTrace();        }        return "";    }    /**     * Base64解密     *     * @param filePath 解密文件路径     * @param code     解密文件编码     * @return 解密结果文件     */    public static File base64DecodedFile(String filePath, String code) {        if (TextUtils.isEmpty(filePath) || TextUtils.isEmpty(code)) {            return null;        }        File desFile = new File(filePath);        try {            byte[] decodeBytes = Base64.decode(code.getBytes(), Base64.DEFAULT);            FileOutputStream fos = new FileOutputStream(desFile);            fos.write(decodeBytes);            fos.close();        } catch (Exception e) {            e.printStackTrace();        }        return desFile;    }    /**     * Aes加密/解密     *     * @param content  字符串     * @param password 密钥     * @param type     加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}     * @return 加密/解密结果字符串     */    public static String aes(String content, String password, int type) {        try {            KeyGenerator generator = KeyGenerator.getInstance("AES");            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");            secureRandom.setSeed(password.getBytes());            generator.init(128, secureRandom);            SecretKey secretKey = generator.generateKey();            byte[] enCodeFormat = secretKey.getEncoded();            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("AES");            cipher.init(type, key);            if (type == Cipher.ENCRYPT_MODE) {                byte[] byteContent = content.getBytes("utf-8");                return parseByte2HexStr(cipher.doFinal(byteContent));            } else {                byte[] byteContent = parseHexStr2Byte(content);                return new String(cipher.doFinal(byteContent));            }        } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |                UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |                NoSuchProviderException e) {            e.printStackTrace();        }        return null;    }    /**     * Des加密/解密     *     * @param content  字符串内容     * @param password 密钥     * @param type     加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}     * @return 加密/解密结果     */    public static String des(String content, String password, int type) {        try {            SecureRandom random = new SecureRandom();            DESKeySpec desKey = new DESKeySpec(password.getBytes());            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES");            cipher.init(type, keyFactory.generateSecret(desKey), random);            if (type == Cipher.ENCRYPT_MODE) {                byte[] byteContent = content.getBytes("utf-8");                return parseByte2HexStr(cipher.doFinal(byteContent));            } else {                byte[] byteContent = parseHexStr2Byte(content);                return new String(cipher.doFinal(byteContent));            }        } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |                UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |                InvalidKeySpecException e) {            e.printStackTrace();        }        return null;    }    /**     * Sha加密类型     */    public final static String SHA224 = "sha-224";    /**     * Sha加密类型     */    public final static String SHA256 = "sha-256";    /**     * Sha加密类型     */    public final static String SHA384 = "sha-384";    /**     * Sha加密类型     */    public final static String SHA512 = "sha-512";    /**     * Sha加密     *     * @param string 加密字符串     * @param type   加密类型 :{@link #SHA224},{@link #SHA256},{@link #SHA384},{@link #SHA512}     * @return SHA加密结果字符串     */    public static String sha(String string, String type) {        if (TextUtils.isEmpty(string)) return "";        if (TextUtils.isEmpty(type)) type = SHA256;        try {            MessageDigest md5 = MessageDigest.getInstance(type);            byte[] bytes = md5.digest((string).getBytes());            String result = "";            for (byte b : bytes) {                String temp = Integer.toHexString(b & 0xff);                if (temp.length() == 1) {                    temp = "0" + temp;                }                result += temp;            }            return result;        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        return "";    }    /**     * 随机获取密钥(公钥和私钥), 客户端公钥加密,服务器私钥解密     *     * @return 结果密钥对     * @throws Exception     */    public static Map<String, Object> genKeyPair() throws Exception {        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");        keyPairGen.initialize(1024);        KeyPair keyPair = keyPairGen.generateKeyPair();        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();        Map<String, Object> keyMap = new HashMap<>(2);        keyMap.put("RSAPublicKey", publicKey);        keyMap.put("RSAPrivateKey", privateKey);        return keyMap;    }    /**     * 获取公钥/私钥     *     * @param keyMap      密钥对     * @param isPublicKey true:获取公钥,false:获取私钥     * @return 获取密钥字符串     */    public static String getKey(Map<String, Object> keyMap, boolean isPublicKey) {        Key key = (Key) keyMap.get(isPublicKey ? "RSAPublicKey" : "RSAPrivateKey");        return new String(Base64.encode(key.getEncoded(), Base64.DEFAULT));    }    /**     * 获取数字签名     *     * @param data       二进制位     * @param privateKey 私钥(BASE64编码)     * @return 数字签名结果字符串     * @throws Exception     */    public static String sign(byte[] data, String privateKey) throws Exception {        byte[] keyBytes = Base64.decode(privateKey.getBytes(), Base64.DEFAULT);        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);        Signature signature = Signature.getInstance("MD5withRSA");        signature.initSign(privateK);        signature.update(data);        return new String(Base64.encode(signature.sign(), Base64.DEFAULT));    }    /**     * 数值签名校验     *     * @param data      二进位组     * @param publicKey 公钥(BASE64编码)     * @param sign      数字签名字符串     * @return true:校验成功,false:校验失败     * @throws Exception     */    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {        byte[] keyBytes = Base64.decode(publicKey.getBytes(), Base64.DEFAULT);        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);        KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");        PublicKey publicK = keyFactory.generatePublic(keySpec);        Signature signature = Signature.getInstance("MD5withRSA");        signature.initVerify(publicK);        signature.update(data);        return signature.verify(Base64.decode(sign.getBytes(), Base64.DEFAULT));    }    /**     * Rsa公钥加密类型     */    public static final int RSA_PUBLIC_ENCRYPT = 0;    /**     * Rsa公钥解密类型     */    public static final int RSA_PUBLIC_DECRYPT = 1;    /**     * Rsa私钥加密类型     */    public static final int RSA_PRIVATE_ENCRYPT = 2;    /**     * Rsa私钥解密类型     */    public static final int RSA_PRIVATE_DECRYPT = 3;    /**     * Rsa加密/解密(一般情况下,公钥加密私钥解密)     *     * @param data   源数据     * @param string 密钥(BASE64编码)     * @param type   操作类型:{@link #RSA_PUBLIC_ENCRYPT},{@link #RSA_PUBLIC_DECRYPT},{@link #RSA_PRIVATE_ENCRYPT},{@link #RSA_PRIVATE_DECRYPT}     * @return 加密/解密结果字符串     * @throws Exception     */    public static byte[] rsa(byte[] data, String string, int type) throws Exception {        byte[] keyBytes = Base64.decode(string, Base64.DEFAULT);        Key key;        KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");        if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);            key = keyFactory.generatePublic(x509KeySpec);        } else {            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);            key = keyFactory.generatePrivate(pkcs8KeySpec);        }        // 对数据加密        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());        int inputLen = data.length;        ByteArrayOutputStream out = new ByteArrayOutputStream();        int offSet = 0;        byte[] cache;        int i = 0;        // 对数据分段加密        if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PRIVATE_ENCRYPT) {            cipher.init(Cipher.ENCRYPT_MODE, key);            while (inputLen - offSet > 0) {                cache = cipher.doFinal(data, offSet, inputLen - offSet > 117 ? 117 : inputLen - offSet);                out.write(cache, 0, cache.length);                i++;                offSet = i * 117;            }        } else {            cipher.init(Cipher.DECRYPT_MODE, key);            while (inputLen - offSet > 0) {                if (inputLen - offSet > 128) {                    cache = cipher.doFinal(data, offSet, 128);                } else {                    cache = cipher.doFinal(data, offSet, inputLen - offSet);                }                out.write(cache, 0, cache.length);                i++;                offSet = i * 128;            }        }        byte[] result = out.toByteArray();        out.close();        return result;    }}

md5

// 字符串加密String str = "123456";System.out.println("一次加密:" + Encryption.md5(str));System.out.println("二次加密:" + Encryption.md5(str, 2));System.out.println("盐值加密:" + Encryption.md5(str, "78"));

System.out: 一次加密:e10adc3949ba59abbe56e057f20f883e
System.out: 二次加密:c56d0e9a7ccec67b4ea131655038d604
System.out: 盐值加密:25d55ad283aa400af464c76d713c07ad

// 文件加密Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);System.out.println("IO文件加密:" + EncryptUtil.md5(getBitmap2File(bmp), EncryptUtil.MD5_TYPE_IO));System.out.println("NIO文件加密:" + EncryptUtil.md5(getBitmap2File(bmp), EncryptUtil.MD5_TYPE_NIO));

I/System.out: IO文件加密:d41d8cd98f00b204e9800998ecf8427e
I/System.out: NIO文件加密:d41d8cd98f00b204e9800998ecf8427e


Base64

// 字符串加解密String baseStr = EncryptUtil.base64EncodeStr("123456");System.out.println("base64字符串加密:" + baseStr);System.out.println("base64字符串解密:" + EncryptUtil.base64DecodedStr(baseStr));

I/System.out: base64字符串加密:MTIzNDU2
I/System.out: base64字符串解密:123456

// 文件加解密Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);String baseFile = EncryptUtil.base64EncodeFile(getBitmap2File(bmp));System.out.println("base64文件加密:" + baseFile);System.out.println("base64文件解密:" + EncryptUtil.base64DecodedFile("/mnt/sdcard/01.jpg", baseFile));

I/System.out: base64文件加密:
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB

I/System.out: base64文件解密:/mnt/sdcard/01.jpg


AES

// 对象加解密String key = "1234567890123456";String aesStr = EncryptUtil.aes("gzejia", key, Cipher.ENCRYPT_MODE);System.out.println("aes对象加密: " + aesStr);System.out.println("aes对象解密: " + EncryptUtil.aes(aesStr, key, Cipher.DECRYPT_MODE));

I/System.out: aes对象加密: 7E8886393DD34B24CC51B1A9D030DB5A
I/System.out: aes对象解密: gzejia

javax.crypto.BadPaddingException: pad block corrupted,出现该异常的主导原因可能如下:

  1. 密钥key长度不足16位
  2. 缺少 SecureRandom secureRandom = SecureRandom.getInstance(“SHA1PRNG”, “Crypto”);

DES

String key = "1234567890123456";String desStr = EncryptUtil.des("gzejia", key, Cipher.ENCRYPT_MODE);System.out.println("des对象加密: " + desStr);System.out.println("des对象解密: " + EncryptUtil.des(desStr, key, Cipher.DECRYPT_MODE));

I/System.out: des对象加密: 552E6962E5187580
I/System.out: des对象解密: gzejia


SHA

String shaStr = "gzejia";System.out.println("sha_SHA224对象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA224));System.out.println("sha_SHA256对象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA256));System.out.println("sha_SHA384对象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA384));System.out.println("sha_SHA512对象加密: " + EncryptUtil.sha(shaStr, EncryptUtil.SHA512));

I/System.out: sha_SHA224对象加密:
36e2a37256a87dda91e8dacf9662c49461ecfc68d65488857c146e59

I/System.out: sha_SHA256对象加密:
94a9222df72d5927d1996203b0b186ab857d9055db54b48277bf943272b19fc1

I/System.out: sha_SHA384对象加密:
ea8e751bdfccb96715a37153a831fc935e2986743de72b32941043c1960f2e2ab7d71b965dda42cd128a837191e4667a

I/System.out: sha_SHA512对象加密:
a5e7bea71af1fccdc1f3d353df08013e2bebe8e0a49b435512bdc855f36589cffbf1ac1825e2357a4a4f8b5295173928f76a806ba0c77c2a7ba3ef068cdf3ced


RSA

try {    byte[] data = "gzejia有中文".getBytes();    // 密钥与数字签名获取    Map<String, Object> keyMap = EncryptUtil.genKeyPair();    String publicKey = EncryptUtil.getKey(keyMap, true);    System.out.println("rsa获取公钥: " + publicKey);    String privateKey = EncryptUtil.getKey(keyMap, false);    System.out.println("rsa获取私钥: " + privateKey);    // 公钥加密私钥解密    byte[] rsaPublic =            EncryptUtil.rsa(data, publicKey, EncryptUtil.RSA_PUBLIC_ENCRYPT);    System.out.println("rsa公钥加密: " + new String(rsaPublic));    System.out.println("rsa私钥解密: " + new String(            EncryptUtil.rsa(rsaPublic, privateKey, EncryptUtil.RSA_PRIVATE_DECRYPT)));    // 私钥加密公钥解密    byte[] rsaPrivate =            EncryptUtil.rsa(data, privateKey, EncryptUtil.RSA_PRIVATE_ENCRYPT);    System.out.println("rsa私钥加密: " + new String(rsaPrivate));    System.out.println("rsa公钥解密: " + new String(            EncryptUtil.rsa(rsaPrivate, publicKey, EncryptUtil.RSA_PUBLIC_DECRYPT)));    // 私钥签名及公钥签名校验    String signStr = EncryptUtil.sign(rsaPrivate, privateKey);    System.out.println("rsa数字签名生成: " + signStr);    System.out.println("rsa数字签名校验: " +            EncryptUtil.verify(rsaPrivate, publicKey, signStr));} catch (Exception e) {    e.printStackTrace();}

I/System.out: rsa获取公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3W84EWgATxN4OfjXUResyzy+lf/8TDDmHtRkh

I/System.out: rsa获取私钥:
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALdbzgRaABPE3g5+NdRF6zLPL6V/

I/System.out: rsa公钥加密:o�ZW�Ay����&�d��qa�h�]�ɟ�Ӵ�Rg1�0#

I/System.out: rsa私钥解密: gzejia有中文

I/System.out: rsa私钥加密: � ��IA�{�R�+�y�_ ����%�=��

I/System.out: rsa公钥解密: gzejia有中文

I/System.out: rsa数字签名生成:
XYHhwM2d+qUOWfTvi4l0Xh0JHlgf4zOBz81wahV90dxHhoqbi/HG6PlmkPnFnnZAkB5X8VMRKumK

I/System.out: rsa数字签名校验: true

java.security.spec.InvalidKeySpecException:
java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag,解决途径:

原语句: KeyFactory keyf = KeyFactory.getInstance(“RSA”);
更改为:KeyFactory keyFactory = KeyFactory.getInstance(“RSA”, “BC”);

0 0
原创粉丝点击