公钥基础结构(续):基于OpenSSL和SQLite3的证书颁发机构

图片 如果公钥基础结构(PKI)的主要对象之一是X509证书,则PKI的中心主题是证书颁发机构(CA)。 颁发证书,终止其有效性(证书吊销),确认其有效性的是CA。 在Habrahabr的页面上您可以找到有关使用OpenSSL发行数字证书的各种出版物。 基本上,这些文章讨论了openssl实用程序的用法,描述了它的命令行界面,并使用了存储所有内容的文件:密钥,请求,证书,包括根目录等。 但是,如果您开发基于OpenSSL的全面认证中心(CA),那么自然就希望摆脱各种文件并转而使用数据库,并具有用于颁发和管理证书的图形界面。 如果您还记得2011年4月6日的联邦法律。 关于电子签名的第63-号要求,CA必须遵守该法律的要求以及2011年12月27日俄罗斯联邦安全局命令第795号批准的电子签名验证密钥合格证书的格式要求。

普通市民给人的印象是UT太庞大了(嗯,中心就像任务控制中心一样)。

图片 从CA的责任角度来看-确实如此。 毕竟,由CA颁发的证书实际上在今天的护照中是相同的。

从程序员的角度来看,一切并不那么可怕。 于是CAFL63认证中心项目诞生了。 CAFL63项目的实现基于三个“支柱”,即OpenSSL, SQLite3Tcl / Tk

那么今天的认证中心是什么? 首先,它是注册中心,法人,个人,个体企业家的代表来此索取带有一整套必要文件的证书,特别是确定申请人的身份和权限。 他们可以以电子方式提供现成的应用程序。 CR检查文档,请求(完整的数据,电子签名的正确性等),如果一切顺利,请接受请求,批准并发送给认证中心(CA)。 但这是理想的。 实际上,一切看起来都不同。

公民组织需要证书(用于访问State Services门户,税务报告,投标),但是他们不知道它是什么以及如何使用它。 他们由衷地相信CA会收到电子签名,例如传真。 但是这些都是启蒙的问题。 因此,申请人来到中央行政管理中心并出示文件。 他们与中央办公室的员工一起前往另一个工作场所并准备证书申请



CR已经收到了关于电子媒体的准备好的请求。 申请人需要记住什么? 首先,使用创建的私钥拾取媒体!
将批准的电子媒体请求发送到CA,CA将根据证书颁发证书。

这是CA的工作原理图。 详细信息将在下面变得清楚。 一句话,为了方便演示,将准备请求的实用程序,CR和CA合并为一个演示复合体。 但是功能多样性没有问题。 其中最简单的方法是在每个工作场所都拥有一个CAFL63实例,并仅使用所需的功能。

当项目进行得如火如荼时, SimpleCA项目引起了我的注意。 研究此项目对CAFL63 CA的最终实施有很大帮助。

可以找到该实用程序的源代码及其在Linux和MS Windows平台上的发行版本。
因此,运行CAFL63实用程序,开始页面出现在屏幕上:



我们通过按“创建数据库”键开始工作。 使用SQLite3跨平台DBMS创建CA数据库。 CA数据库包含几个表。 主表mainDB仅包含一条记录,该记录存储根证书,使用密码加密的私钥和CA设置。 有两个与证书请求相关的表:当前reqDB请求和reqDBArc请求归档。 为证书创建了三个表:新证书certDBNew的表,证书存档certDB的表和吊销证书certDBRev的表:

. . . certdb eval {create table certDB( ckaID text primary key , nick text, sernum text, certPEM text, subject text, notAfter text, notBefore text, dateRevoke text, state text )} certdb eval {create table certDBRev( ckaID text primary key )} certdb eval {create table certDBNew( ckaID text primary key )} certdb eval {create table reqDB (ckaID text primary key, nick text, sernum text, subject text, type text, datereq text, status text, reqpem text, pkcs7 text)} certdb eval {create table reqDBAr (ckaID text primary key, nick text, sernum text, subject text, type text, datereq text, status text, reqpem text, pkcs7 text)} certdb eval {create table crlDB(ID integer primary key autoincrement, signtype text, issuer text, publishdate text, nextdate text, crlpem text)} . . . 

所有请求和证书表都使用公共密钥中的哈希值 (sha1)作为密钥(主密钥)。 为了方便起见,将来,来自公钥值的哈希值将称为CKAID(PKCS#11术语)。 事实证明,这非常方便,例如,根据要求搜索证书时,反之亦然。 数据库中还有另一个crlDB表,用于存储已撤销证书的列表。

公钥值既存储在请求中,又存储在证书中。 因此,在将它们放入数据库之前,有必要从它们中提取公钥并计算CKAID。 要提取公钥的值,使用pki软件包(需要pki的软件包)非常方便,该软件包包含用于处理证书和请求的工具。 但是,此软件包并非旨在与俄罗斯密码一起使用。 在这方面,根据pki软件包中包含的parse_cert和parse_csr过程,编写parce_cert_gost和parse_csr_gost过程:

 ... ## Convert Pubkey type to string set pubkey_type [::pki::_oid_number_to_name $pubkey_type] # Parse public key, based on type switch -- $pubkey_type { "rsaEncryption" { set pubkey [binary format B* $pubkey] binary scan $pubkey H* ret(pubkey) ::asn::asnGetSequence pubkey pubkey_parts ::asn::asnGetBigInteger pubkey_parts ret(n) ::asn::asnGetBigInteger pubkey_parts ret(e) set ret(n) [::math::bignum::tostr $ret(n)] set ret(e) [::math::bignum::tostr $ret(e)] set ret(l) [expr {int([::pki::_bits $ret(n)] / 8.0000 + 0.5) * 8}] set ret(type) rsa } "1.2.643.2.2.19" - "1.2.643.7.1.1.1.1" - "1.2.643.7.1.1.1.2" { # gost2001, gost2012-256,gost2012-512 set pubkey [binary format B* $pubkey] binary scan $pubkey H* ret(pubkey) set ret(type) $pubkey_type ::asn::asnGetSequence pubkey_algoid pubalgost #OID -  ::asn::asnGetObjectIdentifier pubalgost oid1 #OID -   ::asn::asnGetObjectIdentifier pubalgost oid2 } default { error "Unknown algorithm" } } ... 

与“本机”过程不同,它们使您不仅可以使用PEM格式的对象,还可以使用DER格式的对象。 为了使用CRL证书吊销列表,编写了parse_crl过程。 所有这些过程都可以在源代码中找到,该源代码与分发一起存储。

另外,在pki软件包中没有俄文oid,例如TIN,SNILS等。 通过在数组:: pki :: oids中添加俄语oid -s可以轻松解决此问题:

 . . . set ::pki::oids(1.2.643.100.1) "OGRN" set ::pki::oids(1.2.643.100.5) "OGRNIP" set ::pki::oids(1.2.643.3.131.1.1) "INN" set ::pki::oids(1.2.643.100.3) "SNILS" #  set ::pki::oids(1.2.643.2.2.3) "  34.10-2001" set ::pki::oids(1.2.643.7.1.1.3.2) "  34.10-2012-256" set ::pki::oids(1.2.643.7.1.1.3.3) "  34.10-2012-512" . . . 

具有函数parse_cert_gost和parse_csr_gost的CKAID值(数据库的主键)的计算如下:

 . . . array set b [parse_csr_gost $req] set pem $b(pem) set subject $b(subject) set pubkey $b(pubkey) set key1 [binary format H* $pubkey] set ckaID [::sha1::sha1 $key1] . . . 

因此,单击按钮“创建数据库”:



创建CA时首先要选择目录,我们将在其中存储数据库和密码设置以访问CA私钥。 CAFL63实用程序会仔细监视密码长度:



密码以哈希形式存储在CA数据库中:

 . . . set hash256 [::sha2::sha256 $wizData(capassword)] . . . 

按下“ Trace”(跟踪)键后,将开始形成已部署CA的自签名根证书的过程。 在此过程的第一步,选择密钥对的类型和参数:



在确定了创建的认证中心的根证书的密钥对之后,我们继续使用有关所有者的信息填写表单(缺少第一个屏幕截图)。

请注意,CAFL63实用程序具有一定的“智能”,因此不仅可以控制字段中数据的可用性,还可以控制填写TIN,PSRN,SNILS,PSRNIP,电子邮件地址等字段的正确性(红色突出显示-错误):



在填写了有关CA所有者的信息后,将提供它来确定CA的系统设置:



如果您不打算使用俄语加密,那么可以使用通常的OpenSSL。 要使用俄语加密,必须选择适当的版本,即OpenSSL的修改。 有关更多详细信息,请阅读下载的发行版中的README.txt。 由于计划颁发合格证书,因此还必须提供有关CA本身及其所使用的密码信息保护系统的证书的信息(请参阅2011年12月27日俄罗斯联邦安全局命令批准的“电子签名验证密钥合格证书表格的要求”)。

正确填写所有字段后,将再次提供它以检查其准确性,然后单击“完成”按钮:



单击“完成”按钮后,将创建CA数据库,其中将保存CA根证书,私钥,系统设置,并且CAFL63实用程序开始页面将再次出现在屏幕上。 现在,我们已经创建了新创建的CA的数据库,我们单击“打开数据库”按钮,选择带有数据库的目录,转到CA的主工作窗口,然后单击“查看CA CA”按钮,确保已创建的根证书:



下一步是为法人,个人和个人企业家准备应用程序模板/配置文件(“ 工具”->“设置”->“证书类型”->“新建” ):



在指定新配置文件的名称之后,将建议确定其组成:



配置文件的组成由专有名称(证书持有者的专有名称/唯一名称)确定。 每个配置文件都有自己的组成,其中包含必填(必填)或非必填字段/ oid。 法律实体,个人,个人企业家的个人资料的构成由联邦第63号法律的要求和俄罗斯FSB的“电子签名验证密钥证书的合格证书形式要求”决定。

准备好个人资料后,CA可以接收他们的申请者和申请。 如上所述,申请人可以随身携带或不随身携带证书。
如果申请人提供了准备好的申请,则在检查其文件之后,会将申请导入到CA的数据库中。 为此,请在主工作窗口中选择“证书申请”选项卡,单击“导入申请/ CSR”按钮,然后选择包含该申请的文件。 之后,将出现一个包含有关请求信息的窗口:



在查看请求并确保正确填写请求之后,您可以单击“导入”按钮以将其输入数据库。 马上,我们注意到当您尝试在CA数据库中重新发出请求时,将显示一条消息:



到CA数据库的请求被标记(“类型”列)为在CA注册中心创建的“区域设置”,或由申请人本人创建的“导入”,并且还记录了在CA中收到申请的时间。 这对于解决冲突情况很有用。 因此,在导入证书申请时,您应指出是谁创建了该申请(请参见屏幕截图)。
导入的应用程序位于CA数据库中,并显示在“证书请求”选项卡的主窗口中。 收到的请求处于“考虑”阶段(“证书请求”和“请求档案”选项卡的“状态”列)。 对于每个新收到的请求,都必须做出决定(右键单击所选请求时,会出现下拉菜单):



每个请求都必须被拒绝或批准:



如果请求被拒绝,则将其从当前reqDB请求的表移至reqDBArc请求归档的表,并因此在“证书请求”选项卡上消失,并在“请求归档”选项卡上出现。

批准的应用程序保留在reqDB表中和“证书申请”选项卡上,直到颁发证书为止,然后也将其保存在存档中。

在颁发证书之前,有必要与申请人明确说明将使用证书的目的(例如,访问国家服务门户)( 工具->设置->证书类型->个人->编辑->密钥用法 ):



要颁发证书,必须在“证书申请”选项卡上选择批准的应用程序,右键单击并在下拉菜单中选择“颁发证书”。 在显示的小部件中,您将需要选择请求/证书的配置文件应与之对应的配置文件:



请注意,在颁发证书的过程中,您可以阐明特定字段的值:



颁发证书本身的过程(菜单项“颁发证书”)与创建根证书或发布应用程序的过程几乎没有什么不同:



颁发的证书将立即显示在“证书”选项卡上。 在这种情况下,证书本身将落入CA数据库的certDBNew表中,并保持在那里直到发布。 将证书导出到新证书的SQL转储后,该证书将被视为已发布,该新证书将被传输到公共服务。 发布证书会将其从certDBNew表移至certDB表。

如果右键单击“证书”选项卡中的所选行,将显示具有以下功能的菜单:



这些功能使您既可以查看证书本身,也可以查看证书的颁发日期。 您还可以将证书导出到文件或申请人的闪存驱动器。 这里最重要的功能是证书吊销功能! 有一个特殊的功能,例如将证书导出到PKCS#12安全容器。 当申请人想要接收这样的容器时使用它。 对于此类申请人,特别提供了将私钥保存在文件中的请求生成功能(“证书请求”选项卡上的“创建请求/ CSR”按钮)。

因此,CA开始了其生命,颁发了第一份证书。 CA的目标之一是组织免费访问已颁发证书的组织。 证书的发布通常通过Web服务进行。 CAFL63还提供以下服务:



要在公共服务上发布证书和吊销的证书列表,CA会将证书预先上传到文件( Certificates-> Export Certificates ),或者对整个证书表进行SQL转储,从中可以创建证书数据库并将其上传到数据库,然后进行处理新证书的SQL转储,将从中将新证书添加到公共服务数据库中:



CA的基本功能是发布一份吊销证书清单,类似于内政部对过期护照的处理方式。 证书可以应所有者的要求吊销。 撤销的主要原因是私钥丢失或对其失去信任。

要撤销证书,只需在“证书”选项卡上选择它,右键单击并选择菜单项“证书撤销”:



撤销程序与请求或颁发证书的批准程序没有什么不同。 吊销的证书将落入CA数据库的cerDBRev表中,并显示在“吊销的证书”选项卡中。

仍然需要考虑CA的最后功能-CRL的发布-吊销证书的列表。 单击“创建SOS / CRL”按钮时,“已撤销的证书”选项卡上将形成CRL列表。 管理员所需要做的就是输入CA密码并确认您打算发布CRL:



颁发的CRL落入数据库的crlDB表中,并显示在CRL / SOS选项卡上。

为了在将CRL放入数据库之前解析CRL,编写了parse_crl过程:

 proc parse_crl {crl} { array set ret [list] if { [string range $crl 0 9 ] == "-----BEGIN" } { array set parsed_crl [::pki::_parse_pem $crl "-----BEGIN X509 CRL-----" "-----END X509 CRL-----"] set crl $parsed_crl(data) } ::asn::asnGetSequence crl crl_seq ::asn::asnGetSequence crl_seq crl_base ::asn::asnGetSequence crl_base crl_full ::asn::asnGetObjectIdentifier crl_full ret(signtype) #puts "KEY_TYPE=$ret(signtype)" ::::asn::asnGetSequence crl_base crl_issue set ret(issue) [::pki::x509::_dn_to_string $crl_issue] #puts "ISSUE=$ret(issue)" ::asn::asnGetUTCTime crl_base ret(publishDate) ::asn::asnGetUTCTime crl_base ret(nextDate) #puts "publishDate=$ret(publishDate)" return [array get ret] } 

要查看CRL或将其导出以在公共服务上发布,必须像往常一样选择所需的行,单击鼠标右键并选择适当的菜单项:



仅此而已,证书颁发机构已准备就绪。
图片 在此处了解如何组装和连接带有俄语密码的OpenSSL。

Source: https://habr.com/ru/post/zh-CN413493/


All Articles