AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 36416
Accepted
Marek
Marek
Asked: 2013-03-12 02:49:57 +0800 CST2013-03-12 02:49:57 +0800 CST 2013-03-12 02:49:57 +0800 CST

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

  • 772

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

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

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

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

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

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

postgresql python
  • 4 4 个回答
  • 8083 Views

4 个回答

  • Voted
  1. Best Answer
    Craig Ringer
    2013-03-12T03:46:32+08:002013-03-12T03:46:32+08:00

    复制并不理想,但在这种情况下可能是最佳选择。设置表权限,以便表所有者不是您的应用程序运行的日常数据库用户,并且只有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,它没有权限。

    • 6
  2. bgiles
    2015-09-09T08:37:11+08:002015-09-09T08:37:11+08:00

    我在我的博客Storing X.509 Digital Certificates (And Other Messy Things)和一些较早的评论中解决了类似的问题。(在这里剪切和粘贴太长了。)如果您可以创建一个用户定义的函数来提取您需要缓存的字段,那么这里提出的许多要点会容易得多。

    解决上面的另一点 -可以编写一个使用 SPI 的触发器来验证证书的颁发者是否存在于数据库中。您需要包括自签名根证书和其他人提供的“受信任”证书的例外情况。这一点,加上其他一些健全性检查(例如,发行者是否具有“基本”能力?是否有 DN 限制?)将为您提供更强大的存储库。

    这样做是否明智?我一直在这方面来回走动。我目前的想法是,如果您发布和管理自己的证书,它会起作用,但如果您合并第三方证书,那将是一个巨大的麻烦。问题是那里有很多垃圾证书。如果你很严格,你会排除很多正在使用的证书,如果你很松懈,那么为什么还要为额外的逻辑烦恼呢?

    • 3
  3. Burhan Khalid
    2013-03-12T03:40:54+08:002013-03-12T03:40:54+08:00

    我不太明白为什么要单独存储各种主题/颁发者字段,除非您要从数据库中查询信息;特别是因为您必须阅读证书以验证其详细信息(列表中的第二项)。

    如果您将其存储为自动过期/失效证书,您可以运行一个单独的任务来执行此操作。

    此外,由于 postgresql 允许您使用 python 作为过程语言;您可以编写一个触发器或视图来返回您的应用程序的“已解析”信息 - 如果您真的想从您的应用程序中卸载它。

    此外,由于您要存储证书,因此我会执行以下操作:

    1. 确保客户端和服务器之间的连接是加密的(无论如何你都应该这样做)。请参阅文档中的第17.9节。

    2. 确保表/列已加密。请参阅pycrypto模块文档。

    • 1
  4. Chris Travers
    2013-03-12T18:06:07+08:002013-03-12T18:06:07+08:00

    添加到 Craig 的出色回复中,一旦您开始从 X509 库中提取信息,您就可以用它做一些其他有趣的事情。我不知道 SQLAlchemy 是否总是使用表别名,或者您是否可以强制它这样做,但如果可以,那么您可以通过直接调用 X509 证书上的解析例程来避免重复信息,您甚至可以索引输出正如他所提到的那样,您不必在选择时间调用它们(即函数在插入/更新时间运行)。

    我要指出的一件事是,您可以创建表方法,如果您可以让您的 ORM始终使用表别名,则可以代替列。例如:

    CREATE OR REPLACE FUNCTION issuer(x509table) returns text 
    LANGUAGE SQL IMMUTABLE AS $$
        select issuer_cn FROM extract_x509info($1.x509data);
    $$;
    

    然后可以通过以下方式找到:

    SELECT x.issuer FROM x509table x;  --works
    

    请注意,以下内容无效,因此我对 ORM 的评论:

    SELECT issuer FROM x509table; --does not work
    

    原因是如果没有颁发者列,解析器会将第一条语句转换为:

    SELECT issuer(x) from x509table x;
    

    请注意,为大量列建立索引会使大量计算时间从读取转移到写入(使插入/更新更慢,但读取操作更快)。

    最后,如果不确切知道您在做什么,您的预期工作负载是什么等,很难提出完整的建议。复制的优点是它将数据与读取和写入的提取函数分开,允许更多优化成为可能。保持一切正常运行(假设您的 ORM 支持这一点)的优势在于它提供了数据完整性的额外保证。

    • 1

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve