简体   繁体   English

序列化期间的构造函数调用

[英]Constructor call during serialization

I have a KeyChain class in my code, which allows me to store to disk and retrieve an encrypted list of credentials. 我的代码中有一个KeyChain类,它使我可以存储到磁盘并检索加密的凭据列表。

During the KeyChain 's construction, i initialize AES ciphers. KeyChain的构造过程中,我初始化了AES密码。

To serialize the object, i first serialize the credentials list into a buffer, then encrypt that buffer and put it into the original OutputObjectStream . 要序列化该对象,我首先将凭证列表序列化到一个缓冲区中,然后对该缓冲区进行加密并将其放入原始的OutputObjectStream

To deserialize it, i tried reading the ObjectInputStream into a buffer, decrypting it and deserializing my credentials from it, but to do that, i need to have the ciphers constructed in the first place. 为了反序列化,我尝试将ObjectInputStream读入缓冲区,解密并从中反序列化我的凭证,但是要做到这一点,我首先需要构造密码。 I can't do that since deserialization doesn't calls my constructor. 我不能这样做,因为反序列化不会调用我的构造函数。 How do i turn around this? 我该如何扭转呢?

KeyChain: 钥匙链:

private void readObject(ObjectInputStream is) throws IOException {
    byte[] buffer = new byte[512000];

    int readBytes = is.read(buffer);

    byte[] encryptedBytes = new byte[readBytes];
    System.arraycopy(buffer, 0, encryptedBytes, 0, readBytes);

    // Here it crashes and burns because i can't decrypt yet, the ciphers haven't been setup
    byte[] decryptedBytes = decryptBytes(encryptedBytes);

    ByteInputStream stream = new ByteInputStream(decryptedBytes, readBytes);
    ObjectInputStream unsafeInputStream = new ObjectInputStream(stream);
    try {
        Keys = (List<Key>)unsafeInputStream.readObject();
    } catch (ClassNotFoundException ex) {
        // Fail miserably
    }
}

private void writeObject(ObjectOutputStream os) throws IOException {
    ByteOutputStream streamBytes = new ByteOutputStream();
    ObjectOutputStream unsafeOutputStream = new ObjectOutputStream(streamBytes);

    unsafeOutputStream.writeObject(Keys);
    unsafeOutputStream.flush();

    byte[] decryptedBytes = streamBytes.getBytes();

    byte[] encryptedBytes = encryptBytes(decryptedBytes);

    os.write(encryptedBytes);
    os.flush();

    Arrays.fill(decryptedBytes, (byte)0);
    Arrays.fill(encryptedBytes, (byte)0);
}

gotcha: I can't just call initCryptograhy(char[] password) in readObject because i just don't have the password available there, i can't pass it as an argument, this is the root of the problem. initCryptograhy(char[] password) 我不能只在readObject中调用initCryptograhy(char[] password) ,因为我在那里没有可用的密码,我无法将其作为参数传递,这是问题的根源。

Java actually has a facility called SealedObject for encrypting a serialized instance. Java实际上有一个称为SealedObject的工具,用于加密序列化的实例。 Maybe this would work better for what you are trying to achieve. 也许这对于您要实现的目标会更好。 I think the key difference between what you are doing and what SealedObject does is that it does the decrypting in a second phase, not in the initial deserialization. 我认为您正在做的事情和SealedObject做的事情之间的主要区别在于,它在第二阶段而不是在最初的反序列化中进行解密。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM