In matlab it is possible to write matlab objects, or even the entire workspace, to a file using the matlab save() call. I would like to intercept the bytestream and postproc
Your best bet is probably to write the mat file to a tmpfs/ramdisk and then encrypt it before saving it to disk. You sacrifice portability and rely on the OS to provide secure virtual memory, but if you can't even trust the local disk, you're probably not going to be able to achieve satisfactory security.
By the way, why exactly are you unable to trust the local disk at all, even to the extent that you can't put your temporary file in a directory with permissions set to only allow access for the user owning the matlab process (and root)? Are you trying to implement a DRM system?
Maybe you could do something like the following:
%# serialize objects into a byte array using Java
bout = java.io.ByteArrayOutputStream();
out = java.io.ObjectOutputStream(bout);
out.writeObject( rand(3) ) %# MATLAB matrix
out.writeObject( num2cell(rand(3)) ) %# MATLAB cell array
out.flush()
out.close()
bout.close()
b = bout.toByteArray(); %# vector of type int8
%# perform processing on `b` ...
%# write byte[] stream to file
save file.mat b
Then in the opposite direction, you simply load the saved MAT-file, reverse whatever processing you performed, and deserialize the stream of bytes to recvover the original objects.
%# load MAT-file
load file.mat b
b = typecast(b,'int8'); %# cast as int8 just to be sure
%# undo any processing on `b`...
%# deserialize
in = java.io.ObjectInputStream( java.io.ByteArrayInputStream(b) );
X1 = double( in.readObject() ) %# recover matrix
X2 = cell( in.readObject() ) %# recover cell array
in.close()
Note that you would have to maintain variables meta-information on your own, such as their number and type (maybe you can save it inside the same MAT-file somehow), and use custom wrapper functions to take care of all marshaling, but you get the idea...
I also came across a couple of submissions on FEX that help in serializing/deserializing MATLAB types:
Step 1: mkfifo /tmp/fifo
-- This creates a FIFO, a filename that represents a pipe. Anything written into the pipe stays there until a process reads it back out of the pipe. The data never hits the disk.
Step 2: In one terminal, run this: openssl enc -aes-256-cbc -a -e -in fifo -out safe
-- This runs the OpenSSL program to encrypt with AES, 256 bit key, CBC mode (openssl supports a lot more cipher types and parameters, pick one that works for you, this is a safe default); -a
Base64 encodes the output (which is nice for testing, but you can probably leave it off when you're really using it, Base64 causes a 4/3 size-increase); -e
runs in encrypt mode, -in fifo
specifies that the input file is named fifo
(perhaps use the full path); -out safe
specifies that the output file is named safe
(again, perhaps use a full path). OpenSSL will sleep until data arrives in the pipe.
OpenSSL will prompt you for a passphrase when some data arrives on the pipe.
Test it out: run "echo foo > /tmp/fifo" in another terminal. See the password prompt in the first terminal, give it a password and confirm the password, then look at the contents of the file 'safe':
$ openssl enc -aes-256-cbc -a -e -in fifo -out safe
# (in another terminal, "echo foo > fifo")
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
$ cat safe
U2FsdGVkX18aWBw0Uz8N3SfrRg4PigL609F+HQPuc6o=
Test the other direction:
$ openssl enc -aes-256-cbc -a -d -in safe
enter aes-256-cbc decryption password:
foo
Now, re-run the OpenSSL command from Step 2: openssl enc -aes-256-cbc -a -e -in fifo -out safe
, run your Matlab, and give /tmp/fifo
to the SAVE()
command.
There is a chance that Matlab will do something silly like delete any existing file with the given filename, in which case you will find your unencrypted data in a regular file named /tmp/fifo
. So please test with some unimportant data first. But I hope Matlab is written with Unix tools in mind, and will simply write into the named pipe you give it.
Use getByteStreamFromArray
and getArrayFromByteStream
for serialisation/deserialisation. You can modify the resulting bytes before you write them to a file
% A cell array of several data types
>> byteStream = getByteStreamFromArray({pi, 'abc', struct('a',5)}); % 1x312 uint8 array
>> getArrayFromByteStream(byteStream)
ans =
[3.14159265358979] 'abc' [1x1 struct]
As explained on http://undocumentedmatlab.com/blog/serializing-deserializing-matlab-data