gpt4 book ai didi

java - 不断收到 javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher

转载 作者:太空宇宙 更新时间:2023-11-04 09:04:24 25 4
gpt4 key购买 nike

在套接字之间用 java 编写 AES-192 算法时,我不断收到该异常,但不知道如何修复它。我认为这一定与我在其他帖子中读到的服务器解码方式有关,但我无法正确理解。我的java版本是13以防万一需要。感谢您的帮助。

*注意:有些已实现的库可能无法使用,来自之前的尝试使其正常工作

服务器代码

import java.net.*; 
import java.io.*;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class Bob {
private Socket socket = null;
private ServerSocket bob = null;
private DataInputStream in = null;

public Bob(int port) {
try {
bob = new ServerSocket(port);

socket = bob.accept();

in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

String ciphertext = "";

while(!ciphertext.equals("Stop")){
try{
ciphertext = in.readUTF();
System.out.println("Received ciphertext: " + ciphertext);
String plaintext = decrypt(ciphertext);
System.out.println("Decrypted plaintext: " + plaintext + "\n");

}catch(Exception e){
System.out.println(e);
}

}

socket.close();
in.close();
}
catch(IOException i)
{
System.out.println(i);

}
}

public static String decrypt(String encrypted) {
try {

int ivSize = 16;
int keySize = 24;

String key = "i5q5jZFd73kuK3wG2jTCvtWp";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

byte[] encryptedIvTextBytes = encrypted.getBytes();

byte[] iv = new byte[ivSize];
System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

int ciphertextLength = encryptedIvTextBytes.length - ivSize;

byte[] ciphertextB = new byte[ciphertextLength];
System.arraycopy(encryptedIvTextBytes,ivSize,ciphertextB,0,ciphertextLength);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);

byte[] original = cipher.doFinal(Base64.getDecoder().decode(ciphertextB));

eturn new String(original);
} catch (Exception e) {
System.out.println(e);
}
return null;
}


public static void main(String args[]) {
Bob bob = new Bob(3125);
}
}

客户端代码

import java.net.*; 
import java.io.*;
import javax.crypto.*;
import java.security.*;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;



public class Alice {
private Socket socket = null;
private DataOutputStream out = null;
private BufferedReader in = null;


public Alice(String address, int port) {
try {
socket = new Socket(address, port);
in = new BufferedReader(new InputStreamReader(System.in));

out = new DataOutputStream(socket.getOutputStream());
} catch(UnknownHostException u) {
System.out.println(u);
} catch(IOException i) {
System.out.println(i);
}
String plaintext = "";

while(!plaintext.equals("Stop")){
try {
System.out.println("Introduce plaintext:");
plaintext = in.readLine();

String ciphertext = encrypt(plaintext);

System.out.println("Encrypted: " + ciphertext + "\n");
out.writeUTF(ciphertext);
} catch(IOException i) {
System.out.println(i);
}
}

try {
socket.close();
in.close();
out.close();
} catch(IOException i) {
System.out.println(i);
}
}


public static String encrypt(String value) {
try {
String key = "i5q5jZFd73kuK3wG2jTCvtWp";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

int ivSize = 16;
byte[] iv = new byte[ivSize];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

byte[] encrypted = cipher.doFinal(value.getBytes());

byte[] encryptedAndIV = new byte[ivSize + encrypted.length];
System.arraycopy(iv, 0, encryptedAndIV, 0, ivSize);
System.arraycopy(encrypted, 0, encryptedAndIV, ivSize, encrypted.length);

return new String(Base64.getEncoder().encode(encryptedAndIV));
} catch (Exception e) {
throw new RuntimeException("Error occured while encrypting data", e);
}
}


public static void main(String args[]) {
Alice alice = new Alice("localhost", 3125);
}
}

最佳答案

您的问题出在解密例程中。通常,在 CBC 中您必须遵循

加密;

  • 加密消息并返回字节
  • 使用 size=IV.lenght+encrypted.lenght 将 IV 添加到更大的字节数组中
  • 通过复制 IV||encrypted 将加密字节附加到更大的字节中
  • 将字节编码为 base64(或类似的)base64(IV||加密)
  • 发送消息

解密;

  • 获取消息
  • 将消息从 Base64 解码为字节
  • 从字节开头提取 IV
  • 从字节中提取加密字节
  • 加密字节以获取消息

在您的代码中,您没有在解密之前对字节进行解码以提取 IV,而是在解密过程中进行了解码。

ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));

//get the IV from the bytes
byte[] iv = new byte[ivSize];
buffer.get(iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

//get the encrypted bytes
byte[] encryptedTextBytes = new byte[buffer.capacity() - iv.length];
buffer.get(encryptedTextBytes);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);

byte[] original = cipher.doFinal(encryptedTextBytes);

关于java - 不断收到 javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60405749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com