【问题标题】:Secure Private Key (RSA) with user password (AES)带有用户密码 (AES) 的安全私钥 (RSA)
【发布时间】:2016-11-30 08:14:51
【问题描述】:

我需要对我的 ASP.NET Core 应用程序中的一些数据进行高度加密。

这个想法是: 用户将拥有一个散列密码。用户还将拥有一个非对称密钥 (RSA-512)。公钥存储在数据库中。私钥首先通过对称密钥 (AES-256) 进行加密。作为此加密的密钥,我们使用用户的明文/文本密码。

如果我想创建一些东西,例如汽车实体。我将为这个特定的汽车实体生成一个公钥和私钥。公钥以纯文本形式存储。私钥使用“汽车”创建者(用户)的公钥加密。

属于汽车的字段比用汽车的公钥加密。

解密汽车。我们需要用户的私钥,因为这是解密汽车私钥所必需的。有了这个解密的汽车私钥,我们就可以解密汽车的内容。

但要成为用户的私钥,我需要用明文/文本密码对其进行解密。此密码仅在@登录时间可用一次(当然它没有存储在任何地方)。

我现在遇到的问题是我正在使用带有 IdentityServer 4 的联合登录系统。这是一个与我的 API 项目不同的“项目”。

但我需要 API 中的密码,因为这会执行我的“业务逻辑”。

真正的问题从这里开始:

解决这个问题:

我正在考虑在我的 API 中添加一个我的登录项目可以调用的“路由”。 因此,每次用户登录登录项目时,都会执行对正确 API 的 REST 调用,并显示如下消息:'这是用户 X 的私钥的解密版本'。

此时 API 会将其存储在“InMemory”EF Core 数据库中。每次用户需要解密他的汽车数据。我需要从“InMemory”数据库中检索私钥。

我在这里遇到的问题。 EF 'InMemory' DB 是否用于此目的?看起来它仅用作演示或测试目的。

什么时候删除内存的私钥。如果用户注销,我可以管理它。但是,当用户“过期”时,我无法触发此操作。所以他解密后的私钥会一直存在于记忆中。

“InMemory”数据库的可靠性如何?它什么时候“清理”自己?

我很高兴收到一些有用的提示。

此致,布莱希特

【问题讨论】:

  • InMemoryDB 主要用于单元测试,您可以使用它来填充和返回数据,而不是依赖真实的数据库
  • 另外:我不是安全专家,但您的系统/逻辑似乎存在很大缺陷,并且超出了安全基础。私钥永远不应该让用户拥有,但您真正想做的是用对称加密对其进行加密,然后在服务器上对其进行解密?这意味着“客户端”和“服务器”都必须知道它。这超出了它的全部目的,您也可以通过 SSL 发送未加密的私钥并具有相同级别的安全性,现在应该作为秘密的散列密码也被替换/用作“明文中的密码” "。
  • 攻击者不再需要真正的密码,他只需要获取身份服务器数据库的哈希值即可访问和解密所有数据。这里的保安在哪里?你什么都没有。这只能在直接使用用户密码并且只有当他输入密码以解密客户端上的某些数据并通过安全通道(带有验证的 SSL 等)将其发送回服务器时才有效
  • 不,他们不需要密码,因为您不使用密码。您只使用密码的哈希,在这种情况下,它基本上充当了一个paintext 密码。 hash 存储在您的身份服务器数据库中,如果他们违反,他们可以轻松获取它。这就是为什么我说它不会增加太多保护,因为解密它所需的所有数据都在你的服务器上!!!只有当私钥/密码短语仅由用户拥有时,保护才能有效,当他想要解密数据时必须提交
  • 这被称为 security by obscurity,几乎没有或根本没有提供保护。如果用户拥有密码私钥,那么当有人入侵服务器时,他们没有机会解密数据,直到用户尝试登录/解密它在违反后的第一次。如果他不这样做,他的数据是安全的。在您的情况下,所有用户数据会在发生违规时自动泄露,攻击者可以访问所有必需的数据

标签: c# encryption cryptography asp.net-core identityserver4


【解决方案1】:

除了安全问题(参见 cmets),InMemoryDatabase 主要用于测试或无 db 教程。您添加到其中的所有内容都将保留在那里,直到 deleted(以及后来的垃圾收集,您实际上无法控制!)或 DbContext 被释放。

使用内存缓存(分布式或本地)而不是 InMemory EF Core 数据库更有意义。

您当然可以使用像 Redis 这样的分布式缓存并将解码后的私钥保存在其中,然后从您的服务中调用它。您可以添加一个expiry 日期,当密钥失效并需要请求或通过在密钥上调用expire command 来延长到期时间,当用户注销时,使用del 删除密钥。

如果您扩大服务器规模,它也能正常工作。如果你从Microsoft.Extensions.Caching.Memory 开始,你以后可以轻松切换到Redis,因为它们都实现了IDistributableCache 接口,只需在启动类中更改配置即可。

您可能还想尝试使用 SecureString(请参阅 here),它不是直接在 .NET Core 中实现的,但可以作为额外包 here 提供)以使其在本地内存中尽可能短,而不是相信 GC 在某个时候会这样做。

【讨论】:

    猜你喜欢
    • 2018-05-31
    • 2022-07-08
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2012-12-19
    • 1970-01-01
    相关资源
    最近更新 更多