Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Feistel密码在Java中的小型实现_Java_Cryptography_Feistel Cipher - Fatal编程技术网

Feistel密码在Java中的小型实现

Feistel密码在Java中的小型实现,java,cryptography,feistel-cipher,Java,Cryptography,Feistel Cipher,我正在尝试一个Feistel密码的小实现。这就是我一直在尝试的: int[] left = {1,2,3};//left half of plaintext int[] right = {4,5,6};//right half of plaintext int temp[];//temp for swapping values //encrypt the plaintext (left and right arrays) for(int r = 0; r < 3; r++) {//the

我正在尝试一个Feistel密码的小实现。这就是我一直在尝试的:

int[] left = {1,2,3};//left half of plaintext
int[] right = {4,5,6};//right half of plaintext
int temp[];//temp for swapping values

//encrypt the plaintext (left and right arrays)
for(int r = 0; r < 3; r++) {//the number of rounds
    for(int i = 0; i < right.length; i++){
        right[i] = left[i] ^ (scramble(right[i], KEY, r));
    }
    temp = left;
    left = right;
    right = temp;
}

//swap left and right array before decryption
temp = left;
left = right;
right = temp;
for(int r = 3; r > 0; r--) {//start from the last round
    for(int i = 0; i < right.length; i++) {
        right[i] = left[i] ^ (scramble(right[i], KEY, r));
    }

    //again, swap arrays to do the next round
    temp = left;
    left = right;
    right = temp;
}
我试图先对明文的左右两半进行加密,然后在解密过程中运行它-因此到最后,数组的值应该是[1,2,3]和[4,5,6](返回到明文)。使用8的密钥输入,解密后得到[15,13,0]和[8,12,1]的值。这件事我哪里做错了

为了简单起见,我现在只使用一个常量作为键以及整数的输入,而不是从文件中读取/使用字节数组

编辑:

循环计数不正确。将“加密循环”更改为:

for(int r=1;r<4;r++){//轮数
for(int i=0;i

循环现在计数第1,2,3轮(加密)和第3,2,1轮(解密)。但是,解密仍然不能产生正确的明文。

您的整数计数器不是对称的

for(int r = 0; r < 3; r++)

计数:3、2、1。

Feistel的工作原理是将右侧的函数应用到左侧,即左=左^F(右),然后交换。这相当于right2=left1^F(right1),left2=right1,但该公式在具有并行或解构赋值的语言中工作得更好,而Java没有。请参见第页的图片。此外,您的代码组织在解密结束时进行了一次过多的交换。解决这两个问题:

static void SO40331050Feistel (){ 
    final int KEY = 8;
    int[] left = {1,2,3}, right = {4,5,6}, temp;
    System.out.println ("=====WRONG=====");
    for(int r = 1; r <= 3; r++) {
        for(int i = 0; i < right.length; i++){
            right[i] = left[i] ^ (scramble(right[i], KEY, r));
        }
        System.out.println ("ENC"+r +" "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp;
    }
    temp = left; left = right; right = temp; // swap before decrypt
    for(int r = 3; r >= 1; r--) {
        for(int i = 0; i < right.length; i++) {
            right[i] = left[i] ^ (scramble(right[i], KEY, r));
        }
        System.out.println ("DEC"+r + " "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp;
    }
    left = new int[]{1,2,3}; right = new int[]{4,5,6}; // reset
    System.out.println ("=====RIGHT=====");
    for(int r = 1; r <= 3; r++) {
        for(int i = 0; i < right.length; i++){
            left[i] ^= (scramble(right[i], KEY, r));
        }
        System.out.println ("ENC"+r +" "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp; // swap after
    }
    for(int r = 3; r >= 1; r--) {
        temp = left; left = right; right = temp; // swap before on decrypt
        for(int i = 0; i < right.length; i++) {
            left[i] ^= (scramble(right[i], KEY, r));
        }
        System.out.println ("DEC"+r + " "+Arrays.toString(left) +" "+Arrays.toString(right));
    }
}

同样,F通常使用整个右半部,并产生适用于整个左半部的结果;通过在32位int段上分别执行此操作,实际上可以在ECB模式下并行运行三个独立的32位分组密码。如果这是一个真正的密码,则32位块和ECB都将是严重的弱点。

有时,如果将它们精简到最小,则更容易看到。此伪码最小Feistel密码可能有助于:

function FeistelEncipher(plaintextBlock)

  left <- left hand half of plaintextBlock
  right <- right hand half of plaintextBlock

  // Note the half-open interval.
  for (roundNumber in [0 .. number of rounds[)

    if (roundNumber != 0)
      swap(left, right)
    end if

    right <- right XOR F(left, roundNumber)

  end for

  // Return ciphertext block.
  return join(left, right)

end function


function F(data, roundNumber)

  return some combination of the data and the round key for this round

end function
函数加密(明文块)
左边
for(int r = 3; r > 0; r--)
static void SO40331050Feistel (){ 
    final int KEY = 8;
    int[] left = {1,2,3}, right = {4,5,6}, temp;
    System.out.println ("=====WRONG=====");
    for(int r = 1; r <= 3; r++) {
        for(int i = 0; i < right.length; i++){
            right[i] = left[i] ^ (scramble(right[i], KEY, r));
        }
        System.out.println ("ENC"+r +" "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp;
    }
    temp = left; left = right; right = temp; // swap before decrypt
    for(int r = 3; r >= 1; r--) {
        for(int i = 0; i < right.length; i++) {
            right[i] = left[i] ^ (scramble(right[i], KEY, r));
        }
        System.out.println ("DEC"+r + " "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp;
    }
    left = new int[]{1,2,3}; right = new int[]{4,5,6}; // reset
    System.out.println ("=====RIGHT=====");
    for(int r = 1; r <= 3; r++) {
        for(int i = 0; i < right.length; i++){
            left[i] ^= (scramble(right[i], KEY, r));
        }
        System.out.println ("ENC"+r +" "+Arrays.toString(left) +" "+Arrays.toString(right));
        temp = left; left = right; right = temp; // swap after
    }
    for(int r = 3; r >= 1; r--) {
        temp = left; left = right; right = temp; // swap before on decrypt
        for(int i = 0; i < right.length; i++) {
            left[i] ^= (scramble(right[i], KEY, r));
        }
        System.out.println ("DEC"+r + " "+Arrays.toString(left) +" "+Arrays.toString(right));
    }
}
=====WRONG=====
ENC1 [1, 2, 3] [0, 3, 2]
ENC2 [0, 3, 2] [2, 7, 10]
ENC3 [2, 7, 10] [3, 11, 3]
DEC3 [2, 7, 10] [14, 0, 6]
DEC2 [14, 0, 6] [10, 7, 1]
DEC1 [10, 7, 1] [13, 6, 0]
=====RIGHT=====
ENC1 [0, 3, 2] [4, 5, 6]
ENC2 [5, 13, 2] [0, 3, 2]
ENC3 [3, 4, 11] [5, 13, 2]
DEC3 [0, 3, 2] [5, 13, 2]
DEC2 [4, 5, 6] [0, 3, 2]
DEC1 [1, 2, 3] [4, 5, 6]
function FeistelEncipher(plaintextBlock)

  left <- left hand half of plaintextBlock
  right <- right hand half of plaintextBlock

  // Note the half-open interval.
  for (roundNumber in [0 .. number of rounds[)

    if (roundNumber != 0)
      swap(left, right)
    end if

    right <- right XOR F(left, roundNumber)

  end for

  // Return ciphertext block.
  return join(left, right)

end function


function F(data, roundNumber)

  return some combination of the data and the round key for this round

end function