2016-11-30 54 views
0

我需要对我的ASP.NET Core应用程序中的一些数据进行高度加密。用户密码(AES)的安全私钥(RSA)

这个想法是: 用户将有一个哈希密码。用户还将拥有一个非对称密钥(RSA-512)。公钥存储在数据库中。私钥首先被对称密钥(AES-256)加密。作为这种加密的关键,我们使用用户的纯文本/文本密码。

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

属于该车的字段不是用汽车的公钥加密的。

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

但是,要成为用户的私钥,我需要用普通/文本密码进行解密。此密码仅在登录时有一次(无处存储)。

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

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

真正的问题从这里开始:

为了解决这个问题:

我想加入我的API一个“路线”,我的登录项目可以打电话的。 因此,每次用户登录登录项目时,都会执行REST调用以正确的API作为消息:'这是用户X的私钥的解密版本'。

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

问题我在这里。 EF'InMemory'数据库是否用于此目的?它看起来只能用作演示或用作测试目的。

何时删除内存的私钥。如果用户注销,我可以管理它。但是当用户'过期'时,我无法触发此事。所以他解密的私钥将会保存在内存中。

'InMemory'数据库有多可靠?它什么时候“清理”自己?

我很乐意收到一些有用的提示。

真诚,布莱希特

+1

InMemoryDB主要用于单元测试,您可以在其中使用它来填充和返回数据,而不是依赖实际数据库 – Tseng

+0

另外:我不是安全专家,但是您的系统/逻辑看起来相当有缺陷并且击败了安全基础知识。私钥永远不应该让用户拥有,但是你真正想要做的是用对称加密对它进行加密,然后在服务器上解密它?这意味着“客户端”和“服务器”都必须知道它。这就是它的全部目的,你也可以通过SSL发送未加密的私钥并且具有相同的安全级别,同样应该是秘密的散列密码现在只是被替换/用作密码的明文”。 – Tseng

+0

攻击者不再需要真正的密码,他只需要获得身份服务器数据库的哈希值即可访问和解密所有数据。这里的安全性在哪里?你赢了**没有**。这只能在直接使用用户密码时才有效,只有当用户密码输入时才能解密客户端上的某些数据,并通过安全通道将其发送回服务器(具有验证等的SSL) – Tseng

回答

1

安全问题放在一边(见注释),该内存数据库主要有用于测试或DB-少教程。你添加到它的所有东西都会一直存在,直到deleted(以及一些以后的垃圾收集,你没有真正控制!)或DbContext被丢弃。

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

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

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

你也可以尝试使用SecureString的(见here),这是不是在.NET核心直接实现,但可以作为额外的包here),以保持它尽可能短的本地内存,而不是依靠该GC在某些时候会这样做。