Last active
February 4, 2022 07:23
-
-
Save Forgo7ten/e04b2095d197200bc6b535597008510d to your computer and use it in GitHub Desktop.
DES 加解密
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package my.crypto; | |
import javax.crypto.*; | |
import javax.crypto.spec.DESKeySpec; | |
import javax.crypto.spec.DESedeKeySpec; | |
import javax.crypto.spec.IvParameterSpec; | |
import java.nio.charset.StandardCharsets; | |
import java.security.InvalidAlgorithmParameterException; | |
import java.security.InvalidKeyException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.spec.InvalidKeySpecException; | |
import java.util.Base64; | |
/** | |
* @ClassName DES | |
* @Description DES加解密JAVA实现 | |
* @Author Palmer | |
* @Date 2022/2/3 | |
**/ | |
public class DES { | |
/** | |
* 通过给予的key字节数组,生成DES秘密密钥key | |
* | |
* @param key 字节数组key | |
* @return DES秘密密钥key | |
* @throws InvalidKeyException | |
* @throws NoSuchAlgorithmException | |
* @throws InvalidKeySpecException | |
*/ | |
private static SecretKey getRawKey(byte[] key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException { | |
// 实例化 密钥材料 | |
DESKeySpec desKey = new DESKeySpec(key); | |
// 实例化 密钥生成器 | |
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | |
// 生成密钥 | |
SecretKey secretKey = keyFactory.generateSecret(desKey); | |
return secretKey; | |
} | |
/** | |
* DES ECB 模式加密 | |
* | |
* @param data 需要加密的数据字符串 | |
* @param key 加密的key | |
*/ | |
public static String desECBcrypt(byte[] data, byte[] key) { | |
// 加密结果字节数组 | |
byte[] encrypted; | |
// 加密结果字符串 | |
String result = null; | |
if (null != key && key.length != 8) { | |
System.out.println("DES uses a key length of 8 bytes (64 bits)."); | |
return result; | |
} | |
try { | |
// 生成秘密密钥 | |
SecretKey secretKey = getRawKey(key); | |
// 指定加密模式 实例化Ciper对象 | |
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // 加密方式/工作模式/填充模式 | |
// 初始化,设置加密(1)或解密(2) | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey); | |
// 执行,得到结果字节数组 | |
encrypted = cipher.doFinal(data); | |
// 对结果字节数组进行base64编码,得到加密后的字符串 | |
result = Base64.getEncoder().encodeToString(encrypted); | |
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) { | |
e.printStackTrace(); | |
} | |
return result; | |
} | |
/** | |
* DESede ECB 模式加密 | |
* | |
* @param data 需要加密的数据字符串 | |
* @param key 加密的key | |
*/ | |
public static String des3ECBcrypt(byte[] data, byte[] key) { | |
// 加密结果字节数组 | |
byte[] encrypted; | |
// 加密结果字符串 | |
String result = null; | |
if (null != key && key.length != 24) { | |
System.out.println("DESede uses a key length of 24 bytes (192 bits)."); | |
return result; | |
} | |
try { | |
// 实例化 密钥材料 | |
DESedeKeySpec desKey = new DESedeKeySpec(key); | |
// 实例化 密钥生成器 | |
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); | |
// 生成密钥 | |
SecretKey secretKey = keyFactory.generateSecret(desKey); | |
// 指定加密模式 实例化Ciper对象 | |
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); // 加密方式/工作模式/填充模式 | |
// 初始化,设置加密(1)或解密(2) | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey); | |
// 执行,得到结果字节数组 | |
encrypted = cipher.doFinal(data); | |
// 对结果字节数组进行base64编码,得到加密后的字符串 | |
result = Base64.getEncoder().encodeToString(encrypted); | |
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) { | |
e.printStackTrace(); | |
} | |
return result; | |
} | |
/** | |
* DES CBC 模式加密 | |
* | |
* @param data 需要加密的数据字符串 | |
* @param key 加密的key | |
* @param keyiv CBC模式需要一个iv向量 | |
* @return | |
*/ | |
public static String desCBCcrypt(byte[] data, byte[] key, byte[] keyiv) { | |
// 加密结果字节数组 | |
byte[] encrypted; | |
// 加密结果字符串 | |
String result = null; | |
if (null != key && key.length != 8) { | |
System.out.println("DES uses a key length of 8 bytes (64 bits)."); | |
return result; | |
} | |
if (null != keyiv && keyiv.length != 8) { | |
System.out.println("DES(CBC) uses an IV length of 8 bytes (64 bits)."); | |
return result; | |
} | |
try { | |
// 生成秘密密钥 | |
SecretKey secretKey = getRawKey(key); | |
// 指定加密模式 实例化Ciper对象 | |
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 加密方式/工作模式/填充模式 | |
// CBC模式需要iv向量 | |
IvParameterSpec ivPS = new IvParameterSpec(keyiv); | |
// 初始化,设置加密(1)或解密(2) | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivPS); | |
// 执行,得到结果字节数组 | |
encrypted = cipher.doFinal(data); | |
// 对结果字节数组进行base64编码,得到加密后的字符串 | |
result = Base64.getEncoder().encodeToString(encrypted); | |
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException | InvalidAlgorithmParameterException e) { | |
e.printStackTrace(); | |
} | |
return result; | |
} | |
public static void main(String[] args) { | |
System.out.println(desECBcrypt("Forgo7ten".getBytes(StandardCharsets.UTF_8), "12345678".getBytes(StandardCharsets.UTF_8))); | |
System.out.println(des3ECBcrypt("Forgo7ten".getBytes(StandardCharsets.UTF_8), "123456781234567812345678".getBytes(StandardCharsets.UTF_8))); | |
System.out.println(desCBCcrypt("Forgo7ten".getBytes(StandardCharsets.UTF_8), "12345678".getBytes(StandardCharsets.UTF_8), "12345678".getBytes(StandardCharsets.UTF_8))); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* DES 特征值 | |
*/ | |
/** | |
* 明文初始置换IP | |
*/ | |
const unsigned char IP_Table[] = {58, 50, 42, 34, 26, 18, 10, 2, | |
60, 52, 44, 36, 28, 20, 12, 4, | |
62, 54, 46, 38, 30, 22, 14, 6, | |
64, 56, 48, 40, 32, 24, 16, 8, | |
57, 49, 41, 33, 25, 17, 9, 1, | |
59, 51, 43, 35, 27, 19, 11, 3, | |
61, 53, 45, 37, 29, 21, 13, 5, | |
63, 55, 47, 39, 31, 23, 15, 7}; | |
/** | |
* S盒置换 f函数内 | |
*/ | |
const unsigned char S_Table[8][4][16] = { | |
//S1盒 | |
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, | |
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, | |
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, | |
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, | |
//S2盒 | |
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, | |
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, | |
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, | |
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, | |
//S3盒 | |
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, | |
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, | |
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, | |
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, | |
//S4盒 | |
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, | |
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, | |
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, | |
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, | |
//S5盒 | |
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, | |
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, | |
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, | |
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, | |
//S6盒 | |
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, | |
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, | |
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, | |
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, | |
//S7盒 | |
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, | |
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, | |
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, | |
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, | |
//S8盒 | |
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, | |
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, | |
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, | |
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 | |
}; | |
/** | |
* F函数: P盒置换 | |
*/ | |
const unsigned char P_Table[32] = {16, 7, 20, 21, | |
29, 12, 28, 17, | |
1, 15, 23, 26, | |
5, 18, 31, 10, | |
2, 8, 24, 14, | |
32, 27, 3, 9, | |
19, 13, 30, 6, | |
22, 11, 4, 25}; | |
/** | |
* 逆初始置换IP-1(X) | |
*/ | |
const unsigned char reIP_Table[64] = {40, 8, 48, 16, 56, 24, 64, 32, | |
39, 7, 47, 15, 55, 23, 63, 31, | |
38, 6, 46, 14, 54, 22, 62, 30, | |
37, 5, 45, 13, 53, 21, 61, 29, | |
36, 4, 44, 12, 52, 20, 60, 28, | |
35, 3, 43, 11, 51, 19, 59, 27, | |
34, 2, 42, 10, 50, 18, 58, 26, | |
33, 1, 41, 9, 49, 17, 57, 25}; | |
/** | |
* 密钥初始置换 PC-1置换 | |
*/ | |
const unsigned char PC_1_Table[56] = {57, 49, 41, 33, 25, 17, 9, 1, | |
58, 50, 42, 34, 26, 18, 10, 2, | |
59, 51, 43, 35, 27, 19, 11, 3, | |
60, 52, 44, 36, 63, 55, 47, 39, | |
31, 23, 15, 7, 62, 54, 46, 38, | |
30, 22, 14, 6, 61, 53, 45, 37, | |
29, 21, 13, 5, 28, 20, 12, 4}; | |
/** | |
* 左移 | |
*/ | |
const unsigned char Bit_Round[16] = {1, 1, 2, 2, | |
2, 2, 2, 2, | |
1, 2, 2, 2, | |
2, 2, 2, 1}; | |
/** | |
* PC-2置换 | |
*/ | |
const unsigned char PC_2_Table[48] = {14, 17, 11, 24, 1, 5, | |
3, 28, 15, 6, 21, 10, | |
23, 19, 12, 4, 26, 8, | |
16, 7, 27, 20, 13, 2, | |
41, 52, 31, 37, 47, 55, | |
30, 40, 51, 45, 33, 48, | |
44, 49, 39, 56, 34, 53, | |
46, 42, 50, 36, 29, 32}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment