我有一个服务器和客户端套接字程序,服务器向客户端发送加密消息,即服务器端代码:
cipher2 = Cipher.getInstance("AES");
secretKeySpec = new SecretKeySpec(decryptedText, "AES");
cipher2.init(Cipher.ENCRYPT_MODE, secretKeySpec);
feedback = "Your answer is wrong".getBytes();
cipher2.doFinal(feedback);
dos.writeInt(feedback.length);
dos.write(feedback);
Run Code Online (Sandbox Code Playgroud)
客户端代码:
int result_len = 0;
result_len = din.readInt();
byte[] result_Bytes = new byte[result_len];
din.readFully(result_Bytes);
cipher2 = Cipher.getInstance("AES");
cipher2.init(Cipher.DECRYPT_MODE, aesKey);
byte[] encrypt = cipher2.doFinal(result_Bytes);
Run Code Online (Sandbox Code Playgroud)
抛出异常 byte[] encrypt = cipher2.doFinal(result_Bytes);
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
Run Code Online (Sandbox Code Playgroud)
问题是什么?
Ani*_*rni 17
这是一个非常古老的问题,但我的回答可能会对某人有所帮助。
下面是工作代码
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionDecryptionUtil {
public static String encrypt(final String secret, final String data) {
byte[] decodedKey = Base64.getDecoder().decode(secret);
try {
Cipher cipher = Cipher.getInstance("AES");
// rebuild key using SecretKeySpec
SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
cipher.init(Cipher.ENCRYPT_MODE, originalKey);
byte[] cipherText = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(cipherText);
} catch (Exception e) {
throw new RuntimeException(
"Error occured while encrypting data", e);
}
}
public static String decrypt(final String secret,
final String encryptedString) {
byte[] decodedKey = Base64.getDecoder().decode(secret);
try {
Cipher cipher = Cipher.getInstance("AES");
// rebuild key using SecretKeySpec
SecretKey originalKey = new SecretKeySpec(Arrays.copyOf(decodedKey, 16), "AES");
cipher.init(Cipher.DECRYPT_MODE, originalKey);
byte[] cipherText = cipher.doFinal(Base64.getDecoder().decode(encryptedString));
return new String(cipherText);
} catch (Exception e) {
throw new RuntimeException(
"Error occured while decrypting data", e);
}
}
public static void main(String[] args) {
String data = "This is not easy as you think";
String key = "---------------------------------";
String encrypted = encrypt(key, data);
System.out.println(encrypted);
System.out.println(decrypt(key, encrypted));
}
}
Run Code Online (Sandbox Code Playgroud)
对于生成密钥,您可以使用以下类
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class SecretKeyGenerator {
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
int keyBitSize = 256;
keyGenerator.init(keyBitSize, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
System.out.println(Base64.getEncoder().encodeToString(secretKey.getEncoded()));
}
}
Run Code Online (Sandbox Code Playgroud)
有一个类似的问题.但重要的是要了解根本原因,并且可能因不同的用例而异.
方案1
您试图解密首先未正确编码的值.
byte[] encryptedBytes = Base64.decodeBase64(encryptedBase64String);
Run Code Online (Sandbox Code Playgroud)
如果String由于某种原因配置错误或者编码不正确,您会看到错误"使用填充密码解密时输入长度必须是16的倍数"
场景2
现在,如果你在url中使用这个编码的字符串(试图在url中传入base64Encoded值,它将失败.你应该做URLEncoding,然后传入令牌,它将工作.
场景3
当与其中一个供应商集成时,我们发现我们必须使用URLEncoder对Base64进行加密,但我们不需要解码它,因为它是由供应商内部完成的
| 归档时间: |
|
| 查看次数: |
100158 次 |
| 最近记录: |