有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    数据的最后一块必须小于等于64字节(可以包括0字节)。这是因为该算法在64字节块上工作,需要在最后一个块中适当地填充数据。如果剩下64个或更多字节,则不应执行最后一个块,而应将接下来的64个字节加密为非最终字节

    如果你不知道这一点,那说明你对加密研究得不多。我会考虑不要这样做,而是在SSL上隧道连接。即使是专家,加密也很容易出错。例如,您如何进行密钥交换?最好使用经过测试的库/解决方案,而不是自己使用任何东西