Java 逐块加密:从第二个块开始解密不起作用
我正在使用自动生成的密钥和自定义IV逐块实现CBC加密+解密。我在第二个块解密中遇到问题,第一个块的解密正在工作,但第二个块的解密不工作。这是我的密码Java 逐块加密:从第二个块开始解密不起作用,java,encryption,Java,Encryption,我正在使用自动生成的密钥和自定义IV逐块实现CBC加密+解密。我在第二个块解密中遇到问题,第一个块的解密正在工作,但第二个块的解密不工作。这是我的密码 public static void main(String args[]) { Cipher fcipher, scipher; String plaintextstring = ""; System.out.println("Enter the first message:"); BufferedReader
public static void main(String args[]) {
Cipher fcipher, scipher;
String plaintextstring = "";
System.out.println("Enter the first message:");
BufferedReader buffp = new BufferedReader(new InputStreamReader(System.in));
try {
plaintextstring = buffp.readLine();
} catch (Exception e) {
System.out.println("Exception occured:" + e.getMessage());
}
int strlen1 = plaintextstring.length();
int x1 = strlen1 % 8;
int y1 = 8 - x1;
StringBuffer buf1 = new StringBuffer(plaintextstring);
if (x1 > 0) {
for (int k = 0; k < y1; k++) {
buf1.append('0');
}
}
System.out.println("Modified plaintext is:" + buf1);
String inp = buf1.toString();
try {
SecretKey key1 = KeyGenerator.getInstance("DES").generateKey();
SecretKey key2 = KeyGenerator.getInstance("DES").generateKey();
fcipher = Cipher.getInstance("DES/ECB/NoPadding");//CBC
scipher = Cipher.getInstance("DES/ECB/NoPadding");//CBC
// Create an 8-byte initialization vector
//byte[] iv = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
//byte[] iv = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] iv = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
System.out.println("Length of IV is :" + iv.length);
byte[] sencrypted = new byte[8];
fcipher.init(Cipher.ENCRYPT_MODE, key1);
scipher.init(Cipher.DECRYPT_MODE, key2);
System.out.println("Default Charset is :" + Charset.defaultCharset());
byte[] pbytes = inp.getBytes("UTF-8");
System.out.println("Byte array of input string is :" + pbytes);
System.out.println("Size of first message in bytes is:" + pbytes.length);
for (int i = 0; i < pbytes.length; i++) {
System.out.println("Array values of byte array are: " + pbytes[i]);
}
int z = (pbytes.length) / 8;
System.out.println("Number of data blocks of 8 bytes formed from message = " + z);
for (int i = 0; i < z; i++) {
byte[] ds = getSection(pbytes, i * 8);//getting block of 64bit
byte[] out = new byte[8];
for (int r = 0; r < 8; r++) {
System.out.println("Array values of IV from previous stage is :" + iv[r]);
}
for (int k = 0; k < 8; k++) {
out[k] = (byte) (ds[k] ^ iv[k]);//XORing of message block with IV bit by bit.
// System.out.println("XORed array byte by byte is:"+out[k]);
}
byte[] fencrypted = fcipher.doFinal(out);//Applying DES Encryption to the XOR'ed result.(E)key1
byte[] fdecrypted = scipher.doFinal(fencrypted);// (D)key2
sencrypted = fcipher.doFinal(fdecrypted);// (E)key1
System.out.println("Encrypted byte length: " + sencrypted.length);
System.out.println("Encrypted text is :" + sencrypted);
fcipher.init(Cipher.DECRYPT_MODE, key1);
scipher.init(Cipher.ENCRYPT_MODE, key2);
byte[] sfdecrypted = fcipher.doFinal(sencrypted);//DES1 key1 (D)
byte[] sfencrypted = scipher.doFinal(sfdecrypted);//DES Key2 (E)
byte[] ssdecrypted = fcipher.doFinal(sfencrypted);//DES Key3 (D)
System.out.println("length of final decrypted byte array is :" + ssdecrypted.length);
byte[] d = new byte[8];
for (int u = 0; u < 8; u++) {
d[u] = (byte) (ssdecrypted[u] ^ iv[u]);//XORing of message block with IV bit by bit.
System.out.println("final decrypted array byte by byte of a single 64 bit block is:" + d[u]);
}
String sdecryptedstr = new String(d);
System.out.println("Decrypted block is :" + sdecryptedstr);
iv = sencrypted;
System.out.println("IV from previous stage is: "+iv);
}
} catch (Exception e) {
System.out.println("Exception Occured: " + e);
}
}
//function to get CBC message blocks.
public static byte[] getSection(byte[] message, int start) {
byte[] section = new byte[8];//dividing whole message into 64bit blocks.
for (int i = 0, j = start; i < 8; i++, j++) {
section[i] = message[j];
}
return section;
}//end of getSection function.
publicstaticvoidmain(字符串参数[]){
密码fcipher,scipher;
字符串明文字符串=”;
System.out.println(“输入第一条消息:”);
BufferedReader buffp=新的BufferedReader(新的InputStreamReader(System.in));
试一试{
plaintextstring=buff.readLine();
}捕获(例外e){
System.out.println(“发生异常:+e.getMessage());
}
int strlen1=plaintextstring.length();
int-x1=strlen1%8;
int y1=8-x1;
StringBuffer buf1=新的StringBuffer(明文字符串);
如果(x1>0){
对于(int k=0;k
此问题的常见原因是未能在加密输出中保留解密块边界,导致解密块与加密块不对齐。但我的第一个块正在正确解密,每次我检查块大小是否为8字节。如果要CBC模式加密,我认为,只要向Cipher.getInstance()询问CBC模式加密,您就可以省去很多麻烦。@NeilCoffey我认为我们可以放心地假设这是一项学习专业知识。源代码中有两件事情似乎不正确。首先,将密码文本作为字符串处理。除非经过特殊编码(例如base64或十六进制),否则密文永远不是字符串。其次,似乎每次运行时都会生成随机密钥。这可以而且永远不会起作用;您甚至不应该得到一个正确的解密块。