文章目录

  • 引言
  • 1、Base64加密
  • 2、DES加密
  • 3、AES加密
  • 4、RSA加密
  • 5、MD5加密

引言

项目中经常会用到Base64DESAESRSAMD5几种加解密方式,每次都要去网上搜索半天,今天索性一次性把他们都汇总起来,以便记忆查找。
JDK版本:1.8.0_45
代码位置:com.leo.demo.encodetest
源码地址:https://gitee.com/leo825/sortalgorithm-demos.git

1、Base64加密

Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法。

package com.leo.demo.encodetest;import java.util.Base64;/*** @ClassName: Base64Util* @Description: Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法* @Author: leo825* @Date: 2020-02-12 17:32* @Version: 1.0*/
public class Base64Util {private static final String CHARSET_UTF_8 = "UTF-8";/*** 使用base64加密** @param content* @return*/public static String encryptData(String content) throws Exception {return Base64.getEncoder().encodeToString(content.getBytes(CHARSET_UTF_8));}/*** 使用base64解密** @param encryptData* @return*/public static String decodeDate(String encryptData) throws Exception {return new String(Base64.getDecoder().decode(encryptData.getBytes()), CHARSET_UTF_8);}public static void main(String[] args) throws Exception {String str = "hello world, base64";System.out.println("原字符串:" + str);String encodeStr = encryptData(str);System.out.println("base64加密后:" + encodeStr);System.out.println("base64解密后:" + decodeDate(encodeStr));}
}

打印结果如下:

原字符串:hello world, base64
base64加密后:aGVsbG8gd29ybGQsIGJhc2U2NA==
base64解密后:hello world, base64

2、DES加密

DES是一个分组加密算法,它以64位为分组对数据加密。64位一组的明文从算法的一端输入,64位的密文从另一端输出,特点是数据加密标准,速度快,适用于加密大量数据的场合。**DES是一种对称加密算法,对称加密就是加解密秘钥是一样一样的。

package com.leo.demo.encodetest;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;/*** @ClassName: DESUtil* @Description: DES加密* DES是对称性加密里面常见一种,全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。* 密钥长度是64位(bit),超过位数密钥被忽略。所谓对称性加密,加密和解密密钥相同。* 对称性加密一般会按照固定长度,把待加密字符串分成块。不足一整块或者刚好最后有特殊填充字符* @Author: leo825* @Date: 2020-02-12 10:02* @Version: 1.0*/
public class DESUtil {private static Key key;private static final String PRIVATE_KEY = "f573a9b0";static {try {KeyGenerator generator = KeyGenerator.getInstance("DES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(PRIVATE_KEY.getBytes());generator.init(secureRandom);key = generator.generateKey();generator = null;} catch (Exception e) {e.printStackTrace();}}/*** 加密,返回BASE64的加密字符串* @param str* @return*/public static String getEncryptString(String str) throws Exception {byte[] strBytes = str.getBytes("UTF-8");Cipher cipher = Cipher.getInstance("DES");cipher.init(Cipher.ENCRYPT_MODE, key);byte[] encryptStrBytes = cipher.doFinal(strBytes);return Base64.getEncoder().encodeToString(encryptStrBytes);}/*** 对BASE64加密字符串进行解密* @param str* @return*/public static String getDecryptString(String str) throws Exception {byte[] strBytes = Base64.getDecoder().decode(str);Cipher cipher = Cipher.getInstance("DES");cipher.init(Cipher.DECRYPT_MODE, key);byte[] encryptStrBytes = cipher.doFinal(strBytes);return new String(encryptStrBytes, "UTF-8");}public static void main(String[] args) throws Exception {String name = "root";String password = "1qaz!QAZ";String encryname = getEncryptString(name);String encrypassword = getEncryptString(password);System.out.println("加密:" + encryname);System.out.println("加密:" + encrypassword);System.out.println("解密:" + getDecryptString(encryname));System.out.println("解密:" + getDecryptString(encrypassword));}
}

打印结果如下:

加密:Lk/2YIL4N+c=
加密:SatR2mGfn3WncqRUHpmsrQ==
解密:root
解密:1qaz!QAZ

3、AES加密

AES高级加密标准(,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。**AES也是一种对称加密算法,对称加密就是加解密秘钥是一样一样的。**详情参考百度百科AES

package com.leo.demo.encodetest;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
/*** @ClassName: AESUtil* @Description: AES 本身就是为了取代 DES 的,AES 具有更好的 安全性、效率 和 灵活性* @Author: leo825* @Date: 2020-02-12 09:46* @Version: 1.0*/
public class AESUtil {/** 加密(对外暴露)*/public static String encryptData(String privateKey, String content) throws Exception {KeyGenerator keygen = getKeyGenerator(privateKey);SecretKey key = new SecretKeySpec(keygen.generateKey().getEncoded(), "AES");return Base64.getEncoder().encodeToString(encrypt(key, content.getBytes("UTF-8")));}/** 解密(对外暴露)*/public static String decryptData(String privateKey, String content) throws Exception {KeyGenerator keygen = getKeyGenerator(privateKey);SecretKey key = new SecretKeySpec(keygen.generateKey().getEncoded(), "AES");return new String(decrypt(key, Base64.getDecoder().decode(content)), "UTF-8");}private static KeyGenerator getKeyGenerator(String privateKey) throws NoSuchAlgorithmException {KeyGenerator keygen = KeyGenerator.getInstance("AES");SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(privateKey.getBytes());keygen.init(128, secureRandom);return keygen;}private static byte[] encrypt(Key key, byte[] srcBytes) {if (key != null) {try {// Cipher负责完成加密或解密工作,基于AESCipher cipher = Cipher.getInstance("AES");// 对Cipher对象进行初始化cipher.init(Cipher.ENCRYPT_MODE, key);// 加密,保存并返回return cipher.doFinal(srcBytes);} catch (Exception e) {e.printStackTrace();}}return null;}private static byte[] decrypt(Key key, byte[] encBytes) {if (key != null) {try {Cipher cipher = Cipher.getInstance("AES");//对Cipher对象进行初始化cipher.init(Cipher.DECRYPT_MODE, key);//解密return cipher.doFinal(encBytes);} catch (Exception e) {e.printStackTrace();}}return null;}public static void main(String[] args) throws Exception {String privateKey = "ABC";String content = "ASD456";String m = encryptData(privateKey, content);System.out.println("要加密的内容为::" + content);System.out.println("根据私钥:" + privateKey + ",加密后的密文是:" + m);System.out.println("根据私钥:" + privateKey + ",解密后的明文是:" + decryptData(privateKey, m));}}

运行结果:

要加密的内容为::ASD456
根据私钥:ABC,加密后的密文是:6vLE6e1f//pq9e+ZmczfxQ==
根据私钥:ABC,解密后的明文是:ASD456

4、RSA加密

RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。通常个人保存私钥,公钥是公开的(可能同时多人持有)。

package com.leo.demo.encodetest;import org.apache.commons.lang3.StringUtils;import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/*** @ClassName: RSAUtil* @Description:*  RSA 加密算法是目前最有影响力的 公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一。*  RSA 是第一个能同时用于 加密 和 数字签名 的算法,它能够 抵抗 到目前为止已知的 所有密码攻击,已被 ISO 推荐为公钥数据加密标准。* @Author: leo825* @Date: 2020-02-12 09:35* @Version: 1.0*/public class RSAUtil {/*** 加密(对外暴露)* 如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。* 如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。** @param keyStr* @param data* @return* @throws Exception*/public static String encryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {if (StringUtils.isEmpty(keyStr)) {return "";}return encryptBASE64(encrypt(getKey(keyStr, isPublicKey), data.getBytes()));}/*** 解密(对外暴露)* 如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密。* 如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密。** @param keyStr* @param data* @return* @throws Exception*/public static String decryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {if (StringUtils.isEmpty(keyStr)) {return "";}return new String(decrypt(getKey(keyStr, isPublicKey), decryptBASE64(data)), "UTF-8");}/*** 加密** @param key* @param srcBytes* @return*/private static byte[] encrypt(Key key, byte[] srcBytes) {if (key != null) {try {//Cipher负责完成加密或解密工作,基于RSACipher cipher = Cipher.getInstance("RSA");//对Cipher对象进行初始化cipher.init(Cipher.ENCRYPT_MODE, key);//加密,并返回return cipher.doFinal(srcBytes);} catch (Exception e) {e.printStackTrace();}}return null;}/*** 解密** @param key* @param encBytes* @return*/private static byte[] decrypt(Key key, byte[] encBytes) {if (key != null) {try {Cipher cipher = Cipher.getInstance("RSA");//对Cipher对象进行初始化cipher.init(Cipher.DECRYPT_MODE, key);//解密并返回结果return cipher.doFinal(encBytes);} catch (Exception e) {e.printStackTrace();}}return null;}/*** 根据key获取公有或者私有key对象** @param keyStr* @param isPublicKey* @return* @throws Exception*/private static Key getKey(String keyStr, Boolean isPublicKey) throws Exception {if (isPublicKey) {return getPublicKey(keyStr);} else {return getPrivateKey(keyStr);}}/*** 根据公有key获取公有key对象** @param key* @return* @throws Exception*/private static RSAPublicKey getPublicKey(String key) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(key);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return (RSAPublicKey) keyFactory.generatePublic(keySpec);}/*** 根据私有key获取私有对象** @param key* @return* @throws Exception*/private static RSAPrivateKey getPrivateKey(String key) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(key);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);}/*** 获取公有/私有Key** @return*/private static KeyPair getRSAKey() {KeyPair keyPair = null;try {//生成公钥和私钥对,基于RSA算法生成对象KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");//初始化密钥对生成器,密钥大小为1024位keyPairGen.initialize(1024);//生成一个密钥对,保存在keyPair中keyPair = keyPairGen.generateKeyPair();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return keyPair;}/*** 对字符串进行BASE64Decoder** @param key* @return* @throws Exception*/private static byte[] decryptBASE64(String key) {return Base64.getDecoder().decode(key);}/*** 对字节数组进行BASE64Encoder** @param key* @return* @throws Exception*/private static String encryptBASE64(byte[] key) {return Base64.getEncoder().encodeToString(key);}public static void main(String[] args) {// 生成的一对key保存好try {//得到私钥和公钥KeyPair keyPair = getRSAKey();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();String pubKey = encryptBASE64(publicKey.getEncoded());String priKey = encryptBASE64(privateKey.getEncoded());System.out.println("公钥:" + pubKey);System.out.println("私钥:" + priKey);// 测试String message = "QWERDF";System.out.println("明文:" + message);String jiami = encryptData(pubKey, message, true);System.out.println("公钥加密后:" + jiami);String jiemi = decryptData(priKey, jiami, false);System.out.println("用私钥解密后的结果是:" + jiemi);jiami = encryptData(priKey, message, false);System.out.println("私钥加密后:" + jiami);jiemi = decryptData(pubKey, jiami, true);System.out.println("用公钥解密后的结果是:" + jiemi);} catch (Exception e) {e.printStackTrace();}}}

打印结果如下:

公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUK5sCqFJblXMMUzkPkC7vDmo7S51yIpMlkKDB67eVYh7M7sbPI9MBB3jzlscL08rYpnB7xA8zq5PZZHsALeAa+PU4Kxfkl1shnji11HDIzVOE53sArBqeh/IWScIkM5QY/Me3jXsqg+j8l5XmIVQSqmA+Bj19Vw9LJ9TLm50xLwIDAQAB
私钥:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJQrmwKoUluVcwxTOQ+QLu8OajtLnXIikyWQoMHrt5ViHszuxs8j0wEHePOWxwvTytimcHvEDzOrk9lkewAt4Br49TgrF+SXWyGeOLXUcMjNU4TnewCsGp6H8hZJwiQzlBj8x7eNeyqD6PyXleYhVBKqYD4GPX1XD0sn1MubnTEvAgMBAAECgYAxi2sntlTjntN7eZCI7bNj6DQJY71f3sPJOdUnQsR+RPL7n5QGy3nQzEjbWr1v7P/U9cKDAAn9QxALDxg59R0MI46xAi4NZkP6/p/fA2qTlXFxyBkCvKoOjyMMeH/l7YM90qTg5NB2M+LkOXswrkKj9JAh4zZ7raE6RRdyKu3e4QJBAOhbpRHEDwOX/xa7HDFUWZMWCzMUw1k06QqMJZyrJPfQjH9KOph6r86T+6WxlpC4FfIAWWaahXEzrakaPWnZB0kCQQCjPxQ4z1F5HHDin6tPB1M2uTh0R3WWmNmqtKiChCYePcwco1HmkgaJxMarqpOJj7H2600XiV/R5PZGVMpORRy3AkA527Aj110huPR09YyUn/taC9AoHRBzoyAwVyt6codXCeAiRhqHI22pk+HCpZDnYl9cjke0q990i7i/deA6/ia5AkBNJK/vsLj1nKUT0xRnQjTmtVyiRmqhAhZKfxjqpHxG6jkch2lapkMEs8KWuQMDjK4y2zsRFk/7plFjJwp7Nlm9AkEAjj3xaxd8UIYOZpTq5mv0yyPmXE1zsMIjKQkmXXOma5WZElo7130b70Vj463150C0X/66upP+i9r6NS/ijwkmrg==
明文:QWERDF
公钥加密后:gKeXQIcZf+8u48DLoSOCbwBHGia9hkrvjh+AWiX7GB1pbox6us+ysYfeVNt+QDL39Fzwy/sMMFGsvSxnxR+aZuWWcyYO6C1vsbqgfk/gQ/WnwZzS23w5qEcq1LI2AEwVn3j3T1gQvDGmWgw4D8f3srPi9WgB3YbVNM6TBRtXgyE=
用私钥解密后的结果是:QWERDF
私钥加密后:ACgPe2wS94ttqivgPRGn5sLQIKhim+xmCcYyTBxxB9QsNkNFHAMHF0pt/WhUpEfPiKp4hC3XvOqhGZwLeqlFkGj86bl+WH55jadntDWYIbC0ylMpWlNz7Djdhp+g2mt2+ZnZ8JrNXQYyQkm+AjrrfWyVYccSf8+SVveVaJ548xw=
用公钥解密后的结果是:QWERDF

5、MD5加密

主要是对于密码的加密,MD5加密是不可逆的,加密后无法解密,直接将加密后的数据作为密码;这样就算得到用户密码的MD5值,也无法获取用户的密码,就算是管理员也无法得知用户密码。

package com.leo.demo.encodetest;import java.security.MessageDigest;/*** @ClassName: MD5Util* @Description: MD5加密* MD5,即消息摘要算法(英语:MD5 Message-Digest Algorithm)。* 是一种被广泛使用的密码散列函数,将数据(如一段文字)运算变为另一固定长度值,* 是散列算法的基础原理,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致* @Author: leo825* @Date: 2020-02-12 18:02* @Version: 1.0*/
public class MD5Util {private static final String CHARSET_UTF_8 = "UTF-8";private static final String hexDigIts[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};/*** MD5加密** @param origin      字符* @param charsetname 编码* @return*/public static String encodeData(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (null == charsetname || "".equals(charsetname)) {resultString = byteArrayToHexString(md.digest(resultString.getBytes()));} else {resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));}} catch (Exception e) {}return resultString;}/*** 默认使用的utf-8进行编码,32位小写* @param origin* @return*/public static String encodeData32(String origin) {return encodeData(origin, CHARSET_UTF_8);}/*** 默认使用的utf-8进行编码,32位大写* @param origin* @return*/public static String encodeData32UpperCase(String origin){return encodeData(origin, CHARSET_UTF_8).toUpperCase();}/*** 默认使用的utf-8进行编码,16位小写* @param origin* @return*/public static String encodeData16(String origin){return encodeData(origin, CHARSET_UTF_8).substring(8,24);}/*** 默认使用的utf-8进行编码,16位大写* @param origin* @return*/public static String encodeData16UpperCase(String origin){return encodeData(origin, CHARSET_UTF_8).substring(8, 24).toUpperCase();}private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++) {resultSb.append(byteToHexString(b[i]));}return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0) {n += 256;}int d1 = n / 16;int d2 = n % 16;return hexDigIts[d1] + hexDigIts[d2];}public static void main(String[] args) {String username = "张三";System.out.println(encodeData16(username));System.out.println(encodeData16UpperCase(username));System.out.println(encodeData32(username));System.out.println(encodeData32UpperCase(username));}}

打印结果如下:

a314529aaa0fbe95
A314529AAA0FBE95
615db57aa314529aaa0fbe95b3e95bd3
615DB57AA314529AAA0FBE95B3E95BD3

常见加密工具类Base64、DES、AES、RSA、MD5汇总相关推荐

  1. python常见加密方法实现,DES,AES,RSA,MD5,国密。--更新中

    常见加密算法的简介和python的实现,使用各种库实现,而不是源码实现 对称加密 DES加密 非对称加密 RSA加密 消息摘要算法/签名算法 MD5 国密算法 SM1 对称密码 SM4 对称算法 SM ...

  2. 密码加密工具类(非简单的MD5,UUID加密);

    实际用到的密码加盐的加密方式 这里我单独抽取成了一个工具类,有的时候直接调很方便 PasswordSaltUtil加密 // An highlighted block public class Pas ...

  3. 加密算法(DES,AES,RSA,ECC,MD5,SHA1)简介

    加密算法(DES,AES,RSA,MD5,SHA1)简介 一.对称性加密算法 二.非对称算法 三.散列算法 四.算法举例 1.对称性加密算法有:AES.DES.3DES 1.1.DES(Data En ...

  4. 加密解密工具类(Java,DES)

    一个Java版的DES加密工具类,可以用来进行网络数据传输加密,保存密码的时候进行加密. import java.security.Key; import java.security.spec.Alg ...

  5. 【Java工具类】(30)—DES加密工具类

    Java工具类(30)-DES加密工具类 package com.awifi.cloudnative.container.manage.provider.utils;import org.apache ...

  6. java 在线rsa解密_通用的Java RSA加密工具类,可在线验证通过

    /** * RSA加密工具类 * 使用PKCS1_PADDING填充,密钥长度1024 * 加解密结果在这里测试通过:http://tool.chacuo.net/cryptrsaprikey * 注 ...

  7. Java 开发中常用的 4 种加密方法。MD5加密工具类测试 base64加密工具类测试 SHA加密工具类测试 BCrypt加密工具类测试

    一.工具类 1, md5加密工具类 2, base64加密工具类 3, Bcrypt工具类 二.加密测试 MD5加密测试 base64加密测试 SHA加密测试 BCrypt加密测试 一.工具类 1, ...

  8. Android加密工具类,Android AES加密工具类分享

    1.AES加密工具类 java不支持PKCS7Padding,只支持PKCS5Padding.我们知道加密算法由算法+模式+填充组成,下一篇介绍iOS和Android通用的AES加密,本篇文章使用PK ...

  9. 常见文件的加密工具类

    报表文件(word.excel.pdf.ppt)加密工具类实现. 1 pom文件 <!-- 报表相关架包 --><dependency><groupId>com.i ...

最新文章

  1. AXI DMA DRIVER 阶段性 kernel driver 构建并测试(三 )
  2. linux命令怎么打开优盘,Linux下U盘使用具体步骤
  3. 获得本机的IP,掩码和网关
  4. java清理语句,java – 如何在不使用准备语句的情况下对SQL进行清理
  5. 移植PPP2.4.5到ARM上实现拨号
  6. 安装kenlm出现问题的解决方案gcc g++
  7. python3下使用cv2.imwrite存储带有中文路径图片或者绝对路径图片
  8. php 设置页面内容具有缓存性,php header()设置页面Cache缓存
  9. md5后得到的32位字符串存储到mysql中太占空间了_面试官:你对MySQL高性能优化有什么规范建议?...
  10. Java面试题,成员变量以及成员方法的调用,类和对象的关系,程序详细流程,类和对象栈堆的详细解答
  11. 完美刷机找不到服务器,完美刷机
  12. XcodeGhost作者声明:源于实验,无任何威胁
  13. Matlab数学建模工具
  14. 【从零开始学架构-李运华】08|架构设计三原则
  15. cachecloud部署详细过程
  16. 积分形式的詹森不等式_均值不等式及其积分形式
  17. 多测师拱墅校区肖sir___性能测试之单个接口性能和多个接口性能测试(3)
  18. android广播内容显示在屏幕上,如何将手机屏幕投影到计算机显示器上?
  19. 第一次迭代开发感想——快租车APP
  20. Break Continue Return( BCR ) 三者的区别

热门文章

  1. 物流行业SAP整体解决方案
  2. SAP ERP差异来源和差异处理
  3. abap--关于异常的处理
  4. PC上虚拟机中安装NW 7.02 ABAP试用版
  5. 进军B2B乏力?转转为何一直在原地打转?
  6. “照骗”大行其道,没有人是“无辜的雪花”
  7. Java 怎么 get char_Java KeyCharacterMap.getDeadChar方法代码示例
  8. 华为防火墙查看日志命令_防火墙接入互联网方式,到底有哪些呢?5分钟学会防火墙入网...
  9. java pattern用法_Java Pattern和Matcher用法
  10. 从0搭建一个Springboot+vue前后端分离项目(四)利用Element框架搭建页面主体部分表格与侧边栏