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] 万分感谢.................

解决方案 »

  1.   

    import java.security.Key;
    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 就可以了。
      

  2.   

    下面的代码是采用 SunJCE 内置的 3DES 算法写的,加密后的结果与上面那个一致。import java.security.Key;
    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);
        }
    }
      

  3.   

    根据 3DES 的定义,如果 24 个字节长的密钥分为 3 个 8 字节长的子密钥,如果这 3 个子密钥是相同的话,那么这个密钥的 3DES 与 DES 是一致。
      

  4.   

    诸位高手有做过c语言的3des加密,然后用java的3des解密没?