当前位置: 代码迷 >> 综合 >> 2.2.2 Android Base64,Hex,URLEncoding编码和解码,以及AES,DES,MD5加密和解密的工具类
  详细解决方案

2.2.2 Android Base64,Hex,URLEncoding编码和解码,以及AES,DES,MD5加密和解密的工具类

热度:63   发布时间:2023-12-16 16:09:56.0
编码,解码:
 
 
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.EditText;import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;public class MainActivity extends AppCompatActivity {private EditText txtContent;private EditText txtPassword;private EditText txtResult;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);txtContent = (EditText) findViewById(R.id.txt_content);txtPassword = (EditText) findViewById(R.id.txt_password);txtResult = (EditText) findViewById(R.id.txt_result);gzipTest();}private void gzipTest() {FileOutputStream fout = null;GZIPOutputStream gzipOutputStream = null;File directory = Environment.getExternalStorageDirectory();File file = new File(directory, "myself.gz"); // GZIP 压缩的文件通常都是 .gz 结尾PrintStream ps = null;try {fout = new FileOutputStream(file);gzipOutputStream = new GZIPOutputStream(fout);ps = new PrintStream(gzipOutputStream);for (int i = 0; i < 100; i++) {ps.println("Hello World by GZIPOutputStream");}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (ps != null) {try {ps.close();} catch (Exception e) {e.printStackTrace();}}if (gzipOutputStream != null) {try {gzipOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if (fout != null) {try {fout.close();} catch (IOException e) {e.printStackTrace();}}}}private void urlEncodingTest() {// 将非网址字符串,转换为 %XX 这种显示形式;try {String encode = URLEncoder.encode("变形金刚", "UTF-8");// 参数2 必须和服务器支持的编码一致;Log.d("MainActivity", "urlEncoding => " + encode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}try {// 解码部分,用于将 编码的内容还原为 实际内容,注意第二个参数的问题// 需要和编码一致;String decode = URLDecoder.decode("%E5%8F%98%E5%BD%A2%E9%87%91%E5%88%9A", "UTF-8");Log.d("MainActivity", "urlDecode => " + decode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}try {String encode = URLEncoder.encode("I Love Android !!! 张哥. ", "UTF-8");Log.d("MainActivity", "中文英文 " + encode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}private void hexTest() {String s = null;try {s = CryptUtil.hexEncode("你好".getBytes("GBK"));Log.d("MainActivity", "你好 hex = " + s);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}private void base64Test() {String str =Base64.encodeToString("你".getBytes(), Base64.NO_WRAP);Log.d("MainActivity", "Base64 编码的 你 = " + str);str =Base64.encodeToString("好".getBytes(), Base64.NO_WRAP);Log.d("MainActivity", "Base64 编码的 好 = " + str);str =Base64.encodeToString("你好".getBytes(), Base64.NO_WRAP);Log.d("MainActivity", "Base64 编码的 你好 = " + str);// --------------------------// 解码// 1. 模拟生成编码之后的数据;str = Base64.encodeToString("I love 安卓!".getBytes(), Base64.NO_WRAP);// 解码时注意事项,第二个参数的取值,应该和编码时一致;byte[] data = Base64.decode(str, Base64.NO_WRAP);String decodedStr = new String(data);Log.d("MainActivity", "解码字符串 " + decodedStr);String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM62H9NVaAFL54uyqjNv11J7eeOsh/xRQ2c31zUXGmFvuq5iUVxahQBNKa5O3w4qoOdzCt6yw+Fcl9hN/9NV9pWiCUBzNBluUMyqTb2Qs+bULisevBk810Uevo/Cct+gu+6e2tTal2dXszAXK7tYjJqd5Rzmc/qJRzFPNn4j3W2NAgMBAAECgYEAwEDBHtPrNHF9O/+Cru5RLGSs++SmYTTPZLuZy8XeAkthK/lDRIrn8lzR7E1sxYc+OaVUscU/y2VL0KDS06K6/8gVCcJe4UiCjIBXyhmwNBKBHf4jlKKAlaWZkPwJSxpfE1O16epBvTHZdyEY0ALfMnvQlUZ8RAAXo5DHGutHscECQQD++08BYfWDhYVpDzlEcPM+9fyecen8vGiX/T0+LB88kREIldjiQmqJyBvKECRBUJYg+2mqHGQjQMfBHfaaUsC9AkEAz4l27Qps5e93EmNlDn3RsMH+JVzMu0442nA8SbpRJOtmuqYDZAH7W2uj3J3J1gIbZg5zCxQc9rLDYcq2wo21EQJBAK1x/ZgPLpa8qLeCZ44q1wwpACI3ktccwnlBBfvYv5bPhyqz48hlLVt0B5M3z7GuQ7FD0+inT2a7liXDYBAx4nECQD8SSsc9LN0wSmKXPGYMDMcIHcGjE0E1Q4f3JgtOCU0MEVtWCp/BDm+5JcJtXaKhX0xDxeivAyJiL4ivv50ezdECQHptoOYG0tMCHL0oOXrZXsdpAFL/c8vX25Oq/uaYaR+Zgv02ipt+81YQ+8nYTwD55TZytt0TcifqUQhDf0y7XyQ=";data = Base64.decode(privateKey, Base64.NO_WRAP);}public void btnGenZip(View view) {// 生成ZIP文件,压缩文件File directory =Environment.getExternalStorageDirectory();// 文件对象File file = new File(directory, "myself.zip");try {// 压缩包对象FileOutputStream fout = new FileOutputStream(file);// 用于创建压缩文件ZipOutputStream zout = new ZipOutputStream(fout);// 压缩文件之前,需要添加文件的实体,到 zout,相当于添加一个空的文件zout.putNextEntry(new ZipEntry("Hello.txt"));// write 向 Entry 文件中写内容zout.write("Hello World by ZipOutputStream".getBytes());zout.closeEntry(); // 代表文件Entry添加完成zout.close(); // 关闭 Zip文件// 添加文件的步骤// putNextEntry()// write// closeEntry()fout.close();} catch (IOException e) {e.printStackTrace();}}public void btnDesEncrypt(View view) {// DES 加密String content = txtContent.getText().toString();String password = txtPassword.getText().toString();// TODO: DES 算法,要求密码的长度必须是 8个字节;if(password.length() == 8){byte[] contentData = content.getBytes();byte[] passwordData = password.getBytes();// 加密解密用的都是字节数组byte[] bytes = CryptUtil.desEncrypt(contentData, passwordData);// !!! 加密的结果不允许直接 new String() !!!String str = Base64.encodeToString(bytes, Base64.NO_WRAP);txtResult.setText(str);// ----// 验证解密方法byte[] data = CryptUtil.desDecrypt(bytes, passwordData);str = new String(data);Log.d("MainActivity", "解密的数据是 " + str);}}
}

加密,机密工具类:
import java.security.*;
import java.security.spec.InvalidKeySpecException;import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;/*** 加密解密工具类*/
public final class CryptUtil {private CryptUtil() {}// ---------------------// RSA密钥生成/*** RSA 加密,参数 key 可以是 公钥,或者 私钥;* <p/>* !!! 如果使用 私钥加密,那么只能够使用 公钥解密* 如果使用 公钥加密,那么只能够使用 私钥解密** @param data* @param key* @return*/public static byte[] rsaEncrypt(byte[] data, Key key) {byte[] ret = null;if (data != null && data.length > 0 && key != null) {try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, key);ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}return ret;}public static byte[] rsaDecrypt(byte[] data, Key key) {byte[] ret = null;if (data != null && data.length > 0 && key != null) {try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, key);ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}return ret;}/*** 生成 RSA 密钥信息,参数就是生成的尺寸位数* 支持 1024, 2048, 4096** @param keySize* @return*/public static KeyPair generateRSAKey(int keySize) {KeyPair ret = null;// 1. 使用密钥生成器来创建try {KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); // RSA 算法// 设置密钥位数 也就是 n 的位数kpg.initialize(keySize);ret = kpg.generateKeyPair();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return ret;}// ---------------------// AES 加密,采用简单加密的算法,一个密码/*** AES 加密,采用一套密码的形式,密码长度支持 128bit** @param data* @param password* @return*/public static byte[] aesEncrypt(byte[] data, byte[] password) {byte[] ret = null;if (data != null && password != null) {if (data.length > 0 && password.length == 16) { // 128bit// 1. 创建 Ciphertry {Cipher cipher = Cipher.getInstance("AES");// 2. 创建 AES 简单的密码 KeySecretKeySpec key = new SecretKeySpec(password, "AES");// 3. 初始化cipher.init(Cipher.ENCRYPT_MODE, key);ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}public static byte[] aesDecrypt(byte[] data, byte[] password) {byte[] ret = null;if (data != null && password != null) {if (data.length > 0 && password.length == 16) { // 128bit// 1. 创建 Ciphertry {Cipher cipher = Cipher.getInstance("AES");// 2. 创建 AES 简单的密码 KeySecretKeySpec key = new SecretKeySpec(password, "AES");// 3. 初始化cipher.init(Cipher.DECRYPT_MODE, key);ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}// ---------------------/*** DESede 要求密码 24字节** @param data* @param password* @return*/public static byte[] desedeEncrypt(byte[] data, byte[] password) {// DESede 算法 Cipher// DESedeKeySpecbyte[] ret = null;if (data != null && password != null) {// DESedeif (data.length > 0 && password.length == 24) {// 1. 创建 Cipher ,用于加密和解密,就是一个内部的算法引擎// getInstance("加密的算法名称")try {Cipher cipher = Cipher.getInstance("DESede");// 3. 生成 Key 对象,根据不同的算法DESedeKeySpec keySpec = new DESedeKeySpec(password);// 3.2 使用密钥生成工具,来生成实际的 Key 对象SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");// 参数为算法名称// 3.3 生成 KeySecretKey secretKey = keyFactory.generateSecret(keySpec);// 2. 初始化 Cipher,设置是加密模式还是解密模式,同时设置密码// 通常第二个参数可以使用  Key 对象,每一种算法,Key对象的生成是不同的cipher.init(Cipher.ENCRYPT_MODE, secretKey);// 4. 进行加密或者解密的实际操作;// 返回值就是最终的结果了ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {  // 找不到算法的异常e.printStackTrace();} catch (NoSuchPaddingException e) { //e.printStackTrace();} catch (InvalidKeyException e) {  // 非法的密钥异常e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}public static byte[] desedeDecrypt(byte[] data, byte[] password) {byte[] ret = null;if (data != null && password != null) {// DESede 24字节if (data.length > 0 && password.length == 24) {// 1. 创建 Cipher ,用于加密和解密,就是一个内部的算法引擎// getInstance("加密的算法名称")try {Cipher cipher = Cipher.getInstance("DESede");// 3. 生成 Key 对象,根据不同的算法DESedeKeySpec keySpec = new DESedeKeySpec(password);// 3.2 使用密钥生成工具,来生成实际的 Key 对象SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");// 参数为算法名称// 3.3 生成 KeySecretKey secretKey = keyFactory.generateSecret(keySpec);// 2. 初始化 Cipher,设置是加密模式还是解密模式,同时设置密码// 通常第二个参数可以使用  Key 对象,每一种算法,Key对象的生成是不同的cipher.init(Cipher.DECRYPT_MODE, secretKey);// 4. 进行加密或者解密的实际操作;// 返回值就是最终的结果了ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {  // 找不到算法的异常e.printStackTrace();} catch (NoSuchPaddingException e) { //e.printStackTrace();} catch (InvalidKeyException e) {  // 非法的密钥异常e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}// ---------------------// 对称加密 DES 部分public static byte[] desEncrypt(byte[] data, byte[] password) {byte[] ret = null;if (data != null && password != null) {// DES 密码必须是8个字节;标准的描述是按位描述;必须是 64bitif (data.length > 0 && password.length == 8) {// 1. 创建 Cipher ,用于加密和解密,就是一个内部的算法引擎// getInstance("加密的算法名称")try {Cipher cipher = Cipher.getInstance("DES");// 3. 生成 Key 对象,根据不同的算法DESKeySpec keySpec = new DESKeySpec(password);// 3.2 使用密钥生成工具,来生成实际的 Key 对象SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 参数为算法名称// 3.3 生成 KeySecretKey secretKey = keyFactory.generateSecret(keySpec);// 2. 初始化 Cipher,设置是加密模式还是解密模式,同时设置密码// 通常第二个参数可以使用  Key 对象,每一种算法,Key对象的生成是不同的cipher.init(Cipher.ENCRYPT_MODE, secretKey);// 4. 进行加密或者解密的实际操作;// 返回值就是最终的结果了ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {  // 找不到算法的异常e.printStackTrace();} catch (NoSuchPaddingException e) { //e.printStackTrace();} catch (InvalidKeyException e) {  // 非法的密钥异常e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}public static byte[] desDecrypt(byte[] data, byte[] password) {byte[] ret = null;if (data != null && password != null) {// DES 密码必须是8个字节;标准的描述是按位描述;必须是 64bitif (data.length > 0 && password.length == 8) {// 1. 创建 Cipher ,用于加密和解密,就是一个内部的算法引擎// getInstance("加密的算法名称")try {Cipher cipher = Cipher.getInstance("DES");// 3. 生成 Key 对象,根据不同的算法DESKeySpec keySpec = new DESKeySpec(password);// 3.2 使用密钥生成工具,来生成实际的 Key 对象SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 参数为算法名称// 3.3 生成 KeySecretKey secretKey = keyFactory.generateSecret(keySpec);// 2. 初始化 Cipher,设置是加密模式还是解密模式,同时设置密码// 通常第二个参数可以使用  Key 对象,每一种算法,Key对象的生成是不同的cipher.init(Cipher.DECRYPT_MODE, secretKey);// 4. 进行加密或者解密的实际操作;// 返回值就是最终的结果了ret = cipher.doFinal(data);} catch (NoSuchAlgorithmException e) {  // 找不到算法的异常e.printStackTrace();} catch (NoSuchPaddingException e) { //e.printStackTrace();} catch (InvalidKeyException e) {  // 非法的密钥异常e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();}}}return ret;}// ---------------------// 编码解码部分;// Encode 编码// Decode 解码// Base64 -> 使用 android.util.Base64 就可以了,不需要// Hex 编码// 将字节数组每一个字节编码为十六进制字符串// 0x3C => "3c" "3C"// 0x5D => "5d" "5D"/*** Hex 编码** @return*/public static String hexEncode(byte[] data) {String ret = null;if (data != null) {StringBuilder sb = new StringBuilder();for (byte b : data) {int i = b & 0x0FF;String s = Integer.toHexString(i); // 消除符号,不用补码显示// 15 => "0F"if (i < 16) {sb.append('0');}sb.append(s);}ret = sb.toString();}return ret;}public static byte[] hexDecode(String str) {byte[] ret = null;if (str != null) {int len = str.length();if (len > 0 && len % 2 == 0) {ret = new byte[len >> 1];int rLen = ret.length;for (int i = 0; i < rLen; i++) {int start = i * 2;// substring 第二个参数在 Android 中,代表 结束索引要求 + 1// 因此 使用 start + 2 -> 包含了 start, start + 1;String subStr = str.substring(start, start + 2); // start, endint i1 = Integer.parseInt(subStr, 16);ret[i] = (byte) i1;}}}return ret;}// ---------------------}



  相关解决方案