【问题标题】:loading database file from memory从内存中加载数据库文件
【发布时间】:2012-12-14 23:45:36
【问题描述】:

我可以将一些文件解密到内存中,然后在不使用硬盘的情况下将其用作普通文件吗?

更准确地说,我想解密一个包含一些敏感数据的 .mdb 文件,并像从磁盘加载一样对其进行操作,但 不使用临时文件。 我想也许我可以从解密的字节数组中做一个 File 对象或流(仍然必须计算代码),但是,问题是 OleDbConnection 从包含文件名的字符串加载数据。

让我们试着举个例子:

byte[] someArrayWithTheContentsOfAdotMDBFile = getDecryptedFile();

[...]

// 即使我将数组包装到文件或流中,加载过程也需要文件名

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??

编辑:由于答案采用这种方式,我将标题更改为“正在加载数据库......”。我仍然有兴趣从内存中加载任何文件类型,但让我们把它留给另一个线程

【问题讨论】:

  • 我能想到的唯一能在一般意义上起作用的方法绝对不是微不足道的,即编写一个使用内存映射作为其存储区域的磁盘驱动程序。
  • 有一天你会回顾这个问题并问自己:“我真的有那么年轻吗?”
  • 两个思路:(1)建立一个命名管道,通过文件名读取。 (2) ram 磁盘将像任何其他磁盘一样出现在操作系统中。
  • @500-InternalServerError,我认为它没有帮助 - 它仍然是可见文件(只是没有写在磁盘上......)。目前尚不清楚什么是实际限制......即无论如何都由页面文件支持的内存......
  • @Dwright - 我查看了 MemoryStream,但即使我让它工作,引擎也需要一个字符串格式的文件名来加载。 msdn.microsoft.com/es-es/library/…

标签: c# database file memory


【解决方案1】:

我不认为访问可以做到这一点......

但是您使用以下设置来实现您的目标:

  • 使用 SQLite
    它可以使用内存(纯 RAM)作为存储并对其进行操作

  • 使用加密的“SQLite-Dump”(即备份)作为传输机制(文件)
    当您需要对其进行操作时,将其加载到内存中,解密它,创建一个空的“SQLite 内存实例”并从您的解密流中“恢复”它

注意:
您要求的方案对于 SQLite 等一些数据库引擎是可能的,因为您需要解密文件,您的应用程序必须包含解密所需的密钥。
这意味着如果有人想读取您的数据库文件,他们可以通过首先分析您的应用程序、恢复解密密钥等来读取。
如果您使用“对称加密”(例如 AES),那么他们甚至可以在您的应用程序没有注意到的情况下修改数据库文件。
如果您使用“非对称加密”(例如 RSA),那么他们仍然可以读取它,但他们无法修改数据库文件。

关于安全性的一个非常重要的一点:任何运行在非 100% 受您控制的机器上的东西都可能被“破解”——这仅取决于攻击者的能力和动机。

【讨论】:

  • +1 表示在非 100% 受您控制的机器上运行的任何东西都可能被“破解”。看看价值数十亿美元的行业,比如在 DVD 上销售电影。
  • 我正在研究一种方案,该方案使用磁盘上的多个加密文件来制作未加密的文件。那里没有密码,只有算法和文件。我同意任何事情都是可以破解的,只是想让它变得更难:D
  • 不是没有的,只是一个快速的字符串转储会显示他当前设置的连接字符串
  • @jay 一个连接字符串说“内存中”(例如在 SQLite 的情况下)不会帮助攻击者...
  • @CristobalDeIncógnitoFlipo 不,不是真的...想法是拆分功能...“基本功能”无需互联网连接即可使用...“高级功能”和更新需要互联网连接... . 你甚至可以给他们 1 年免费的“高级功能”,如果他们有互联网可用...顺便说一句:你的竞争对手是如何解决这个问题的?
【解决方案2】:

您是否考虑过将SQL Server Compactdatabase encryption 一起使用?

SQL Server Compact 是基于文件的数据库,而不是基于服务器的数据库,正如您在评论中所说的那样,它更适合您。

磁盘上的文件已加密。它在内存中解密,解密后的数据不存储到磁盘。

使用起来非常简单——您只需在打开与数据库的连接时将密码输入连接字符串即可。

这似乎适合您的用例。


关于密码/密钥管理的旁白: 是的,谢谢 Alexei,我希望没有人会提到那个。 :-) 这是一个棘手的问题,尤其是当我们谈论的是分发给您想要保护数据库的人的应用程序时。

最终,它无法完成。如果您的应用程序可以打开数据库,并且您分发了您的应用程序,那么攻击者可以对您的应用程序进行逆向工程并找出如何打开数据库。 .NET 应用程序当然特别容易反编译。

在我看来,您可以将密钥放入代码中,并接受任何反编译代码的人都会找到它;或者您可以尝试对其进行混淆(将密钥分解到代码中的各个位置,编写丑陋的复杂代码来重构它等)如果您这样做,它仍然是可破解的 - 您只需提高从“任何反编译代码的人”到“任何反编译代码并愿意花费时间和精力来解决您的混淆问题的人”。

【讨论】:

  • +1(您的答案包含所有“加密内容”案例中最有趣的问题之一 - 如何处理密码/密钥)。
  • 我不知道它存在。如果按照你说的那样做,这听起来像是我的解决方案。 Sha512 加密 :D 从 MDB 切换可能还为时不晚。我祈祷我不必重写这么多查询。我必须深入研究一下,也许可以接受作为解决方案。谢谢。
  • @AlexeiLevenkov:编辑了密码的答案。不过,我认为,密钥管理情况基本上与问题的原始想法相同,即解密内存中的文件。
  • 是的,如果我采用这种方式,我想我必须重写一些查询...谢天谢地,我使用一个类进行连接,但仍然...然后我面临字符串密码的问题纯文本。我肯定会花一些时间,但最后我必须将最终密码发送到连接。相同的旧旧的...如果我自己进行解密/加密,我可以使用几个步骤/假密码来稍微提高破解栏,并且在单个变量中永远不会有真正的密码。我可能需要几天的时间来分析和更改项目,但这似乎是可行的方法。
  • .net 反编译的简单性.... 我也在寻找打包程序和操作员在发布时。从不受保护的 exe 中获取代码是多么容易。
【解决方案3】:

如果某些内容需要文件名,您无法绕过公开可见的文件(无论是磁盘上的普通文件、ram 磁盘还是任何其他类型的设备)。

你可以试试:

  • 为文件配置安全性,以便只有当前用户可以打开它
  • 考虑创建带有关闭时删除标志的临时文件,这样它就不会保留足够长的时间
  • 寻找另一个可以在内存存储中工作的数据库引擎。

旁注:您需要仔细考虑为什么要走这条路。事实证明,您尝试创建的限制要么无法解决您的问题,要么考虑到您的用户完全矫枉过正。

【讨论】:

  • 目的是帮助使我的应用程序更难破解,并且如果不是通过我的应用程序,则不允许访问数据库。 “在文件上配置安全性,以便只有当前用户可以打开它”。你能解释一下吗?我可以在使用文件时锁定要读取的文件吗? (mdb 上的密码几乎被即时破解)“找到另一个可以在内存存储中工作的数据库引擎。”你能说出一些吗?如果他们使用像访问这样的本地文件,而不是像mysql这样基于服务器的文件会更好我正在考虑将临时文件作为我当前的选择,想知道我是否可以做得更好
  • @CristobalDeIncógnitoFlipo - 主要问题是使用 JET/MDB 文件是deprecated。这是旧技术,可能是“mdb 上的密码几乎被即时破解”的原因。解决方案是使用当前技术,即 SQL Server Compact,正如我在回答中所推荐的那样。
  • @CristobalDeIncógnitoFlipo,查看stackoverflow.com/questions/5231891/in-memory-database-in-net。其余的 - 要么仔细考虑你想要实现的目标,要么编写你想要编写的保护代码,不要担心它是否有用。
【解决方案4】:

【讨论】:

  • 如何解决问题?您不能使用内存映射文件使内存“显示为具有完整路径的文件”...“MMF”反过来工作-它们使真实文件显示为内存!
  • 想一想,然后告诉我 :)
  • 我想了很多关于内存映射文件...请赐教。
  • 要做到这一点,您需要在磁盘上创建一个真实文件...连接字符串只能处理磁盘上的真实文件! MMF 在这方面有什么帮助???
  • 您总是可以尝试挂接LoadFile 调用,等待存根文件的加载并立即使用MemoryMappedFile 的地址对其进行修补
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 2017-05-23
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
相关资源
最近更新 更多