【问题标题】:Decrypt sensitive data in database on access在访问时解密数据库中的敏感数据
【发布时间】:2017-08-06 06:11:41
【问题描述】:

我正在使用包含敏感信息(SSN、信用卡详细信息等)的数据库。我正在寻找一种方法来保护数据。

我想在从外部来源引入数据时对其进行加密,同时在我的用户通过使用数据库作为其后端的应用程序访问数据时对其进行解密。

我知道以下两种方法,但我很想知道是否有其他方法可以使用。

例子:

ENCRYPTEDBYPASSPHRASE({PASSWORD}, {FIELD})/DECRYPTBYPASSPHRASE({PASSWORD},{FIELD})
-- This allows me to set a custom password but could be read through the stored procedures.

HASHBYTES('SHA_512', {PASSWORD}+CAST({SALT} AS NVARCHAR(36)))
-- This seems the most secure but I do not know how to decrypt the data from here.

ENCRYPTEDBYPASSPHRASE 在这种情况下是否安全?

【问题讨论】:

  • 您使用的是哪个 DBMS?
  • 抱歉 - 关系 - Microsoft SQL/Oracle
  • 这是两个非常不同的数据库系统。您真的需要两者的解决方案吗?
  • 抱歉,误解了我正在处理的要求。我正在使用 MS SQL 数据库

标签: sql sql-server tsql encryption


【解决方案1】:

加密将数据转换为一系列不固定长度的不可读字符。

哈希是从一串文本生成的字符串或数字。结果字符串或数字是固定长度的。

加密和散列之间的主要区别在于,如果您拥有正确的密钥并且散列可以很好地存储密码,则加密字符串可以反转回其原始解密形式。

1) 如果您想使用散列来保证数据的安全性,那么有很多类型的算法,但 SHA 和 MD4/5 是广泛使用的算法。

例如,如下所示,使用 MD5 算法的散列输出产生一个 16 字节长的值,而 SHA1 算法产生一个 20 字节长的值:

SELECT HASHBYTES('MD5', 'Test String')  AS Col1, HASHBYTES('MD5', 'Test String')  AS Col2 GO

SELECT HASHBYTES('SHA1', 'Test String')   AS Col1, HASHBYTES('SHA1', 'Test String')   AS Col2 GO

2) 如果您想使用加密,那么有两种主要的加密类型,symmetric key encryption 和 public key encryption。

例子:

要创建对称密钥,我们首先需要使用主密钥和证书设置我们的数据库,它们充当我们对称密钥存储的保护者。

创建数据库主密钥:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = ‘myStrongPassword’

创建证书:

CREATE CERTIFICATE MyCertificateName WITH SUBJECT = 'A label for this certificate'

创建对称密钥:

CREATE SYMMETRIC KEY MySymmetricKeyName WITH IDENTITY_VALUE = 'a fairly secure name', ALGORITHM = AES_256, KEY_SOURCE = 'a very secure strong password or phrase' ENCRYPTION BY CERTIFICATE MyCertificateName;

加密和解密数据:

打开钥匙:

在开始加密或解密数据之前,您必须先初始化密钥。这是通过以下代码完成的。

OPEN SYMMETRIC KEY MySymmetricKeyName
DECRYPTION BY CERTIFICATE MyCertificateName
Encrypting data

您可以使用 EncryptByKey 函数加密数据,如下所示:

DECLARE @Result varbinary(256) 
SET @Result = EncryptByKey(Key_GUID('MySymmetricKeyName'), @ValueToEncrypt)

请注意,上述加密的结果是 varbinary(256) 类型,如果您想将值存储在列中以使用此类型。

解密数据:

您可以使用 DecryptByKey 函数解密数据,如下所示:

DECLARE @Result varchar(max)
SET @Result = DecryptByKey(@ValueToDecrypt)

【讨论】:

    【解决方案2】:

    您无法解密哈希(编辑:除非它已被整体破坏),这就是哈希的意义所在。如果您仅将哈希值与您的哈希值进行比较(例如,登录您的应用程序就是这种情况 - 永远不要以明文形式存储密码),这将是一项简单的应用程序端工作。

    我发现这篇关于安全性的非常方便的文章:

    https://security.stackexchange.com/questions/16939/is-it-generally-a-bad-idea-to-encrypt-database-fields

    这应该可以帮助你。

    【讨论】:

      【解决方案3】:

      关于:第二个选项:哈希是一种单向操作。它通常不会以取消散列的意图完成。 (考虑一个密码。它被散列并产生一个 256 字节的字符串。不是对产生的散列进行解码并将其与裸用户输入进行比较,而是对用户的输入进行散列并比较两个散列。)

      我认为您正在寻找使用您的加密方法知识编写的数据访问层。那是你必须自己创造的东西。 (即使用存储过程、函数和视图从中读取数据,在静止状态下加密,解密并将其返回给调用者。拒绝用户访问基础表。创建存储过程 GetAccountNumber 等。[您会注意到,在这些情况下,主键必须是未加密的,以便您可以找到它。其他数据必须以纯文本形式存储,以便您可以正确索引和搜索它。您不想在在这种情况下,您必须循环遍历表中的每条记录,解密每条记录,以找到匹配的地址。])

      Microsoft SQL Server 企业版中提供了透明数据加密 (TDE)。使用 TDE,数据是静态加密的,任何可以访问数据库的人都可以访问未加密的数据。对于数据访问层方法也是如此。在某个时候,这个秘密被暴露了。发生在哪里取决于设计。 TDE 可以通过多种不同方式进行配置。

      如果满足 PCI 要求,我会走 TDE 路线。没有企业版?小马升级。

      【讨论】:

        猜你喜欢
        • 2019-09-07
        • 1970-01-01
        • 2013-03-24
        • 1970-01-01
        • 2012-03-19
        • 2017-11-26
        • 2016-10-08
        • 2011-01-19
        • 2012-08-11
        相关资源
        最近更新 更多