一個聚合的加解密工具類

Kakarotto發表於2018-04-11
轉自: https://blog.csdn.net/u013523377/article/details/52755332

小序

字串,byte[],檔案等物件的加密和解密,是開發當中必不可少的操作。這裡僅基於不同方式的加解密實現,為方便使用固聚合為一個工具類使用,且程式碼實現與前輩們的實現並沒有什麼太大的差別。有需要的親可直接帶走,如若有不正確的地方還望指正。

總覽

functionimpact
String md5(String string)MD5 文字加密
String md5(String string, int times)MD5 文字多次加密
String md5(String string, String slat)MD5 文字鹽值加密
String md5(File file, int style)MD5 檔案 IO/NIO 型別加密
String base64EncodeStr(String string)Base64 文字加密
String base64DecodedStr(String string)Base64 文字解密
String base64EncodeFile(File file)Base64 檔案加密
File base64DecodedFile(String filePath, String code)Base64 檔案 code 編碼解密
String aes(String content, String password, int type)AES 加密/解密
String des(String content, String password, int type)DES 加密/解密
String sha(String string, String type)SHA 加密
byte[] rsa(byte[] data, String string, int type)RSA 加密/解密
Map<String, Object> getKeyPair()獲取金鑰(公鑰/私鑰)
String getKey(Map<String, Object> keyMap, boolean isPublicKey)根據上方金鑰獲取公鑰/私鑰
String sign(byte[] data, String privateKey)根據上方私鑰獲取數字簽名
boolean verify(byte[] data, String publicKey, String sign)數字簽名校驗

程式碼

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> getKeyPair() 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;
    }
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538複製程式碼

實現

md5

// 字串加密
String str = "123456";
System.out.println("一次加密:" + Encryption.md5(str));
System.out.println("二次加密:" + Encryption.md5(str, 2));
System.out.println("鹽值加密:" + Encryption.md5(str, "78"));12345複製程式碼

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));1234複製程式碼

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));1234複製程式碼

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));12345複製程式碼

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));12345複製程式碼

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));1234複製程式碼

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));12345複製程式碼

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.getKeyPair();
    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();
}1234567891011121314151617181920212223242526272829303132複製程式碼

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”);

場景普及

對稱加密

加密和解密用的是同一個金鑰

非對稱加密

金鑰對(即公鑰與私鑰),分別負責加密或解密的任務

非對稱加密+對稱加密

主對稱加密,以非對稱加密方式傳輸對稱加密金鑰


相關文章