Java AES加密解密工具 -- GUI 、在线传输文件

本文介绍了Java中AES加密解密的原理和步骤,包括如何使用Cipher和KeyGenerator类进行加密解密操作。文章还展示了如何构建GUI界面,并结合网络传输实现文件的安全加密传输。

原理

对于任意长度的明文,AES首先对其进行分组,每组的长度为128位。分组之后将分别对每个128位的明文分组进行加密。

对于每个128位长度的明文分组的加密过程如下:

    (1)将128位AES明文分组放入状态矩阵中。

    (2)AddRoundKey变换:对状态矩阵进行AddRoundKey变换,与膨胀后的密钥进行异或操作(密钥膨胀将在实验原理七中详细讨论)。

    (3)10轮循环:AES对状态矩阵进行了10轮类似的子加密过程。前9轮子加密过程中,每一轮子加密过程包括4种不同的变换,而最后一轮只有3种变换,前9轮的子加密步骤如下:

  • ● SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;
  • ● ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;
  • ● MixColumns变换:MixColumns变换对状态矩阵的列进行变换;
  • ● AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作。
最后一轮的子加密步骤如下:
  • ● SubBytes变换:SubBytes变换是一个对状态矩阵非线性的变换;
  • ● ShiftRows变换:ShiftRows变换对状态矩阵的行进行循环移位;
  • ● AddRoundKey变换:AddRoundKey变换对状态矩阵和膨胀后的密钥进行异或操作;

    (4)经过10轮循环的状态矩阵中的内容就是加密后的密文。

步骤

主要用到的java类有:

  • 类 Cipher
    java.lang.Object
    javax.crypto.Cipher,主要提供加密解密功能

  • 类 KeyGenerator
    java.lang.Object
    javax.crypto.KeyGenerator,此类提供(对称)密钥生成器的功能。

  • 接口 SecretKey
    所有超级接口:
    Key, Serializable
    所有已知子接口:
    PBEKey
    所有已知实现类:
    KerberosKey, SecretKeySpec

加密步骤

  1. 构造密钥生成器,指定为AES算法,不区分大小写
  2. 根据ecnodeRules规则初始化密钥生成器
    生成一个128位的随机源,根据传入的字节数组
  3. 产生原始对称密钥
  4. 获得原始对称密钥的字节数组
  5. 根据字节数组生成AES密钥
  6. 根据指定算法AES自成密码器
  7. 初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
  8. 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
  9. 根据密码器的初始化方式--加密:将数据加密
  10. 将加密后的数据转换为字符串
    这里用Base64Encoder中会找不到包
    解决办法:
    在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
  11. 将字符串返回

效果演示及代码

效果图

1098476-20190330112513970-1447886935.png

1098476-20190330112529327-1730459529.png

1098476-20190330112700211-534204751.png

1098476-20190330112544387-171914714.png

代码

AesJM.java


package AesMmx;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class AesJM {

    public static String MmxEncode(String theKey, String theText) {
        try {
            KeyGenerator k = KeyGenerator.getInstance("AES");//密钥生成器
            k.init(128, new SecureRandom(theKey.getBytes()));//初始化128位生成器
            SecretKey ori_key = k.generateKey();//产生密钥
            byte[] sz = ori_key.getEncoded();//密钥转为二进制数组
            SecretKey key = new SecretKeySpec(sz, "AES");//转为AES密钥
            Cipher c = Cipher.getInstance("AES");//定义AES密码器
            c.init(Cipher.ENCRYPT_MODE, key);//传入密码初始化密码器
            byte[] content_b = theText.getBytes("utf-8");//获取文本的utf-8二进制数组
            byte[] miwen_b = c.doFinal(content_b);//加密
            String miwen = new String(new BASE64Encoder().encode(miwen_b));//加密后的二进制转为String
            return miwen;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String MmxDncode(String theKey, String theText) throws UnsupportedEncodingException, IOException {
        try {
            KeyGenerator k = KeyGenerator.getInstance("AES");
            k.init(128, new SecureRandom(theKey.getBytes()));
            SecretKey ori_key = k.generateKey();
            byte[] sz = ori_key.getEncoded();
            SecretKey key = new SecretKeySpec(sz, "AES");
            Cipher c = Cipher.getInstance("AES");
            c.init(Cipher.DECRYPT_MODE, key);
            byte[] content_b = new BASE64Decoder().decodeBuffer(theText);
            byte[] mingwen_b = c.doFinal(content_b);//解密
            String mingwen = new String(mingwen_b, "utf-8");
            return mingwen;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

Net.java

package AesMmx;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Net {
//网络功能,实现互相传数据功能
    private static int po = 6666;
//默认端口号
    public static void setPo(int port) {    //设置端口号
        po = port;
    }

    public static void ListenNet() throws IOException {     //监听端口功能,接受数据
        while (true) {
            ServerSocket serverSocket = new ServerSocket(po);   //创建服务器socket
            Socket socket = serverSocket.accept();      //监听端口
            InputStream is = socket.getInputStream();   
            InputStreamReader isr = new 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值