我有一个连接到服务器的android消息传递应用程序。应用和服务器通过"数据包"进行通信。这些数据包是通过hybrid encryption加密的反序列化对象。出于某种原因,我在尝试加密数据时遇到以下错误:
W/System.err: javax.crypto.IllegalBlockSizeException: input must be under 64 bytes
W/System.err: at com.android.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;
}
}
EncryptionOutputStream:
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;
}}
答案 0 :(得分:0)
数据的最后一块必须是64字节或更少(可包括0字节)。这是因为该算法适用于64字节块,并且需要在最后一个块中适当填充数据。如果剩下64个或更多字节,则不应该执行最后一个块,应该将接下来的64个字节加密为非最终字节。
如果你不知道,你还没有多少研究加密。我考虑不要这样做,而是通过SSL隧道连接。即使专家出错也很容易加密。例如,你是如何进行密钥交换的?最好使用经过测试的库/解决方案而不是自己滚动任何东西。