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

Cristo
  • 700
  • 1
  • 8
  • 20
  • 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. – 500 - Internal Server Error Dec 14 '12 at 23:48
  • 1
    Some day you'll look back on this question and ask yourself, "Was I _really_ ever that young?" – John Saunders Dec 14 '12 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. – DWright Dec 14 '12 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... – Alexei Levenkov Dec 15 '12 at 00: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. http://msdn.microsoft.com/es-es/library/system.io.memorystream%28v=VS.80%29.aspx – Cristo Dec 15 '12 at 00:13

4 Answers4

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.

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • 1
    +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. – Carson63000 Dec 15 '12 at 00:36
  • 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 – Cristo Dec 15 '12 at 01:00
  • Not for nothing but just a quick string dump would reveal his connection string with his current setup – Jay Dec 15 '12 at 04:03
  • @jay a connection string saying "in-memory" (in case of SQLite for example) wouldn't help the attacker... – Yahia Dec 15 '12 at 12:34
  • @CristobalDeIncógnitoFlipo I understand that scheme (implemented some myself over the years) but basically all these schemes come down to one point: risk versus cost - i.e. how sophisticated is your really existing most advanced attacker ? and how much does it cost to implement all these measures (including mantainability etc.) ? – Yahia Dec 15 '12 at 12:38
  • @CristobalDeIncógnitoFlipo often there are other options to mitigate the risk once you do the analysis about relevant attack scenarios and their probability and "harmful potential"... – Yahia Dec 15 '12 at 12:39
  • @yahia: I'm working on my own so If my application gets cracked it directly means lot less of benefits for me. the application will be public so the attacker could be anyone. The measures cost is my time wich I have some to spare these days. Can you suggest other options to mitigate? i'm looking at the encryption of the db and the licensing system for the app. Also I have a list of ofuscators/packers to test as this is a .net app – Cristo Dec 15 '12 at 13:31
  • @CristobalDeIncógnitoFlipo what you describe is not a real analysis... "attacker could be anyone" is not a an assesment, who might be interested in cracking it and how sophisticated are they ? "time to spare these days" is a very bad assesment: once you implement this you will need to maintain it (newer OS versions, changes in security etc.) in the future - so you need to be sure that you have enough capacity in the future too! – Yahia Dec 15 '12 at 13:34
  • @CristobalDeIncógnitoFlipo without a real analysis (potential attackers, consequences...) I can't even think of any measures to describe for you... – Yahia Dec 15 '12 at 13:36
  • Good point. The app is focused on little shops of all kind, planning of doing specialized versions for some sectors in the future... say shoe shops versions, bars&cafe version and so on. Typical app of management of bills, printing reports, tickets, etc... So I guess the level of IT skill of most of them (customers) is not good, but there are "freelancer" crackers and so... but yes... i guess odds are low. I fear consequences of application cracked is lot less of sells and that I have to offer something new in the next uncracked-yet version. – Cristo Dec 15 '12 at 13:45
  • Time now and future: I'm doing all I can to make this for a living (I have no job ATM) so I want to spend all my time on this if I can. – Cristo Dec 15 '12 at 13:46
  • @CristobalDeIncógnitoFlipo I see... do your targeted customer base have an internet connection while working with your product ? – Yahia Dec 15 '12 at 14:41
  • I thought of an www based licensing but so many shops here do not have internet connection that i will be limiting my product. If i make local and www licenses then it's waste of time doing www based because the local door is opened, but maybe I'll do www-based and email or phone options, so the algorithm for licensed is under my control. Was that the idea? ;D – Cristo Dec 15 '12 at 16:37
  • 1
    @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 ? – Yahia Dec 15 '12 at 16:40
  • The main competitor I analyzed gives the licences mainly via mail or phone, using a code generated in the application. Then u enter the other code they sent to you in the application and it's registered for a period of time(usually a year). they also sell optional features. Oh, they distribute a trial 90-day app. – Cristo Dec 15 '12 at 17:21
  • @CristobalDeIncógnitoFlipo does the app of your competitor get cracked alot ? – Yahia Dec 15 '12 at 17:31
  • It's developed in VB6 and the db is password protected in mdb... also they don't bother much of updating features so yes, moderately. At least the cracks don't use to be published, instead, they sell in private 'black market' for less than half of original license. That's what I investigated so far. – Cristo Dec 15 '12 at 17:40
  • @CristobalDeIncógnitoFlipo how long are they in business ? are they successful (in terms of market share versus profitability) ? – Yahia Dec 15 '12 at 18:05
  • I think they are very successful but I don't know about those terms you say, selling in at least 5 countries and have been for... i don't know... looking at the design and programing language and other clues I estimate almost 10 years. What's your point? Let's see if I understand the terms: market share as if it is the % of people that have their program I think it is the majority in their specialized areas, and less presence in the others. Profit: it's not an expensive soft. Moderate price. – Cristo Dec 15 '12 at 18:11
  • @CristobalDeIncógnitoFlipo my point is: they have "moderate protection", a free 90-day-trial, have been cracked (copies sold for half the price) and are in business since 10 years in 5 countries... this tells me that cracking/copies is not the main problem in that market... it is more important what features you offer, how good your customer service is, a good customer-friendly pricing model etc. – Yahia Dec 15 '12 at 21:01
  • @CristobalDeIncógnitoFlipo from your description: protection is not the major point here IMO... – Yahia Dec 15 '12 at 21:02
  • OK, I appreciate your input and will take some of your suggestions into consideration. (specially liked the way of splitting features) Still, if they don't care about cracking maybe it's because its a low % of its sells or they still sell millions without bothering about it; but I will care if that happens to me because I start with 0 clients and just a low number of lost clients will screw me. Thanks a lot. – Cristo Dec 16 '12 at 12:47
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".

Carson63000
  • 4,215
  • 2
  • 24
  • 38
  • +1 (and your answer contains one of the most interesting problem with all "encrypt the content" cases - how to deal with passwords/keys). – Alexei Levenkov Dec 15 '12 at 00:23
  • 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. – Cristo Dec 15 '12 at 00:23
  • @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. – Carson63000 Dec 15 '12 at 00:35
  • 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. – Cristo Dec 15 '12 at 00:50
  • 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. – Cristo Dec 15 '12 at 00:51
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.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 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 – Cristo Dec 15 '12 at 00:12
  • @CristobalDeIncógnitoFlipo - the main issue is that using JET/MDB files is [deprecated](http://msdn.microsoft.com/en-us/library/ms810810.aspx#bkmk_MDAC_WDAC). 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. – Carson63000 Dec 15 '12 at 00:16
  • @CristobalDeIncógnitoFlipo, Check out http://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. – Alexei Levenkov Dec 15 '12 at 00:21
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

Jay
  • 3,276
  • 1
  • 28
  • 38
  • 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! – Yahia Dec 15 '12 at 00:26
  • Just think about that for a second and you tell me :) – Jay Dec 15 '12 at 00:28
  • I thought alot about memory-mapped files... please enlighten me. – Yahia Dec 15 '12 at 00:29
  • Well if you make a memory mapped file from the contents of your array what do you have? And then what would you pass to the connection string? – Jay Dec 15 '12 at 00:29
  • 1
    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 ??? – Yahia Dec 15 '12 at 00:31
  • that does NOT help... because the connection string/DB engine still reads from disk... IF that is empty/not a real DB file it won't work!!! – Yahia Dec 15 '12 at 00:40
  • 1
    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` – Jay Dec 15 '12 at 00:47
  • Hahaha I take note of the idea for an ofuscation! (but this alone does not seem a solution) – Cristo Dec 15 '12 at 01:04
  • @Jay what you describe is hard to implement on newer Windows versions since they have heightened security which basically means that you need to run as Administrator... and it is also hard to implement from managed code... hooking an API needs to be done in native code... – Yahia Dec 15 '12 at 12:33
  • Here is some help with that... http://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x86-x64-API-Hooking-Libra – Jay Dec 15 '12 at 15:21