有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中的位操作DES实现:密钥生成阶段出错

我是一名学生,正在做一个小型项目——DES实现。 我之前对将64位密钥转换为56位密钥有疑问,由于这里提供了一些指导,我可以成功地实现这一点

我将我的实现分为密钥生成阶段(16轮中的每一轮我都会生成一个新密钥)和加密阶段

但是,我无法生成正确的密钥。 我用“abcdefgh”作为键手工做了一个例子,但我无法在我的程序中重现结果

DES keygen阶段包括:

  1. 将56位密钥划分为2个28位密钥。我将4个字节中的28位存储为leftkey28[4](最后4位为0)&rightkey28[4](前4位为0)

  2. 这28位组使用(<;<;1<;<;<;2在原始算法中,然后组合得到一个新的56位密钥)进行左循环移位。然而,由于这个问题,我现在放弃了左移2,而只剩下左循环移动1。然而,这个问题的根源是无法追踪的

问题似乎出在我的输出中的Round#2 Byte#2

如果您能提供任何指导或提示,以找出根本原因,我将不胜感激。 ( 另外,我以前从来没有做过这么多的操作! 代码没有根据Java规则/约定进行优化或编写,因为我只是想在做任何其他事情之前让它工作 )

提前谢谢

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;

/**
 * @author krish 2nd Aug, 2011
 */

    class DES {

final static int KEY_LENGTH = 8; // 8 byte key, 64 bits
final static int BLOCK_SIZE = 8; // 8 byte blocks, 64 bits
final static int NUM_ROUNDS = 16; // 16 rounds per block

// =======================================================================
// FOR KEY TRANSFORMATION
int[] compressionPermutation = { 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 };

// int[] keyShiftValue = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
// ---
// don't need this
// =======================================================================

public static void main(String[] args) {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter an 8 char key: ");
    String inputKey, inputMsg;
    char[] inputArray;
    byte[] key64 = new byte[8];
    byte[] key56 = new byte[7];
    int counter;

    try {
        // get key, key length() >= 8 chars

        // inputKey = br.readLine();// uncomment later!!$$$$$$$
        inputKey = "abcdefgh";
        System.out.println(inputKey);
        if (inputKey.length() < 8) {
            System.out.println("Key < 8 B. Exiting. . .");
            System.exit(1);
        }
        // java char has 16 bits instead of 8 bits as in C,
        // so convert it to 8 bit char by getting lower order byte &
        // discarding higher order byte; &
        // consider only first 8 chars even if input > 8
        inputArray = inputKey.toCharArray();
        for (counter = 0; counter < 8; counter++)
            key64[counter] = (byte) inputArray[counter];

        // converting 64bit key to 56 bit key
        for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
            key64[counter] = (byte) (key64[counter] >>> 1);
            key64[counter] = (byte) (key64[counter] << 1);
        }
        for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
            key56[counter] = (byte) (key64[counter] << counter);
            key56[counter] = (byte) (key56[counter] | (key64[counter + 1] >>> (KEY_LENGTH - 1 - counter)));
        }
        /*
         * Conversion from 64 to 56 bit testing code
         * 
         * System.out.println("64 to 56 test:"); System.out.println(new
         * String(key56)); System.out.println(); for (int counter1 = 0;
         * counter1 < 7; counter1++) { for (int counter2 = 7; counter2 >= 0;
         * counter2--) { System.out.println(key56[counter1] & (1 <<
         * counter2)); } System.out.println(); }
         */

        // end of obtaining 56bit key

        // KEY GENERATION PHASE
        // DS USED - compressionPermutation

        byte[] leftKey28 = new byte[4];
        byte[] rightKey28 = new byte[4];
        byte circularBit;
        byte[][] newKey56 = new byte[16][7];

        // new 56 bit key for the first round, then loop for other rounds
        leftKey28[0] = key56[0];
        leftKey28[1] = key56[1];
        leftKey28[2] = key56[2];
        leftKey28[3] = (byte) (key56[3] & 11110000);

        // rightKey28[0] = (byte) (key56[3] & 00001111);
        // prob here, doesnt work as given above??
        rightKey28[0] = (byte) (key56[3] - leftKey28[3]);
        rightKey28[1] = key56[4];
        rightKey28[2] = key56[5];
        rightKey28[3] = key56[6];

        /*
         * // printing starts here System.out.print("1 Byte # 0" + "     ");
         * for (int counter2 = 7; counter2 >= 0; counter2--) {
         * System.out.print(leftKey28[0] & (1 << counter2));
         * System.out.print(", "); } System.out.println(); // printing ends
         * here
         */

        circularBit = (byte) (leftKey28[0] & (1 << 7));

        leftKey28[0] = (byte) (leftKey28[0] << 1);
        leftKey28[0] = (byte) (leftKey28[0] | ((((int) leftKey28[1]) & 0xff) >>> 7));

        leftKey28[1] = (byte) (leftKey28[1] << 1);
        leftKey28[1] = (byte) (leftKey28[1] | ((((int) leftKey28[2]) & 0xff) >>> 7));

        leftKey28[2] = (byte) (leftKey28[2] << 1);
        leftKey28[2] = (byte) (leftKey28[2] | ((((int) leftKey28[3]) & 0xff) >>> 7));

        leftKey28[3] = (byte) (leftKey28[3] << 1);
        leftKey28[3] = (byte) (leftKey28[3] | ((((int) circularBit) & 0xff) >>> 3));

        circularBit = (byte) (rightKey28[0] & (1 << 3));
        circularBit <<= 4;

        rightKey28[0] = (byte) (rightKey28[0] << 1);
        rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));

        rightKey28[1] = (byte) (rightKey28[1] << 1);
        rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));

        rightKey28[2] = (byte) (rightKey28[2] << 1);
        rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));

        rightKey28[3] = (byte) (rightKey28[3] << 1);
        rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 3));

        newKey56[0][0] = leftKey28[0];
        newKey56[0][1] = leftKey28[1];
        newKey56[0][2] = leftKey28[2];
        newKey56[0][3] = (byte) (leftKey28[3] | rightKey28[0]);
        newKey56[0][4] = rightKey28[1];
        newKey56[0][5] = rightKey28[2];
        newKey56[0][6] = rightKey28[3];
        // we have a new left circular shifted key in newKey56

        // done testing for newkey56[0] // left and right testing code
        for (int counter1 = 0; counter1 < 7; counter1++) {
            System.out.print("Round#0 Byte#" + counter1 + "  ");
            for (int counter2 = 7; counter2 >= 0; counter2--) {
                if (counter2 == 3)
                    System.out.print("   ");
                if ((newKey56[0][counter1] & (1 << counter2)) > 0) {
                    System.out.print("1");
                } else {
                    System.out.print("0");
                }
            }
            System.out.println();
        }
        // left and right testing code ends here

        // for round 1 to 15: left circular shift each 28 bit block by 1{
        for (int round = 1; round < NUM_ROUNDS; round++) {
            // for the first round, then loop for other rounds
            leftKey28[0] = newKey56[round - 1][0];
            leftKey28[1] = newKey56[round - 1][1];
            leftKey28[2] = newKey56[round - 1][2];
            leftKey28[3] = (byte) (newKey56[round - 1][3] & 11110000);

            // rightKey28[0] = (byte) (newKey56[round - 1][3] & 00001111);
            rightKey28[0] = (byte) (newKey56[round - 1][3] - leftKey28[3]);
            rightKey28[1] = newKey56[round - 1][4];
            rightKey28[2] = newKey56[round - 1][5];
            rightKey28[3] = newKey56[round - 1][6];

            // if (round == 1 || round == 8 || round == 15) {
            // left circular shift by 1
            circularBit = (byte) (leftKey28[0] & (1 << 7));

            leftKey28[0] <<= 1;
            leftKey28[0] |= ((((int) leftKey28[1]) & 0xff) >>> 7);

            leftKey28[1] <<= 1;
            leftKey28[1] |= ((((int) leftKey28[2]) & 0xff) >>> 7);

            // ////////////////////////error here ////////////////////////////
            leftKey28[2] <<= 1;
            leftKey28[2] |= ((((int) leftKey28[3]) & 0xff) >>> 7);
            // ////////////////////////error here //////////////////////////

            leftKey28[3] <<= 1;
            leftKey28[3] |= ((((int) circularBit) & 0xff) >>> 3);

            circularBit = (byte) (rightKey28[0] & (1 << 3));
            circularBit <<= 4;

            // //////////////////////////////////////////////////
            rightKey28[0] = (byte) (rightKey28[0] << 1);
            rightKey28[0] &= 00001111;
            rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));
            // //////////////////////////////////////////////////

            rightKey28[1] = (byte) (rightKey28[1] << 1);
            rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));

            rightKey28[2] = (byte) (rightKey28[2] << 1);
            rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));

            rightKey28[3] = (byte) (rightKey28[3] << 1);
            rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 7));
            // } else {
            // // left circular shift by 2
            // }

            newKey56[round][0] = leftKey28[0];
            newKey56[round][1] = leftKey28[1];
            newKey56[round][2] = leftKey28[2];
            newKey56[round][3] = (byte) (leftKey28[3] | rightKey28[0]);
            newKey56[round][4] = rightKey28[1];
            newKey56[round][5] = rightKey28[2];
            newKey56[round][6] = rightKey28[3];

            // testing code for all keys for rounds 1 to 15
            System.out.println();
            for (int counter1 = 0; counter1 < 7; counter1++) {
                System.out.print("Round#" + round + "  Byte#" + counter1
                        + "  ");
                for (int counter2 = 7; counter2 >= 0; counter2--) {
                    if (counter2 == 3)
                        System.out.print("   ");
                    if ((newKey56[round][counter1] & (1 << counter2)) > 0) {
                        System.out.print("1");
                    } else {
                        System.out.print("0");
                    }

                }
                System.out.println();
            }
            if (round == 2)
                break;
            // testing code ends

        }// for loop ends

        /*
         * // newKey56 testing code
         * System.out.println("new56key testing here"); for (counter = 0;
         * counter < NUM_ROUNDS; counter++) { System.out.println(new
         * String(newKey56[counter])); System.out.println();
         * 
         * for (int counter1 = 0; counter1 < 7; counter1++) {
         * System.out.print("Round # " + counter + " Byte # " + counter1 +
         * "     "); for (int counter2 = 7; counter2 >= 0; counter2--) {
         * System.out.print(newKey56[counter][counter1] & (1 << counter2));
         * System.out.print(", "); } System.out.println(); } }
         */

        // DO KEY COMPRESSION ROUTINE HERE

    } catch (Exception e) {
        e.printStackTrace();
    }
}
    }

    Enter an 8 char key: 
    abcdefgh
    Round#0 Byte#0  1100   0001
    Round#0 Byte#1  1000   1011
    Round#0 Byte#2  0001   0110
    Round#0 Byte#3  0100   1100
    Round#0 Byte#4  1001   1001
    Round#0 Byte#5  1011   0011
    Round#0 Byte#6  0110   1000

    Round#1  Byte#0  1000   0011
    Round#1  Byte#1  0001   0110
    Round#1  Byte#2  0010   1100
    Round#1  Byte#3  1001   1001
    Round#1  Byte#4  0011   0011
    Round#1  Byte#5  0110   0110
    Round#1  Byte#6  1101   0001

    Round#2  Byte#0  0000   0110
    Round#2  Byte#1  0010   1100
    Round#2  Byte#2  0101   1000 //error here => 0101 1001
    Round#2  Byte#3  0011   0000 //error here => 0011 0010
    Round#2  Byte#4  0110   0110
    Round#2  Byte#5  1100   1101
    Round#2  Byte#6  1010   0011

共 (0) 个答案