final byte[] keyBytes = "123456789012345612345678".getBytes(); 3DES 要求密匙的长度是24,DES长度是8 我想请问下3DES的内部是否是将24拆分成3个8位数的密匙进行加密解密的呢?
3DES具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,
K代表DES算法使用的密钥,P代表明文,C代表密表,这样,
3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密过程为:P=Dk1((EK2(Dk3(C)))
在网上查找到这样的定义,然后找到DES的代码进行明文加密,以上面的公式计算3DES却出错。
如果有哪位大哥哥姐姐有通过DES加密让后通过公式得到3DES的代码希望发我一份。邮箱是
[email protected] 万分感谢.................
import java.security.spec.KeySpec;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;public class BcTest { // 3DES key = 00 01 02 03 04 05 06 07 01 02 03 04 05 06 07 08 02 03 04 05 06 07 08 09
// data ("01234567") = 30 31 32 33 34 35 36 37
// 3des cipher = 5a b3 fd 7b 2a ca b2 95
// cipher mode = DESede/ECB/NoPadding
public static void main(String[] args) throws Exception { byte[] key1 = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
byte[] key2 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] key3 = new byte[] { 2, 3, 4, 5, 6, 7, 8, 9 };
byte[] data = "01234567".getBytes(); // 由于未采用填充模式,因此原文长度必须为 8 的倍数 // 3DES ciphertext = EK3(DK2(EK1(plaintext)))
byte[] crypt = encrypt(decrypt(encrypt(data, key1), key2), key3); // 3DES plaintext = DK1(EK2(DK3(ciphertext)))
byte[] plain = decrypt(encrypt(decrypt(crypt, key3), key2), key1); System.out.println(" key: " + ByteUtil.bytes2HexSpace(key1) + " "
+ ByteUtil.bytes2HexSpace(key2) + " "
+ ByteUtil.bytes2HexSpace(key3));
System.out.println(" data: " + ByteUtil.bytes2HexSpace(data));
System.out.println("crypt: " + ByteUtil.bytes2HexSpace(crypt));
System.out.println("plain: " + ByteUtil.bytes2HexSpace(plain));
} public static byte[] decrypt(byte[] crypt, byte[] key) throws Exception {
Key k = toKey(key);
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, k);
return cipher.doFinal(crypt);
} public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
Key k = toKey(key);
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, k);
return cipher.doFinal(data);
} public static SecretKey toKey(byte[] key) throws Exception {
KeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
return keyFactory.generateSecret(dks);
}
}class ByteUtil { private static final char HEX[] = "0123456789abcdef".toCharArray(); public static String bytes2HexSpace(byte bys[]) {
char chs[] = new char[(bys.length * 2 + bys.length) - 1];
int i = 0;
int offset = 0;
for (; i < bys.length; i++) {
if (i > 0)
chs[offset++] = ' ';
chs[offset++] = HEX[bys[i] >> 4 & 15];
chs[offset++] = HEX[bys[i] & 15];
}
return new String(chs);
}
}上面 DES 的加密模式采用 ECB,填充方式为不进行填充。实际上 JCE 提供了 3DES 的加密算法,算法名为 DESede,并不需要自己通过 DES 去实现 3DES。只要把上面加密算法中有关 DES 改为 DESede,toKey 方法那个 KeySpec 的引用类由 DESKeySpec 改为 DESedeKeySpec 就可以了。
import java.security.spec.KeySpec;import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;public class BcTest { // 3DES key = 00 01 02 03 04 05 06 07 01 02 03 04 05 06 07 08 02 03 04 05 06 07 08 09
// data ("01234567") = 30 31 32 33 34 35 36 37
// 3des cipher = 5a b3 fd 7b 2a ca b2 95
// cipher mode = DESede/ECB/NoPadding
public static void main(String[] args) throws Exception { byte[] key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9
};
byte[] data = "01234567".getBytes(); byte[] crypt = encrypt(data, key); // 3DES 加密 byte[] plain = decrypt(crypt, key); // 3DES 解密 System.out.println(" key: " + ByteUtil.bytes2HexSpace(key));
System.out.println(" data: " + ByteUtil.bytes2HexSpace(data));
System.out.println("crypt: " + ByteUtil.bytes2HexSpace(crypt));
System.out.println("plain: " + ByteUtil.bytes2HexSpace(plain));
} public static byte[] decrypt(byte[] crypt, byte[] key) throws Exception {
Key k = toKey(key);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, k);
return cipher.doFinal(crypt);
} public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
Key k = toKey(key);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, k);
return cipher.doFinal(data);
} public static SecretKey toKey(byte[] key) throws Exception {
KeySpec dks = new DESedeKeySpec(key); // 这里改为了 DESedeKeySpec
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
return keyFactory.generateSecret(dks);
}
}