使用Java中的DES实现返回的密文不正确

时间:2015-03-01 22:27:30

标签: java des

对于小型作业,我已经获得了实现DES算法而不使用Java中已有的预定义函数。我得到了它的工作,但返回的加密文本不正确。当它应该是AA 39 B9 77 7E FC 3C时,它返回6C 17 96 35 BE 47 EF 95 14.我出错的任何想法?

后续; 3月8日

根据David Koontz的建议使用this manual他将我联系到了。我相信加密开始在子密钥生成周围出错。

后续; 3月8日晚些时候

在烦恼并审查我的代码的每一步后,我发现了问题。在我的一个for循环中,我使用了int j = 0; I< 16; i ++而不是使用j。愚蠢的错误,但没有人发现它哦。已在发布的代码中进行了更正。

package des.implementation;
import java.nio.ByteBuffer;
public class DESImplementation {    
    private static final byte[] IP = { 
        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
    };
    private static final byte[] FP = {
        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
    };
    private static final byte[] E = {
        32, 1,  2,  3,  4,  5,
        4,  5,  6,  7,  8,  9,
        8,  9,  10, 11, 12, 13,
        12, 13, 14, 15, 16, 17,
        16, 17, 18, 19, 20, 21,
        20, 21, 22, 23, 24, 25,
        24, 25, 26, 27, 28, 29,
        28, 29, 30, 31, 32, 1
    };
    private static final byte[][] S = { {
        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
    }, {
        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
    }, {
        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
    }, {
        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
    }, {
        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
    }, {
        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
    }, {
        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
    }, {
        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
    } };
    private static final byte[] P = {
        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
    };
    private static final byte[] PC1 = {
        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
    };
    private static final byte[] PC2 = {
        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
    };
    private static final byte[] rotations = {
        1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
    };
    private static int charToNibble(char c) {
        if (c>='0' && c<='9') {
            return (c-'0');
        } else if (c>='a' && c<='f') {
            return (10+c-'a');
        } else if (c>='A' && c<='F') {
            return (10+c-'A');
        } else {
            return 0;
        }
    }
    private static byte[] parseBytes(String s) {
        s = s.replace(" ", "");
        byte[] ba = new byte[s.length()/2];
        if (s.length()%2 > 0) { s = s+'0'; }
        for (int i=0; i<s.length(); i+=2) {
            ba[i/2] = (byte) (charToNibble(s.charAt(i))<<4 | charToNibble(s.charAt(i+1)));
        }
        return ba;
    }
    private static long permute(byte[] table, int srcWidth, long src) {
        long dst = 0;
        for (int i=0; i<table.length; i++) {
            int srcPos = srcWidth - table[i];
            dst = (dst<<1) | (src>>>srcPos & 0x01);
        }
        return dst;
    }
    private static byte[] longToBytes(long x) {
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
        buffer.putLong(x);
        return buffer.array();
    }   
    private static byte S(int boxNumber, byte src) {
        src = (byte) (src&0x20 | ((src&0x01)<<4) | ((src&0x1E)>>>1));
        return S[boxNumber-1][src];
    }
    private static int  P(int src)    { return (int)permute(P, 32, src&0xFFFFFFFFL); }
    private static int feistel(int r, long subkey) {
        long e = permute(E, 32, r&0xFFFFFFFFL);
        long x = e ^ subkey;
        int dst = 0;
        for (int i=0; i<8; i++) {
            dst>>>=4;
            int s = S(8-i, (byte)(x&0x3F));
            dst |= s << 28;
            x>>>=6;
        }
        return P(dst);
    }
    private static long bytesToLong(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
        buffer.put(bytes);
        buffer.flip();
        return buffer.getLong();
    }
    public static void main(String[] args) {
        byte[] message = parseBytes("0123456789ABCDEF");
        byte[] key = parseBytes("3b3898371520f75e");
            byte[] ciphertext = new byte[message.length];
            for(int i=0; i<message.length; i+=8){
                long Lmessage = bytesToLong(message);
                long Lkey = bytesToLong(key);
                        long subkeys[] = new long[16];
                        Lkey = permute(PC1, 64, Lkey);
                        int c = (int) (Lkey>>>28);
                        int d = (int) (Lkey&0x0FFFFFFF);
                        for (int j=0; j<16; j++) {    //the problem was found here
                            if (rotations[j] == 1) {
                                c = ((c<<1) & 0x0FFFFFFF) | (c>>>27);
                                d = ((d<<1) & 0x0FFFFFFF) | (d>>>27);
                            } else {
                                c = ((c<<2) & 0x0FFFFFFF) | (c>>>26);
                                d = ((d<<2) & 0x0FFFFFFF) | (d>>>26);
                            }
                            long cd = (c&0xFFFFFFFFL)<<28 | (d&0xFFFFFFFFL);
                            subkeys[j] = permute(PC2, 56, cd);
                        }                     
                    long ip = permute(IP, 64, Lmessage);
                    int l = (int) (ip>>>32);
                    int r = (int) (ip&0xFFFFFFFFL);                       
                    for (int k=0; k<16; k++) {
                        int previous_l = l;
                        l = r;
                        r = previous_l^feistel(r, subkeys[k]);
                    }
                    long rl = (r&0xFFFFFFFFL)<<32 | (l&0xFFFFFFFFL);
                    long fp =  permute(FP, 64, rl);
                    ciphertext = longToBytes(fp);
            }
        StringBuilder Message = new StringBuilder();
        StringBuilder Key = new StringBuilder();
        StringBuilder Cipher = new StringBuilder();
        for (int i=0; i<ciphertext.length; i++) {
            Message.append(String.format("%02X ",message[i]));
            Key.append(String.format("%02X ",key[i]));
            Cipher.append(String.format("%02X ",ciphertext[i]));
        }
        System.out.println("Message: "+Message.toString());
        System.out.println("Key: "+Key.toString());
        System.out.println("Cipher: "+Cipher.toString());
    }

}

1 个答案:

答案 0 :(得分:1)

在烦恼并审查我的代码的每一步后,我发现了问题。在我的一个for循环中,我使用了int j = 0; I&LT; 16; i ++而不是使用j。愚蠢的错误,但没有人发现它哦。已在发布的代码中进行了更正。