DES算法的Java实现(ECB模式)

一、算法原理概述

参考自老师的PPT

加密过程

1541244158363

1541244631502

初始置换IP

1541244740744

迭代T

1541245001052

Feistel轮函数

1541245200505

子秘钥生成

1541245413226

逆置换IP-1

1541245475171

解密过程

1541244245356

二、总体结构

class DES{
   
    //构造函数
	public DES(StringBuffer text, StringBuffer key, int mode) throws Exception {
   }
	//PKCS5填充处理明文
	public StringBuffer dealText(final StringBuffer origin) {
   }
	//初始置换IP
	public void start() {
   
		//把明文或者密文转换成二进制字符串
		//分组加密或解密
        IP(...);
	}
	//IP置换
	public void IP(final String plaintextBinary) {
   
		//通过IP置换明文
        //把置换后的明文分为左右两块
        iterationT(...);
	}
	//迭代T
	public void iterationT(StringBuffer L, StringBuffer R) {
   
		//得到子秘钥
        getSbuKey(...);
		//16次迭代
        	feistel(...);
		//左右交换
		//逆置换
        //生成字符串明文或密文
        //END!
	}
	//Feistel轮函数
	public StringBuffer feistel(final StringBuffer R, final StringBuffer subKey ) {
   
		//E扩展
		//异或运算
		//S-Box
		//P置换
	}
	//子秘钥生成
	public StringBuffer[] getSubKey() {
   
		//把key转换为二进制
		//PC1置换
	    // LS循环16轮生成子密钥
            // 把左右两块合并
            // PC2置换
            // 根据PC2压缩C0D0,得到子密钥
	}
    //主函数
    public static void main(String[] args){
   start();}
}

三、模块分解

PKCS5填充处理明文

public StringBuffer dealText(final StringBuffer origin) {
   
		StringBuffer textBinary = new StringBuffer();
		//使用PKCS#5/PKCS7填充
		int max = group*8;
		int padding = max - origin.length();
        for (int i = 0; i < max; ++i) {
   
        	StringBuffer charBinary;
        	if(i >= origin.length()) {
   
        		charBinary = new StringBuffer(Integer.toBinaryString(padding));
        	}else
        		charBinary = new StringBuffer(Integer.toBinaryString(origin.charAt(i)));
            while (charBinary.length() < 8) {
   
            	charBinary.insert(0, 0);
            }
            textBinary.append(charBinary);
        }
        return textBinary;
	}

字符串转二进制

	public StringBuffer string2Binary(final StringBuffer origin) {
   
		StringBuffer textBinary = new StringBuffer();
        for (int i = 0; i < origin.length(); ++i) {
   
        	StringBuffer charBinary = new StringBuffer(Integer.toBinaryString(origin.charAt(i)));
            while (charBinary.length() < 8) {
   
            	charBinary.insert(0, 0);
            }
            textBinary.append(charBinary);
        }
        return textBinary;
	}

IP置换

	public void IP(final String plaintextBinary) {
   
		//通过IP置换明文
        StringBuffer substitutePlaintext = new StringBuffer(); // 存储置换后的明文
        for (int i = 0; i < 64; ++i) {
   
            substitutePlaintext.append(plaintextBinary.charAt(IP[i] - 1));
        }
        //把置换后的明文分为左右两块
        StringBuffer L = new StringBuffer(substitutePlaintext.substring(0, 32));
        StringBuffer R = new StringBuffer(substitutePlaintext.substring(32));
        iterationT(L, R);
	}

Feistel轮函数

	public StringBuffer feistel(final StringBuffer R, final StringBuffer subKey ) {
   
		//E扩展
		StringBuffer RExtent = new StringBuffer(); // 存储扩展后的右边
        for (int i = 0; i < 48; ++i) {
   
            RExtent.append(R.charAt(E[i] - 1));
        }
		//异或运算
        for (int i = 0; i < 48; ++i) {
   
            RExtent.replace(i, i + 1, (RExtent.charAt(i) == subKey.charAt(i)) ? "0" :"1");
        }
		//S-Box
        StringBuffer SBoxString = new StringBuffer();
        for(int i = 0; i < 8; ++i) {
   
        	String SBoxInput = RExtent.substring(i * 6, (i + 1) * 6);
        	int row = Integer.parseInt(Character.toString(SBoxInput.charAt(0)) + SBoxInput.charAt(5), 2);
            int column = Integer.parseInt(SBoxInput.substring(1, 5), 2);
            
            StringBuffer SBoxOutput = new StringBuffer(Integer.toBinaryString(SBox[i][row * 16 + column]));
            while (SBoxOutput.length() < 4) {
   
                SBoxOutput.insert(0, 0);
            }
            SBoxString.append(SBoxOutput);
        }
		//P置换
        StringBuffer substituteSBoxString= new StringBuffer(); // 存储置换后的R
        for (int i = 0; i < 32; ++i) {
   
        	substituteSBoxString.append(SBoxString.charAt(P[i] - 1));
        }
        return substituteSBoxString;
	}
	

子密钥生成

//子秘钥生成
public StringBuffer[] getSubKey() {
   
	//把key转换为二进制
	StringBuffer keyBinary = string2Binary(key);
	
	StringBuffer[] subKey = new StringBuffer[16]; // 存储子密钥
	//PC1置换
	StringBuffer C0 = new StringBuffer(); // 存储密钥左块
    StringBuffer D0 = new StringBuffer(); // 存储密钥右块
    for (int i = 0; i < 28; ++i) {
   
        C0.append(keyBinary.charAt(PC1[i] - 1));
        D0.append(keyBinary.charAt(PC1[i + 28] - 1));
    }
    
    // LS循环16轮生成子密钥
    for (int i = 0; i < 16; ++i) {
   
        // 循环左移
    	char mTemp;
        mTemp = C0.charAt(0);
        C0.deleteCharAt(0);
        C0.append(mTemp);
        mTemp = D0.charAt(0);
        D0.deleteCharAt(0);
        D0.append(mTemp);
        if(i != 0 && i != 1 && i != 8 && i != 15) {
   
        	mTemp = C0.charAt(0);
            C0.deleteCharAt(0);
            C0.append(mTemp);
            mTemp = D0.charAt(0);
            D0.deleteCharAt(0);
            D0.append(mTemp);
        }
        // 把左右两块合并
        StringBuffer C0D0 = new StringBuffer(C0.toString() + D0.toString());
        
        // PC2置换
        // 根据PC2压缩C0D0,得到子密钥
        StringBuffer C0D0Temp = new StringBuffer();
        for (int j = 0; j < 48; ++j) {
   
            C0D0Temp.append(C0D0.charAt(PC2[j] - 1)
  • 3
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
DES(Data Encryption Standard)是一种对称加密算法,常用于数据加密和解密。 在 Java 中,可以使用 `javax.crypto` 包中的 `Cipher` 类来实现 DES 加密和解密。下面是一个简单的示例: ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class DESUtil { private static final String ALGORITHM = "DES"; private static final String TRANSFORMATION = "DES/ECB/PKCS5Padding"; public static String encrypt(String key, String data) throws Exception { SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] encryptedBytes = cipher.doFinal(data.getBytes()); return Base64.getEncoder().encodeToString(encryptedBytes); } public static String decrypt(String key, String encryptedData) throws Exception { SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes); } } ``` 这个工具类中包含了 `encrypt` 和 `decrypt` 两个方法,用于加密和解密数据。其中 `key` 是加密和解密使用的密钥,`data` 是需要加密的数据,`encryptedData` 是需要解密的数据。 使用示例: ```java String key = "12345678"; // 密钥,必须是8个字节 String data = "Hello, world!"; // 待加密的数据 String encryptedData = DESUtil.encrypt(key, data); // 加密 String decryptedData = DESUtil.decrypt(key, encryptedData); // 解密 System.out.println("加密后的数据:" + encryptedData); System.out.println("解密后的数据:" + decryptedData); ``` 需要注意的是,密钥必须是8个字节,否则会抛出异常。如果需要使用其他长度的密钥,可以考虑使用其他加密算法,如 AES。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值