Java/Android:SealedObject 抛出 StreamCorruptedException

Java/Android: SealedObject throws StreamCorruptedException

我想加密和解密之前使用生成的 AES 密钥在 SealedObject 中加密的对象,该密钥也在 SealedObject 中保存和加密,但使用 RSA。

代码

Stack 是我的项目库和 Serializable 的一部分。每个名为 xxxStack 的对象都是 Stack 的子类。

摘自chat.protocol.secure.CryptoStack

相关属性

// encrypted Object
private SealedObject stack;
// cache for the Object
private transient Stack stackCache;

// encrypted AES key
private SealedObject key;
// cache for AES key which is used to encrypt and decrypt the Object
private transient SecretKey keyCache;

使用唯一的 AES 密钥加密缓存对象 (stackCache) 然后使用 public RSA 密钥加密并保存在堆栈中的方法

public void encrypt(Cipher c0) throws IllegalBlockSizeException, IOException{
    /*
     * Creates unique AES key for encrypting the Object
     */
    KeyGenerator keyGen = null;
    try {
        keyGen = KeyGenerator.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    keyGen.init(256);
    keyCache = keyGen.generateKey();

    /*
     * Creating AES Cipher for encryption
     */
    Cipher c1 = null;
    try {
        c1 = Cipher.getInstance("AES");
        c1.init(Cipher.ENCRYPT_MODE, keyCache);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    /*
     * Encrypts Object
     */
    stack = new SealedObject(stackCache, c1);
    /*
     * Encrypts AES key with a Cipher given as argument (intended to be a public RSA key initialized Cipher)
     */
    key = new SealedObject(keyCache, c0);
}

解密加密的AES密钥以解密保存的对象的方法。参数 c 旨在成为 RSA 私钥初始化密码。

public void decrypt(Cipher c) throws ClassNotFoundException, IllegalBlockSizeException, BadPaddingException, IOException{

    //decrypting the AES key (CryptoStack.java:110)
    keyCache = (SecretKey) key.getObject(c);

    //generating Cipher for decryption
    Cipher c1 = null;
    try {
        c1 = Cipher.getInstance("AES");
        c1.init(Cipher.DECRYPT_MODE, keyCache);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //decrypting Object with previous generated Cipher
    stackCache = (Stack) stack.getObject(c1);
}

摘自chat.client.core.Client

相关属性

//Connection to the Server
private Socket socket;

//InputStream
private ObjectInputStream oin;

//Listener for incoming data
private IncomingStackListener l;

//HashMap for caching PublicKeys
private ConcurrentHashMap<String, PublicKey> publicKeyCache = new ConcurrentHashMap<String, PublicKey>();

等待正在解密并提供给侦听器的传入数据的线程。

public void run() {
    Stack stack = null;
    while (!isInterrupted()) {
        try {
            stack = (Stack) oin.readObject();

            /*Irrelevant code removed*/

            // Detect and decrypt encrypted data
            if (stack.getType().equals(StackType.ENCRYPTED)) {

                Cipher c = Cipher.getInstance("RSA");
                c.init(Cipher.DECRYPT_MODE, me.getPrivateKey());
                //following: Client.java:75
                ((CryptoStack) stack).decrypt(c);
                stack = ((CryptoStack) stack).getCache();

            }
        } catch (ClassNotFoundException | IOException
                | NoSuchAlgorithmException | NoSuchPaddingException
                | InvalidKeyException | IllegalBlockSizeException
                | BadPaddingException e) {
            e.printStackTrace();
        }
        l.onStackEntry(stack);
    }
}

问题

在标准 JVM 环境中一切正常。 但是在 Android 应用程序中使用此代码(它是我的项目库的一部分)对存储在 SealedObject 密钥中的唯一密钥的解密失败,并显示以下 LogCat 输出:

java.io.StreamCorruptedException
java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2070)
java.io.ObjectInputStream.<init>(ObjectInputStream.java:371)
javax.crypto.SealedObject.getObject(SealedObject.java:220)
chat.protocol.secure.CryptoStack.decrypt(CryptoStack.java:110)
chat.client.core.Client.run(Client.java:75)

如何使它在 Android 上也能正常工作?
如果需要解决方案,我准备提供更多代码

所以我终于弄清楚问题出在哪里了。 在 Android 和其他 "PC" 平台之间使用跨平台加密时,请确保指定算法、模式和填充(例如 "AES/CBC/PKCS5Padding"),因为仅指定算法(例如 "AES" ) 好像会引起误解。