java 编解码和加解密

1、String转byte[]的作用

网络传输‌:
在通过网络(如TCP/IP)发送数据时,数据通常需要被转换为字节流。这是因为网络传输是基于字节的,而不是基于字符的

文件存储‌:
将字符串写入文件时,通常需要将字符串转换为字节,因为文件是以字节形式存储数据的。例如,使用FileOutputStream写入文件时,需要先将字符串转换为字节

加密和解密‌:
在加密和解密过程中,数据通常需要先转换为字节,因为加密算法通常处理的是字节数据

哈希计算‌:
在计算字符串的哈希值(如MD5、SHA-1、SHA-256等)时,需要将字符串转换为字节,因为哈希函数作用于字节数据

2、编解码

2.1、标准编码表编码方式名称(仅java)

合法 UFT-8 UFT8 uft-8 uft8 不合法 UFT_8 utf_8
合法 GBK gbk
合法 ISO8859-1 ISO-8859-1 ISO_8859_1 ISO_8859-1 iso8859-1 iso-8859-1 iso_8859_1 iso_8859-1 不合法 ISO-8859_1 iso-8859_1
合法 ASCII ascii US-ASCII us-ascii 不合法 US_ASCII us_ascii

2.1、String与byte[]互转

byte[] getBytes(String charsetName) //String转byte[]
String(byte bytes[], String charsetName) //byte[]转String

import java.io.UnsupportedEncodingException;

public class E1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //String转byte[]
        byte[] bytes = "this is 字符串".getBytes("UTF-8"); // [116,104,105,115,32,105,115,32,-27,-83,-105,-25,-84,-90,-28,-72,-78]
        //byte[]转String
        String str = new String(new byte[]{116,104,105,115,32,105,115,32,-27,-83,-105,-25,-84,-90,-28,-72,-78}, "UTF-8");
    }
}

2.2、Url编解码(避免特殊字符如?, #, &破坏URL结构)

static String encode(String s, String enc) //url编码
static String decode(String s, String enc) //url解码

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

public class E1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //url编码
        String encodeUrl = URLEncoder.encode("http://localhost:8080/首 页.html", "UTF-8"); // http%3A%2F%2Flocalhost%3A8080%2F%E9%A6%96+%E9%A1%B5.html
        //url解码
        String decodeURL = URLDecoder.decode("http%3A%2F%2Flocalhost%3A8080%2F%E9%A6%96+%E9%A1%B5.html", "UTF-8"); // http://localhost:8080/首 页.html
    }
}

2.3、16进制编解码

public class E2 {
    public static void main(String[] args) {
        //编码
        byte[] originalTextBytes1 = "this is 原文".getBytes();
        StringBuilder stringBuilder = new StringBuilder();
        for (byte b : originalTextBytes1) {
            stringBuilder.append(String.format("%02X", b));
        }
        String cipherTextStr = stringBuilder.toString(); // 7468697320697320E58E9FE69687

        //解码
        byte[] originalTextBytes2 = new byte[cipherTextStr.length()/2];
        for (int i = 0; i < cipherTextStr.length(); i += 2) {
            String substring = cipherTextStr.substring(i, i + 2);
            originalTextBytes2[i/2] = (byte) Integer.parseInt(substring, 16);
        }
        String originalTextStr = new String(originalTextBytes2); // this is 原文
    }
}

2.4、Base64加解密(常用于http中传递图片数据或密码token数据)

import java.util.Base64;

public class E3 {
    public static void main(String[] args) {
        //编码
        byte[] originalTextBytes1 = "this is 原文".getBytes(); // [116,104,105,115,32,105,115,32,-27,-114,-97,-26,-106,-121]
        byte[] cipherTextBytes1 = Base64.getEncoder().encode(originalTextBytes1); // [100,71,104,112,99,121,66,112,99,121,68,108,106,112,47,109,108,111,99,61]
        String cipherTextStr = new String(cipherTextBytes1); // dGhpcyBpcyDlrZfnrKbkuLI=

        //解码
        byte[] cipherTextBytes2 = cipherTextStr.getBytes(); // [100,71,104,112,99,121,66,112,99,121,68,108,106,112,47,109,108,111,99,61]
        byte[] originalTextBytes2 = Base64.getDecoder().decode(cipherTextBytes2); // [116,104,105,115,32,105,115,32,-27,-83,-105,-25,-84,-90,-28,-72,-78]
        String originalTextStr2 = new String(originalTextBytes2); // this is 原文
    }
}

2.5、哈希加密(摘要加密)

2.5.1 MD5加密(计算出的结果为128bit的数据,可以转为base64或16进制使用)

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

public class E4 {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        //加密
        byte[] originalTextBytes = "this is 原文".getBytes();
        MessageDigest md5Digest = MessageDigest.getInstance("MD5"); //指定算法
        md5Digest.update(originalTextBytes); //指定要加密的数据
        byte[] cipherTextByte  = md5Digest.digest(); //计算出结果 [-126, 65, -95, -21, 5, -36, -27, -118, -90, -35, -24, -124, -18, -10, 84, 98]
    }
}

2.5.2 SHA-256加密(推荐使用,计算出的结果为256bit的数据,可以转为base64或16进制使用)

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

public class E5 {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        //加密
        byte[] originalTextBytes = "this is 原文".getBytes();
        MessageDigest SHA256Digest = MessageDigest.getInstance("SHA-256"); //指定算法
        SHA256Digest.update(originalTextBytes); //指定要加密的数据
        byte[] cipherTextByte = SHA256Digest.digest(); //计算出结果 [-41, 91, -57, 93, 55, -63, 35, 93, 31, 39, 79, -53, 44, 48, 17, -104, 80, 78, -76, -82, 79, -92, -70, 32, 68, 20, 68, -76, -71, -76, -128, -53]
    }
}

2.5.2 SHA-512加密(计算出的结果为512bit的数据,可以转为base64或16进制使用)

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

public class E6 {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        //加密
        byte[] originalTextBytes = "this is 原文".getBytes();
        MessageDigest SHA512Digest = MessageDigest.getInstance("SHA-512"); //指定算法
        SHA512Digest.update(originalTextBytes); //指定要加密的数据
        byte[] cipherTextByte = SHA512Digest.digest(); //计算出结果 [28, -57, -70, 79, -70, 25, -73, -8, 120, 122, -53, -89, -7, -78, -76, 63, -62, 46, 50, 81, -34, -93, 125, 11, -73, -109, 120, 92, -36, 81, -120, 50, -89, -118, -34, -104, 24, -76, 77, -98, 11, 97, -116, 2, 25, 105, 124, 123, 74, -62, -46, -40, 20, -22, -12, 58, 85, -107, -43, -34, 29, -111, -28, 109]
    }
}

2.6、对称加密

2.6.1 DES加密

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class E7 {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String secretKey = "secretke"; //密钥
        String ivVector = "ivvector"; //IV向量

        /*加密*/
        String originalText = "this is 原文"; //原文
        //【AES算法(需要密钥byte[]长度只能为8)】/【ECB(无需向量参数) CBC(需要向量参数,且向量的byte[]长度必须是8)】/【PKCS5Padding(对原文长度无要求) NoPadding(要求原文byte[]的长度是8的倍数)】
        Cipher cipher1 = Cipher.getInstance("DES/CBC/PKCS5Padding"); //指定算法和模式
        SecretKeySpec secretKeySpec1 = new SecretKeySpec(secretKey.getBytes(), "DES"); //创建AES密钥器并指定密钥
        IvParameterSpec ivParameterSpec1 = new IvParameterSpec(ivVector.getBytes()); //创建IV向量器并指定IV向量
        cipher1.init(
                Cipher.ENCRYPT_MODE, //指定为使用加密模式
                secretKeySpec1, //指定使用的密钥器
                ivParameterSpec1 //指定使用的IV向量器
        );
        byte[] encryptedBytes = cipher1.doFinal(originalText.getBytes()); //对原文的byte[]进行加密 得到byte密文

        /*解密*/
        Cipher cipher2 = Cipher.getInstance("DES/CBC/PKCS5Padding"); //指定算法和模式
        SecretKeySpec secretKeySpec2 = new SecretKeySpec(secretKey.getBytes(), "DES"); //创建AES密钥器并指定密钥
        IvParameterSpec ivParameterSpec2 = new IvParameterSpec(ivVector.getBytes()); //创建IV向量器并指定IV向量
        cipher2.init(
                Cipher.DECRYPT_MODE, //指定为使用解密模式
                secretKeySpec2, //指定使用的密钥器
                ivParameterSpec2 //指定使用的IV向量器
        );
        byte[] decryptedBytes = cipher2.doFinal(encryptedBytes); //对byte密文进行解密 得到原文的byte[]
    }
}

2.6.2 AES加密(推荐使用)

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class E8 {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String secretKey = "thisis secretkey"; //密钥
        String ivVector = "this is ivvector"; //IV向量

        /*加密*/
        String originalText = "this is 原文"; //原文
        //【AES算法(需要密钥byte[]长度只能为16 24 32)】/【ECB(无需向量参数) CBC(需要向量参数,且向量的byte[]长度必须是16)】/【PKCS5Padding(对原文长度无要求) NoPadding(要求原文byte[]的长度是16的倍数)】
        Cipher cipher1 = Cipher.getInstance("AES/CBC/PKCS5Padding"); //指定算法和模式
        SecretKeySpec secretKeySpec1 = new SecretKeySpec(secretKey.getBytes(), "AES"); //创建AES密钥器并指定密钥
        IvParameterSpec ivParameterSpec1 = new IvParameterSpec(ivVector.getBytes()); //创建IV向量器并指定IV向量
        cipher1.init(
                Cipher.ENCRYPT_MODE, //指定为使用加密模式
                secretKeySpec1, //指定使用的密钥器
                ivParameterSpec1 //指定使用的IV向量器
        );
        byte[] encryptedBytes = cipher1.doFinal(originalText.getBytes()); //对原文的byte[]进行加密 得到byte密文

        /*解密*/
        Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); //指定算法和模式
        SecretKeySpec secretKeySpec2 = new SecretKeySpec(secretKey.getBytes(), "AES"); //创建AES密钥器并指定密钥
        IvParameterSpec ivParameterSpec2 = new IvParameterSpec(ivVector.getBytes()); //创建IV向量器并指定IV向量
        cipher2.init(
                Cipher.DECRYPT_MODE, //指定为使用解密模式
                secretKeySpec2, //指定使用的密钥器
                ivParameterSpec2 //指定使用的IV向量器
        );
        byte[] decryptedBytes = cipher2.doFinal(encryptedBytes); //对byte密文进行解密 得到原文的byte[]
    }
}

2.7、非对称加密

2.7.1 RSA加密

2.7.2 DSA加密

posted @ 2025-11-19 10:33  略乏旅人  阅读(2)  评论(0)    收藏  举报