java如何修复javax。加密。IllegalBlockSizeException:在安卓中输入必须小于64字节?
我有一个连接到服务器的安卓消息应用程序。应用程序和服务器通过“数据包”进行通信。这些数据包是通过hybrid encryption加密的反序列化对象。由于某些原因,我在尝试加密数据时出现以下错误:
W/System.err: javax.crypto.IllegalBlockSizeException: input must be under 64 bytes
W/System.err: at com.安卓.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:245)
W/System.err: at javax.crypto.Cipher.doFinal(Cipher.java:1204)
W/System.err: at javax.crypto.SealedObject.<init>(SealedObject.java:103)
W/System.err: at com.baiocchi.enigma.client.util.encryption.EncryptionOutputStream.writeObject(EncryptionOutputStream.java:35)
W/System.err: at com.baiocchi.enigma.client.util.CredentialInflator.deflateCredentials(CredentialInflator.java:31)
W/System.err: at com.baiocchi.enigma.shared.packet.Packet.encryptCredentials(Packet.java:55)
W/System.err: at com.baiocchi.enigma.client.util.handlers.PacketDeflationHandler.run(PacketDeflationHandler.java:34)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:841)
我没有主意,在网上找不到答案。请帮忙! 以下是使用的方法:
加密机:
public class Encryptor {
public static byte[] encrypt(byte[] data, RSAKey asymmetricKey) {
if (asymmetricKey instanceof RSAPublicKey) {
return encrypt(data, (RSAPublicKey) asymmetricKey);
}
return encrypt(data, (RSAPrivateKey) asymmetricKey);
}
private static byte[] encrypt(byte[] data, RSAPublicKey asymmetricKey) {
try {
final Cipher cipher = Cipher.getInstance(Config.ASYMMETRIC_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, asymmetricKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] encrypt(byte[] data, RSAPrivateKey asymmetricKey) {
try {
final Cipher cipher = Cipher.getInstance(Config.ASYMMETRIC_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, asymmetricKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
加密输出流:
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SealedObject;
import javax.crypto.spec.IvParameterSpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class EncryptionOutputStream extends ByteArrayOutputStream {
private final Cipher cipher;
public EncryptionOutputStream(SymmetricEncryptionKey symmetricEncryptionKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
super();
cipher = Cipher.getInstance(Config.SYMMETRIC_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, symmetricEncryptionKey.getKey(), new IvParameterSpec(symmetricEncryptionKey.getIvParameter()));
}
public void writeObject(Serializable object) throws IOException {
try {
final SealedObject sealedObject = new SealedObject(object, cipher);
final ObjectOutputStream outputStream = new ObjectOutputStream(this);
outputStream.writeObject(sealedObject);
} catch (final IllegalBlockSizeException e) {
e.printStackTrace();
}
}
}
数据包加密方法:
public final void encryptCredentials(RSAKey asymmetricKey) throws IOException {
if (credentials != null) {
SymmetricEncryptionKey symmetricEncryptionKey = EncryptionKeyGenerator.createNewSymmetricKey().getSymmetricEncryptionKey();
encryptedCredentials = CredentialInflator.deflateCredentials(symmetricEncryptionKey, credentials);
credentials = null;
encryptedKey = Encryptor.encrypt(symmetricEncryptionKey.getKey().getEncoded(), asymmetricKey);
encryptedIvParameter = Encryptor.encrypt(symmetricEncryptionKey.getIvParameter(), asymmetricKey);
}
}
凭据加密方法:
public static byte[] deflateCredentials(SymmetricEncryptionKey key, Credentials credentials) throws IOException {
try (EncryptionOutputStream outStream = new EncryptionOutputStream(key)) {
outStream.writeObject(credentials);
return outStream.toByteArray();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return null;
}
SymmetricEncryptionKey类:
import javax.crypto.SecretKey;
public class SymmetricEncryptionKey {
private final SecretKey key;
private byte[] ivParameter = new byte[16];
public SymmetricEncryptionKey(SecretKey key, byte[] ivParameter) {
this.key = key;
this.ivParameter = ivParameter;
}
public SecretKey getKey() {
return key;
}
public byte[] getIvParameter() {
return ivParameter;
}}
# 1 楼答案
数据的最后一块必须小于等于64字节(可以包括0字节)。这是因为该算法在64字节块上工作,需要在最后一个块中适当地填充数据。如果剩下64个或更多字节,则不应执行最后一个块,而应将接下来的64个字节加密为非最终字节
如果你不知道这一点,那说明你对加密研究得不多。我会考虑不要这样做,而是在SSL上隧道连接。即使是专家,加密也很容易出错。例如,您如何进行密钥交换?最好使用经过测试的库/解决方案,而不是自己使用任何东西