3

Can I decrypt some file into memory and then use it as a regular file without using harddisk?

More exactly, I want to decrypt a .mdb file with some sensitive data and operate with it like loaded from disk but without using temporary files. I figured that maybe i could do a File object or stream (still have to figure the code) from the decrypted byte array, but then, a problem is that the OleDbConnection loads data from a string containing file name.

Lets try to example this:

byte[] someArrayWithTheContentsOfAdotMDBFile = getDecryptedFile();

[...]

// Even if I get to wrap the array into a File or Stream, the load process requires a filename

using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.\"+ fileNameHere)) // can fileNameHere  be a File object, stream or any trick like that??

edit: As the answers took the thread that way, I changed title to "loading database...". I'm still interested in loading any file type from memory, but lets leave that for another thread

5
  • The only way I can think of that would work in the general sense is decidedly non-trivial, namely to write a disk driver that uses a memory map as its storage area. Commented Dec 14, 2012 at 23:48
  • 1
    Some day you'll look back on this question and ask yourself, "Was I really ever that young?" Commented Dec 14, 2012 at 23:48
  • Two ideas: (1) Set up a Named Pipe and read from it by file name. (2) a ram disk will appear to the OS like any other disk. Commented Dec 14, 2012 at 23:49
  • @500-InternalServerError, I don't think it'll help - it still be visible file (just not written on disk...). It is unclear what is actual restriction... i.e. memory backed by page-file anyway... Commented Dec 15, 2012 at 0:03
  • @Dwright - I took a look at MemoryStream but even if I get that to work, the engine needs a filename in string format to load. msdn.microsoft.com/es-es/library/… Commented Dec 15, 2012 at 0:13

4 Answers 4

3

I don't think that access can do that...

BUT you use the following setup to achieve your goal:

  • Use SQLite
    It can use in-memory (pure RAM) as storage and oprate on that

  • Use an encrypted "SQLite-Dump" (i.e. Backup) as your transport mechanism (file)
    When you need to operate on it, load it into memory, decrypt it, create an empty "SQLite in-memory instance" and "restore" it from your decrypted stream

BEWARE:
The scheme you ask for is possible with some DB engines like SQLite BUT since you need to decrypt the file your application must contain the key needed for decryption.
This means that if someone wants to read your DB file they can by first analyzing your application, recovering the decryption key etc.
IF you use "symmetric encryption" (for example AES) then they can even modify the DB file without your application noticing that.
IF you use "asymmetric encryption" (for example RSA) then they can still read it but they can't modify the DB file.

One very important point regarding security: ANYTHING that runs on a machine that is not 100% under your control can be "cracked" - it only depends on how capable and how motivated the attacker really is.

Sign up to request clarification or add additional context in comments.

22 Comments

+1 for ANYTHING that runs on a machine that is not 100% under your control can be "cracked". Just look at billion dollar industries like selling movies on DVD.
I was working on a scheme that used several encrypted files on disk to make the unencrypted file. No passwords in there, just the algorithm and the files. I agree anything is crackable, just trying to make it harder :D
Not for nothing but just a quick string dump would reveal his connection string with his current setup
@jay a connection string saying "in-memory" (in case of SQLite for example) wouldn't help the attacker...
@CristobalDeIncógnitoFlipo no, not really... the idea was to split up features... "basic features" are available without internet connection... "advanced features" and updates need Internet connection... you could even give them 1 year free "advanced features" if they have internet available... BTW: how does your competition solve this problem ?
|
2

Have you considered using SQL Server Compact with database encryption?

SQL Server Compact is a file-based database, not server-based, which as you said in a comment is preferable for you.

The file on disk is encrypted. It is decrypted in memory, decrypted data is not stored to disk.

It's extremely simple to work with - you just need to put the password in the connection string when you open a connection to the database.

Seems this would fit your use case.


An aside on Password/Key management: Yeah, thanks Alexei, I was hoping nobody would mention that one. :-) It's a tough problem, especially if we're talking about an application that is distributed to the people who you want to protect the database from.

Ultimately, it can't be done. If your application can open the database, and you distribute your application, an attacker can reverse-engineer your application and figure out how to open the database. .NET apps are of course particularly easy to decompile.

The way I see it, you can either just put the key in the code, and accept that anyone who decompiles the code will find it; or you can try to make efforts to obfuscate it (break up the key into various places in the code, write ugly complicated code to reconstruct it, etc.) If you do that, it will still be breakable - you'll just raise the bar from "anyone who decompiles the code" to "anyone who decompiles the code and is willing to spend the time & effort working through your obfuscation".

5 Comments

+1 (and your answer contains one of the most interesting problem with all "encrypt the content" cases - how to deal with passwords/keys).
I didn't know that existed. It sounds like my solution if it does as you say. Sha512 encrypted :D Maybe not too late for switching from MDB. I pray that i don't have to rewrite so many querys. I'll have to take a deep look at this, and maybe could accept as solution. Thanks.
@AlexeiLevenkov: edited the answer for a bit on passwords. I figure, though, the key management situation would basically be the same as it would be with the question's original idea of decrypting a file in memory.
Yep, if i take this way I have to rewrite some queries I guess... thank god I use a class for the connections, but still... then I face the problem of the string password in plain text. I'll take some of ofuscation for sure, but in the end I have to send the final password to the connection. same old-same old... If I do myself the decryption/encryption i can use several steps/fakepasswords to raise the crack-bar a bit and never have real password in a single variable. It could take me few days to analyze and change the project, but it seems the way to go.
The easy of .net decompilation.... I'm looking packers and ofuscators too for the time of the release. It scares how easy is to get code from the unprotected exe.
1

If something requires file name you can't get around having publicly visible file (whether normal file on disk, ram disk or any other kind of device).

You can try:

  • configure security on the file so only current user can open it
  • consider creating temporary file with delete-on-close flag so it does not stay around long enough
  • find another DB engine that can work from in-memory storage.

Side note: you need to think carefully why you are trying to go this route. It may turned out that restrictions you are trying to create either not solving your problem OR complete overkill considering your users.

3 Comments

The purpose is help to making my application harder to crack and not letting access to the database if it's not through my application. "configure security on the file so only current user can open it". Can you explain this? can I lock the file to be readen when its being used? (passwords on mdb are almost insta-cracked) "find another DB engine that can work from in-memory storage." can you name some? better if they use local files like access, not server based like mysql I'm considering the tempfile as my current option, wanted to know if i can do better
@CristobalDeIncógnitoFlipo - the main issue is that using JET/MDB files is deprecated. It's old technology, probably why "passwords on mdb are almost insta-cracked". The solution is to use current technology, i.e. SQL Server Compact, as I recommend in my answer.
@CristobalDeIncógnitoFlipo, Check out stackoverflow.com/questions/5231891/in-memory-database-in-net. For the rest - either think carefully about what you want to achieve, or write protection code that you want to write and don't worry about if it is any useful.
0

Memory Mapped Files seem to be the answer here :)

http://blogs.msdn.com/b/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx

Also

http://www.codeproject.com/Articles/138290/Programming-Memory-Mapped-Files-with-the-NET-Frame

10 Comments

how does that solve the problem ? you can't make memory "appear as a file with full path" with memory-mapped files... "MMF" work the other way around - they make a real file appear as memory!
Just think about that for a second and you tell me :)
I thought alot about memory-mapped files... please enlighten me.
to do that you need to create a real file on disk... the connection string can only deal with real files on disk! how does MMF help in this ???
You could always try to hook the LoadFile call, waiting for the loading of the stub file and immediately patching it with the address of the MemoryMappedFile
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.