在 PostgreSQL 数据库中存储 X509 证书的最佳方法是什么?

Mar*_*rek 5 postgresql python

我正在开发网络身份验证系统,用户将对随机令牌进行数字签名,这将使用存储在服务器上的 X509 证书进行检查。

因此我必须在 PostgreSQL 数据库中存储几个 X509 证书(PEM 或 DER 格式)。听起来很简单,但我希望有可能使用主题、颁发者、notBefore、notAfter 和类似标准来搜索证书。

我的想法是在数据库中有以下列:X509data、notAfter、notBefore、subject、issuer 等。然后我将使用 add_new_X509()、find_X509(search criteria) 等方法创建代表 X509 证书的对象(在 SQL 炼金术中)。所以无论何时我将使用 add_new_X509() 方法添加新证书,它将自动从证书中读取所有数据并填写其余列并将原始证书放入 X509data 列。

不幸的是,这个解决方案有两个缺点:

  1. 我将两次存储相同的信息(在 X509 证书本身和单独的列中以便于搜索)
  2. 每当我想读取 X509 证书时,我的应用程序都必须交叉检查 notAfter、notBefore、subject、issuer 以及存储在原始证书中的信息(这是出于安全原因,以防有人尝试修改此字段)。

所以..有人有更好的主意或建议吗?也许有人看到此解决方案可能出现的任何其他安全问题?

Cra*_*ger 5

复制并不理想,但在这种情况下可能是最好的选择。设置表权限,以便表所有者不是您的应用程序运行的日常数据库用户,并且只有GRANT您的应用程序能够写入证书数据列,而不是具有到期等的“缓存”列。有一个SECURITY DEFINER触发器函数拦截对证书字段的写入,并作为特权用户通过使用 X.509 库在验证证书后从证书中提取字段来更新索引缓存列。

或者,您可以编写一个 PL/Python、PL/Perl,甚至是一个 C SQL 函数,它调用 X.509 证书解析器库来提取字段并返回它们。所以你会说extract_x509_field(cert, 'subject')。或者甚至是一个行返回表单,比如SELECT subject, issuerName FROM (SELECT extract_x509_fields(cert) FROM the_table)whereextract_x509_fields返回一行所有相关的证书数据。使用这种方法,您可以创建CREATE INDEX cert_issuer ON certificate_table( extract_x509_field(cert,'issuer') );可用于匹配WHERE表达式的功能索引。您根本不需要为提取的数据设置表列。缺点是这可能会更慢,因为证书会在索引创建、索引重新检查等过程中被多次解析。

无论哪种方式,您的应用程序都必须以 PostgreSQL 用户身份运行,该用户不是数据库所有者、超级用户,也不是相关表和索引的所有者。它应该被GRANT赋予必要的最低权利,而不是更多。如果您有非常独立的任务(例如,只读与写入和更新),请考虑为它们使用不同的数据库用户,这样即使您的应用程序的“读取”部分被欺骗尝试写入字段/更新证书/etc,它没有权限。