Req指令介绍

功能概述和指令格式

  • req指令一般来说应该是提供给证书申请用户的工具,用来生成证书请求以便交给CA验证和签发证书。但是,OpenSSL的req指令的功能远比这样的要求强大得多,它不仅可以生成RSA密钥、DSA密钥,以及将它们封装成证书请求,还可以对现有的证书请求进行签名验证、格式转换及信息修改等。下面将通过对req指令的各个参数的介绍来了解其全面的功能。首先来看看req指令的格式:

  • eq指令的许多选项跟OpenSSL配置文件(默认为openslcnf)的证书请求部分是紧密相关的,如果在指令中有些选项需要指定的参数没有给定,那么req指令就会从配置文件中相应的字段去查找设置值。此外,有相当部分的证书请求属性都是由配置文件的相关部分决定的。在本节的介绍中,会指出相应的证书请求配置部分内容。

输入和输出格式选项inform,outform和keyform

  • inform选项指定了选项in指定的输入证书请求文件的编码格式,目前来说,支持的编码格式有两种:PEM编码和DER编码,默认为PEM编码。in选项指定的文件输入内容是一个已经存在的符合PKCS#10标准的证书请求,在这里输入的目的一般是为了验证和显示其中的一些内容。outform选项指定了输出选项out输出的证书请求或自签名证书的编码格式,目前支持的编码格式包括PEM编码和DER编码,默认为PEM编码。需要注意的是,该选项指定的格式不影响keyout选项的密钥编码格式和pubkey输出的公钥编码格式keyform选项指定了密钥输入选项key指定的密钥编码格式,目前来说,可以接受的编码格式包括PEM编码格式、DER编码格式、PKCS#12编码格式、Netscape编码格式、旧版本的IISSGC编码格式及Engine格式

输入和输出文件选项in,out,key和keyout

  • in选项指定了保存证书请求的文件名,默认是标准输入。如果启用了该选项,那么指令将根据一个已经存在的证书请求生成自签名根证书或者显示其中的一些内容,但是该证书请求的内容基本上是不能进行变更的。如果是要根据现有的证书请求生成自签名根证书(使用x509选项),那么要求同时使用key选项指定证书请求里面的公钥相应的私钥以便对自签名根证书进行签名。
  • 如果使用了new选项或者newkey选项,那么in选项指定的证书请求文件将被忽略
  • in选项输入的证书请求的编码可以是PEM格式也可以是DER格式,由inform选项指定。
  • out选项指定了输出文件名,默认是标准输出。输出文件可以保存包括证书请求、自签名证书、编码公钥,以及由text、subject、modulus等选项指定的明文输出信息
  • 其中,证书请求和自签名证书的输出编码格式可以为DER编码或者PEM编码,由outform选项指定。
  • 公钥(如果使用了pubkey选项输出)的编码格式固定为PEM格式。
  • key选项指定了输入私钥的文件,该文件内的私钥编码格式由keyform指定。
  • 需要注意的是,如果keyform指定的编码格式是ENGINE格式,那么key指定的文件内容要根据具体的Engine接口而定,可能是一个编码公钥,也可能是一个字符串ID,甚至可能是毫无意义的内容。
  • 密钥类型可以是RSA私钥,也可以是DSA私钥。
  • keyout选项指定了新生成的私钥的输出保存文件,如果没有指定,那么默认情况下会从OpenSSL配置文件中的req字段的default_keyfile选项的参数中获取输出私钥文件名(openssl.cnf文件默认值是privkey.pem)。仅在使用了newkey或new选项导致生成新密钥对的时候该选项才有效,如果使用了已有的私钥(key选项指定),那么该选项就会被忽略。该选项输出的私钥编码格式固定为PEM编码。
  • 输出到keyout选项指定文件的私钥一般都会被加密保护,加密的算法是DES3的CBC模式。

输入和输出口令选项passin和passout

  • passin选项指定了读取key选项指定的私钥所需要的解密口令,输入口令的方式可以是多样的。如果没有使用该选项,而key选项指定的私钥又要求提供解密口令,那么指令会在指令行提示用户输入口令。
  • passout选项指定了使用keyout选项输出私钥时使用的加密口令。如果使用了nodes选项,则表示不对私钥进行加密,那么该选项指定的口令无效。如果该选项没有使用,并且输出了私钥,也没有使用nodes选项,那么指令会要求用户从指令行界面输入加密口令。

指令操作类型new,newkey,nodes和x509

  • new选项告诉指令执行生成新的证书请求操作,这时候,in选项指定的输入文件会被忽略。使用new选项后,如果没有使用key选项指定私钥用于生成证书请求,那么就会根据newkey选项的参数生成新的密钥对。
  • 默认情况下,如果指令既没有使用key选项,也没有使用newkey选项,那么指令就会生成一个RSA密钥,其长度由OpenSSL配置文件中req字段的default_bits选项的参数决定。newkey选项让指令生成一个新的密钥对,该选项只有在没有使用key选项的时候才有效。
  • newkey选项有两项功能:指定生成的密钥类型和密钥长度。
  • newkey选项的参数有如下两种形式:
  • rsa : numbits
  • dsa : file
  • 其中,rsa代表生成RSA密钥作为证书请求的密钥对,dsa则表示生成DSA密钥对作为证书请求的密钥对。
  • numbits表示要生成RSA密钥的长度,一般来说使用1024位作为普通证书请求是合适的。
  • file是存储了DSA密钥参数的文件名,DSA密钥的长度由该文件存储的DSA参数决定。
  • nodes选项告诉指令不对新生成的私钥进行加密保存,这样,passout选项将被简单忽略。如果没有使用nodes选项,并且生成了新的私钥,那么私钥输出到keyout指定的文件中时将会被以DES3的CBC模式加密。x509选项让指令生成一个自签名根证书而不是输出一个证书请求。
  • 所谓自签名根证书,就是指用一对密钥对的私钥对自己相应的公钥生成的证书请求进行签名而颁发证书,这样,证书申请人和签发人都是同一个,所以称为自签名根证书。如果根证书不是用于根CA,那么一般来说只有测试上的意义。在req指令中,既可以直接生成一个新的自签名根证书,也可以根据现有的证书请求和其相应私钥生成自签名根证书。如果是根据现有证书请求生成自签名根证书,那么一定要key选项提供相应的私钥指令才能执行成功。

属性设置选项digest,subj,days和set_serial

  • digest选项指定了生成证书请求或者自签名根证书时使用的信息摘要算法,该信息摘要算法一般在生成数字签名的时候使用
  • 需要注意的是,如果使用的是RSA算法,理论上除了DSS数字签名标准指定的信息摘要算法(ds1)不能使用以外,其他信息摘要算法都能够用于生成数字签名并且req指令也能够正确执行,但是,由于RIPEMD算法在标准中没有得到支持,很可能导致某些CA和应用程序不能正确使用。如果使用的密钥是DSA密钥,那么digest的任何设定都会被忽略,事实上,这时digest的值就固定为DSS规定的信息摘要算法。默认的digest算法是MD5。
  • subj选项直接从指令行指定了证书请求的主体名称,如果没有出示该选项,那么req指令将会根据配置文件特征名称字段的设定提示用户输入必要的信息,比如国家代号(通常是两个字符)、省份、单位名称,等等。如果使用subj选项,那么这些提示信息就不会再出现。
  • subj选项的参数格式如下:

  • 参数应该以“/”开头,每个值直接使用“/”作为分隔符号。“type* ”应该是OpenSSL内部支持的数据对象名称。比如下面是一个例子:

  • days选项设定了生成的自签名根证书的有效期,单位是天。该选项只有在使用了x509选项生成自签名根证书的时候才有效。默认值是30天。set_serial选项指定了生成的自签名根证书的序列号,默认情况下生成的自签名根证书序列号是0。该选项也只有在生成自签名根证书的时候有效。

配置文件选项config,extensions和reqexts

  • config选项指定了req指令在生成证书请求的时候使用OpenSSL配置文件,该文件的最好例子是openssl.cnf,一般来说,openssl.cnf也是默认的req指令配置文件。但是,如果在Windows环境中使用并且在编译的时候没有指定正确的路径,那么该默认配置文件很可能因为路径不正确而不能不到,这时候使用config选项就显得非常必要了。当然,config选项并非指定配置文件的唯一方法,你还可以使用OPENSSL_CONF或者SSLEAY_CONF环境变量指定默认的配置文件
  • extensions选项指定了生成自签名根证书的时候使用的扩展字段,其参数为OpenSSL配置文件中某个字段名(比如opensl.cnf文件中的v3_ca字段)。该字段一般规定了一些证书的扩展项信息,比如证书的用途,是否能够作为CA证书等性质
  • reqexts选项指定了生成证书请求时使用的扩展字段,该字段参数也是配置文件中的某个字段名,比如openssl.cnf文件中的v3_req字段,该字段也是证书请求中设置的要求申请的证书的一些使用限制信息。其内容跟证书扩展项内容基本一致。extensions选项和reqexts选项使得在同一个配置文件中可以存在多个不同的字段用于生成不同用途和目的的证书,比如,申请一个CA证书和用户证书的证书请求扩展字段设置是不一样的,那么可以在配置文件中将两种不同的证书请求设置分别写成两个不同的字段,在生成证书请求的时候根据需要使用reqexts选项指定不同的字段即可达到不同的目的。

属性格式化选项asn1-kludge,newhdr和utf8

  • 一般情况下,如果证书请求的某个属性没有填写,那么对应的证书请求字段会填写一个空的值。
  • 但是某些不完全标准的CA不能正确处理这些空值,它们的要求是:如果没有填写任何值,那么该属性字段就不应该出现在证书请求中。
  • 对于这些CA,你可能就需要使用asn1-kludge选项实现这个目的(与属性相对应的字段为空就不出现在证书请求中)
  • newhdr选项使用后将会在输出的PEM编码的证书请求开始和结束行增加“NEW”标记字符串,这是为了跟Netscape和其他一些证书服务器兼容设置的选项。使用newhdr和不用newhdr选项的证书请求格式如下。

  • utf8选项使用之后,将对输入的信息采用UTF8编码,而不是默认的ASCI编码。UTF8编码对于中文来说具有很重要的作用。

engine选项

  • engine选项指定后,所有指定Engine支持的操作都将使用Engine指定的加密库或者硬件设备进行,而不再是使用OpenSSL默认的算法库。对于req指令来说,可能使用Engine设备的操作包括RSA或者DSA密钥产生、签名时使用的信息摘要算法、签名时使用的私钥加密算法、签名验证操作的公钥解密操作、随机数产生和对私钥进行加密的DES3算法。如果engine选项指定了有效的Engine设备,那么指令中任何该Engine设备支持的上述操作都会使用Engine设备的操作流程而不再使用OpenSSL算法库本身提供的函数。

输出内容选项text,reqopt,pubkey,noout和subject

  • text选项让指令输出证书请求或者自签名根证书内容的明文解析,默认情况下,它将输出所有可能输出的内容
  • 但是如果使用了reqopt选项,其输出内容就取决于reqopt选项。
  • reqopt选项用于指定text选项输出的内容,其参数可以是多个,每个之间使用“,”作为连接符号。
  • reqopt支持的参数如表所示。

  • 对于证书请求来说,上表中的很多内容没有,对于这种情况,指令会自然忽略,相关的参数也就不会产生任何作用。
  • reqopt选项只有在跟text选项一起使用的时候才有效
  • 例如我们要使输出自签名证书的文本信息不包含序列号和公钥信息,则可以使用下面的指令:

  • pubkey选项使用后,指令将会输出PEM编码的公钥到out选项指定的文件中。默认情况下只输出私钥到keyout指定的文件,并不输出公钥。
  • noout选项使用后,指令将不会输出编码的证书请求或者自签名根证书到out选项指定的文件中,该选项一般用来测试指令或者查看证书请求的信息。
  • subject选项告诉指令输出主体名信息,即使已经使用text选项输出了主体名信息,该选项的启用也会让指令重复输出一遍主体名信息。

输出字符编码选项nameopt

  • nameopt选项指定了如何显示主体名称和签发者名称,主要用于显示名称中不同编码的内容,比如UTF8编码等。如果没有使用该选项,那么默认使用的是“oneline”参数。该选项可以同时使用多个参数,每个参数之间使用“,”作为连接符。此外,每个参数之前还可以使用“-”表示不使用该参数定义的显示方式。
  • 如表所述是nameopt选项支持的所有参数。

  • 需要注意的是,nameopt选项只影响使用text和subject选项输出的主体名称和签发者名称的显示方式,对其他项目的显示方式没有影响。上述的功能对于正确显示中文信息来说具有很重要的意义。前面说过,可以同时使用多个参数,下面是一个例子:

  • 上述指令指定在显示自签名证书的主体名称和签发者名称时,使用单行显示方式,但是禁止在显示之前进行UTF8格式的转换,并且域名称使用长名称进行显示。

证书请求数字签名验证选项verify

  • 使用verify选项的指令将对证书请求的数字签名进行验证操作,并给出失败或者成功的提示信息。其验证的过程是从证书请求里面提取公钥,然后使用该公钥对证书请求的数字签名进行验证。

其他选项rand,batch和verbose

  • rand选项指定了生成密钥对或者其他一些操作需要的随机数种子文件。如果没有使用rand选项,指令会从其他可能得到的资源取得随机数种子数据。
  • 使用batch选项将不再提示用户输入生成证书请求需要的用户信息,而是直接从OpenSSL配置文件特征名称字段读取默认值,如果没有默认值,则不填写该值域。一般来说,在你做测试的时候使用该选项会提高效率。
  • verbose选项让指令输出执行的各个操作的详细信息,一般来说,该选项也仅对调试程序有意义。

生成证书密钥

证书请求中使用RSA密钥

  • RSA密钥是目前证书中最经常使用的密钥类型,这一部分是因为其既可以支持密钥交换,又可以支持数字签名的特性;
  • 更重要的是RSA算法是一种经过充分考验和密码分析的算法,其安全性得到了公认。在使用req指令生成证书请求时,我们可以采用两种方法生成RSA密钥对:一种是使用genrsa指令预先生成密钥对,一种是直接在req指令中生成密钥对。从本质上来说,这两种方法没有区别,但是,使用第一种方式能够更灵活地处理密钥的保存和格式等问题
  • 我们首先看下面的指令,它使用req指令直接生成了一个新的1024位RSA密钥用于新的证书请求中:

  • 上述指令对生成的RSA私钥进行了加密,加密的算法自己是没有选择余地的,只能是DES3-CBC模式,当然,你可以使用rsa指令对密钥使用的加密方法和口令进行重新的更改。此外,私钥输出的编码格式也没有选择的余地,只能是PEM编码。这些限制可能很多时候不能满足你的要求。
  • 为了避免上面这些限制,你可以使用genrsa指令先生成需要的RSA密钥对,然后再使用req指令生成证书请求。事实上,在实际应用中,你的RSA密钥对甚至可能不是使用OpenSSL的指令工具生成的,但这没有关系,只要你的密钥封装格式是req指令中keyform选项支持的,那么就能够使用req指令生成证书请求。下面我们来看怎么使用genrsa指令和req指令生成一个证书请求。虽然说DES3-CBC方式的安全性一般还是值得信赖的,但我们更愿意使用256位的AES算法保护我们的RSA私钥,毕竟对于私钥来说,怎么提高它的安全性都不为过。
  • 显然,req指令满足不了我们的要求,那么可以使用genrsa指令:

证书请求中使用DSA密钥

  • DSA密钥是专门用于数字签名的密钥,当你要申请一个用于数字签名的证书的时候就可能需要使用这种类型的密钥。跟RSA密钥产生不同,DSA密钥一般通过其预先生成的DSA密钥参数来生成DSA密钥。req指令提供了根据DSA密钥参数生成DSA密钥的功能,而DSA密钥的长度则由给定的DSA密钥参数决定。当然,你也可以根据给定的DSA密钥对生成证书请求。下面我们介绍利用req指令本身生成DSA密钥的功能。由于req指令要求输入一组DSA密钥参数来生成DSA密钥,所以我们必须首先使用dsaparam指令生成DSA密钥参数。
  • 需要注意的是,req指令只能接受PEM编码的DSA密钥参数
  • 首先生成DSA密钥参数的指令如下:

  • 跟使用req指令生成RSA密钥对相同的是,输出DSA私钥的加密算法只能是DES3-CBC模式,编码方式也只能是PEM方式。所以为了灵活和方便,你可能愿意使用gendsa指令来生成DSA密钥,然后再使用req指令生成证书请求文件。首先我们利用刚才生成的DSA密钥参数文件生成一对DSA密钥:

  • 再次强调,上面我们在生成RSA或者DSA密钥对的时候,都只输出了私钥文件,这是因为私钥文件结构中已经包含了相应的公钥参数,req指令使用私钥的时候,事实上主要是从其中提取出相应的公钥,并封装在PKCS#10的证书请求结构中,然后采用私钥对整个证书请求结构签名从而完成操作

谁来生成密钥对

  • 如果私钥由用户本地生成,使用其公钥加密数据,如果用户消失会给组织带来巨大的危险。考虑到这点,为了方便管理,通常就由CA或者RA来生成用户的密钥对,并在发放证书的时候将证书和密钥对一起发送给用户。但这显然违背了私钥是唯一被主人拥有的假设,这样你可能觉得非常没有安全感,因为掌握备份密钥库的人可能随时可以查看你的任何资料和通信内容,但是你没有任何办法
  • 对于用于数字签名的证书来说情况会好一点,因为数字签名不需要对整个文件进行加密,它不存在数据恢复的问题。即便私钥丢失或者破坏了,也只是不能使用它继续签名其他文件而已,换一个就是了。所以用于数字签名的密钥对不需要备份功能,一般可以由用户自己产生。从法律角度而不是保密角度来看,数字签名的唯一性显得尤为重要。
  • 由于上述的这些原因,现在很多系统都使用所谓双证书的概念,即一个证书用于密钥交换,一个证书用于数字签名用于密钥交换的证书其密钥对一般由CA或者RA代替用户产生;而用于数字签名的证书的密钥对则由用户自己产生。事实上,这样的做法只是在法律上得到了保证,而数据保密性能则很值得怀疑,尤其是个人的隐私问题。具体到技术上,如果采用的是用户自身生成密钥对,那么req指令的功能应该由用户来使用。但是如果是CA或者RA生成密钥对,req指令跟用户基本就没有关系了,事实上这时候req指令的功能应该由RA或者CA执行,而用户只要简单地把自己的信息交给RA或者CA就可以了。但是,CA真的那么值得信任?

在证书中添加扩展项

  • 要真正用好req指令提供的功能,仅仅了解req指令的选项和参数是不够的,还需要对req指令所依赖的OpenSSL配置文件中的req指令相关字段有比较深入的了解。一下子要全部了解是不可能的,使用OpenSSL配置文件中的证书请求相关字段实现一些扩展的功能。首先我们看看怎么在证书请求中增加一个自己定义的扩展项。在某些特殊情况下,可能需要在证书中扩展一些标记以便实现一些特定的功能,比如,你可能需要在给你公司员工发放的证书中增加一项权限的功能,这可能给会给管理带来很大的方便,尤其对于有多个服务器的分布式系统中,这种证书尤其有用。下面我们就通过往证书的特征名称字段中添加一个扩展的字段实现存取用户的权限信息
  • 首先请打开OpenSSL默认的配置文件opensl.cnf,然后确保其中的下列语句没有被注释掉:

  • 上面定义了一个新的OID对象,其简短名称和长名称都是UserRights,而OID则为2.5.4.255。下面,我们就要在证书请求的特征名称字段添加我们新增加的这个OID对象,使得证书主体名称中能够增加一项代表用户权限的值域。
  • 为了使得管理方便,我们限定该项的值只能是两个字符,默认的值是“US”(User),表示普通用户权限。
  • 下面是往req_distinguished_name字段添加的语句:

  • 设置完上面这些内容,我们就可以使用这个配置文件作为req指令的配置文件,进行新证书请求的签发。你会发现在生成证书请求时提示输入信息中多了一项提示内容,即“UserRights”选项,用户就可以根据自己对不同权限的命名填写内容了。
  • 如果你用text选项则显示的证书请求主体名称形式如下:

  • 如果证书应用的系统是一个分布式的系统,那么这些选项对于分布式的权限控制等会产生非常大的好处。当然,要在最后生成的证书中增加这些扩展项,CA的配置文件相应的一些选项也需要做一些更改

申请用户证书

  • 证书按照其在证书链中的位置分类,一般可以分为两种:终端用户证书和CA证书。所谓CA证书,是指该证书可以用于签发别的用户证书,也就是说,它可以有下级的证书终端用户证书则用于具体应用程序或协议中,它不能用来签发别的证书,在证书链中,它处于最末端
  • 对于一般用户来说,申请的证书都是终端用户证书。对于生成证书请求的req指令来说,生成的证书请求是用于申请一个终端用户证书还是CA证书是由OpenSSL配置文件的证书请求X.509v3扩展项字段来决定的,opensl.cnf文件中的默认字段名是req_v3。
  • 为了使req_v3扩展字段生效,首先必须确保配置文件req字段中的下面语句没有被注释掉:

  • 接着,我们修改v3_req字段中的basicConstraints选项为下面的形式:

  • 然后保存,利用这个配置文件作为req指令的配置文件,其生成的证书请求就是一个申请终端用户证书的证书请求,如果你使用text选项输出明文信息,你会发现在“RequestedExtensions”部分出现下面的信息:

  • 上述的CA:FALSE值即表示该证书请求不是CA证书请求,而是普通的终端用户证书请求。当然,证书请求的这个扩展字段最后能起到什么作用,还得取决于签发证书的CA的具体策略。
  • 生成一个CA证书请求而不是普通的终端用户证书请求,修改如下

  • 然后保存,利用这个配置文件作为req指令的配置文件,其生成的证书请求就是一个申请CA证书的证书请求,如果你使用text选项输出明文信息,你会发现在“RequestedExtensions”部分出现下面的信息:

  • 上述的CA:TRUE值即表示该证书请求是CA证书请求。同样,证书请求的这个扩展字段最后能起到什么作用,还得取决于签发证书的上级CA的具体策略。

建立CA

  • CA是集技术和管理于一体的庞大机构

CA服务器的基本功能

  • CA服务器是一个应用程序,它从技术上实现了符合PKI和X.509等相关标准的证书签发和管理功能。
  • 总的来说,其基本功能应该包括以下几个方面:接受申请证书的请求、审核证书请求、签发证书、发布证书、吊销证书、生成和发布证书吊销列表(CRL)及证书库的管理

接受证书请求

  • 这是首先必备的功能,一个CA应用程序必须能够从各种途径接受用户的证书请求,至少需要一个这样的途径和接口。一般来说,证书请求的提交归纳起来有三种:在线实时提交、在线非实时提交和本地提交
  • 在线实时提交是指提供一个应用接口(一般是个服务端口),用户可以通过支持CA服务器规定的证书请求协议发送证书请求信息,CA服务器能够实时响应提交的请求并作出是否提交成功的回复,如果CA服务器是自动签发证书并且你的申请符合设定的条件,用户就有可能快速得到签发好的证书。这种方式的实现一般采用C/S的模式,需要客户端软件的支持
  • 在线非实时提交一般通过Web方式实现,用户可以通过Web页面把证书请求提交到服务器指定的一个目录或者数据库中,然后,CA服务器程序或其管理员可以定期或者不定期检测数据库,如果发现有新的证书请求,则起动证书请求审核和签发流程。这种方式的实现一般采用B/S结构
  • 本地提交方式即用户到CA服务器所在地或者RA服务器所在地提交或填写自己的资料和申请证书的请求,然后交给CA服务器管理员处理。一般来说,如果你的CA实现的是密钥对由用户自己生成的方式,那么一般接受的证书请求都是符合PKCS#10标准的。如果不是这样,即CA服务器号称可以替代用户生成“安全”的密钥对的方式,那么接受的资料很可能就是一些文本资料,至于具体的格式,就根据自己的需要决定了。
  • 上述三种接受证书请求的模式各有其不同的应用环境。在线实时接受申请模式,实现起来工作量会比较大,并且需要客户端软件的支持;但是也有好处,在某些必须使用数字证书的客户端软件中可以集成证书自动申请功能,这样就简化了用户使用客户端软件时候的配置操作。而基于Web方式的在线非实时提交方式实现起来显然比较容易。本地提交方式能够提供对用户身份进行严格确认的机会,这对于证书的安全应用能够提供很好的保障。

审核证书请求

  • 很难说审核证书请求仅仅是一个技术上的问题,事实上,审核过程要求得更多的是管理的策略。当然,你可以通过CA服务器程序将你的管理策略实现,比如必须要求用户提交的证书请求中国家名称跟规定的相一致,等等。当然,仅仅这些是不够的,严肃对待一个证书请求的态度是验证严格审核其各个条目的信息,并在有必要的时候跟用户本人进行核实。这就至少要求CA服务器能够向管理员显示出一个证书请求的所有详细内容,这就是CA服务器对审核证书请求的基本要求,当然,CA服务器可以实现

签发证书

  • 如果通过了证书请求的审核过程,那么签发证书就是CA服务器马上要执行的操作。该操作实际上是将证书请求的信息和CA服务器自己的部分信息按照X.509的标准进行格式化,然后CA服务器使用自己的私钥对所有这些信息进行数字签名,然后形成一个X.509标准的证书
  • 接着,当然要将证书保存在证书库中,并对证书库进行更新。

发布证书

  • 证书签发好后,就需要将证书发布出去。发布对象有两种:一种是申请证书的用户本人,必须让他能够及时获得自己的证书;一种是其他用户,可以向他们提供获得所有用户证书的途径
  • 一般来说,可以通过Web方式或LDAP目录发布证书,当然,对于申请证书的用户本人,也可以通过Mail或其他途径发送。在某些情况下,比如是CA服务器生成证书密钥对的情况下,还要考虑私钥的传输问题,这一般来说需要高度考虑其安全性,最好采用硬件设备来传送私钥。如果非要考虑用软件的方式来保存私钥,那么一般需要对私钥进行加密保存,最简单的方式,就是将证书和私钥一起封装成PKCS#12的证书然后通过可能的途径发送给用户本人。

吊销证书

  • 有些情况下需要取消一个没有过期的证书的有效性,那么这就需要CA服务器执行吊销该证书的操作,这是确保整个CA证书域安全性的必备条件。吊销证书的操作一般就是更新证书数据库,发布新的CRL等,目的就是为了尽可能让所有用户都知道该证书已经无效

生成和发布CRL

  • 虽然所有已经吊销的证书在CA有效的证书数据库中都已经不存在,但是用户在很多时候并不能实时地访问和查询CA数据库,当然也就不能就此终止所有基于证书的应用服务。这时候就需要利用CA服务器发布的证书吊销列表(CRL)来进行证书的验证。CA服务器必须能够定期更新和发布CRL,以便用户能够获得准确的CRL信息。

证书库管理

  • CA服务器的证书库存储了CA签发的所有有效证书,有时候,甚至也包括无效的证书和证书相应的私钥,这就要求CA服务器能够对证书进行有效的管理。例如对证书状态的更新,无效和过期的证书应该删除或者做相应的标记状态,等等.

CA服务器的基本要素

  • 要建立和运行一个CA服务器,那么至少应该具备以下一些要素:

    • 一个具备CA应用程序;
    • 一个CA证书和一个其相应的私钥,可能是自签名的根证书,也可能是向另一个CA申请的证书;
    • 证书数据库,用于存储证书(有时候还包括私钥)。
  • CA应用程序的选择有很多,如果你不介意微软的神秘代码可能隐含的安全性问题,那么可以用Windows系统的CA服务器程序。你还可以选择OpenCA提供的CA服务器,当然,它事实上就是OpenSSL的封装版本。
  • CA证书和私钥的产生根据不同的应用而定,如果你的CA服务器是自成体系,并不需要一个上级CA的支持,那么可以使用OpenSSL的req指令生成一个自签名根证书作为CA服务器的证书即可。
  • 如果你的CA服务器是上级CA的一个下级CA,那么就需要生成一个CA证书请求并发送给上级CA,然后等待上级CA签发你的CA证书。
  • 证书数据库的选择是多样的,你可以使用任何像SQLServer,Oracle和MySql这样的数据库,也可以使用自定义的文本数据库,甚至可以使用特定的目录结构等。这需要根据自己的需要而定。如果你选择现有的CA应用程序,你可能没有这么多选择,比如OpenSSL的ca指令,就仅仅使用文本数据库。具备了上述这些基本的要素,你的CA服务器就可以启动并运行签发证书的服务了。

OpenSSL模拟CA服务器架构

  • 默认的CA目录结构上面介绍了各种CA应用服务器,本章节的目的只有一个:就是介绍基于OpenSSL的ca指令的证书服务器。
  • 当然,并非仅仅想告诉你OpenSSL的CA服务器是如何配置和使用的,而是希望通过上面的介绍,让你深刻理解CA服务器的工作流程和操作过程。OpenSSL的ca指令是一个模拟的CA服务器程序,它实现了CA服务器的基本功能。
  • ca指令的正常运行依赖于一个目录结构和一个OpenSSL配置文件,OpenSSL配置文件我们已经相对熟悉了,本节主要对这个目录结构进行介绍。
  • 如图所示展现了整个CA目录的结构。图中,粗线条框显示的是目录,而细线条框显示的则是文件。图中,certs和crl目录是使用ca.pl程序创建生成的,目前来说,ca指令并没有使用这两个目录,可以忽略
  • newcerts目录存放新签发的证书文件,证书文件名是序列号,后缀名是pem,即输出的证书默认都是PEM编码的。比如签发的证书如果其序列号是01,那么其保存在newcerts目录的证书文件名就是“01.pem”。
  • private目录目前仅对于存放CA证书相应的私钥文件有意义,其默认私钥文件名为cakey.pem。每次使用CA指令如果没有指定特别的密钥,那么就会使用该密钥签发证书。
  • demoCA根目录下的cacert.pem文件就是PEM编码的CA证书文件,里面保存了CA的证书。如果没有使用ca指令的选项指定别的证书文件,那么每次使用ca指令签发证书的时候就使用该证书
  • demoCA根目录下的index.txt文件是ca指令相应的文本证书数据库,index.txt文件保存了已经签发的证书的信息和状态
  • demoCA根目录下的serial文件是ca指令决定签发证书的序列号所依赖的文件,其格式和内容请参考第6章相关内容。在使用ca指令签发证书后,你还会发现在根目录下还会产生serial.old和index.txt.old文件,这是上次签发证书时serial和index.txt文件的备份文件,一般来说不用理会它们。

OpenSSL配置文件

  • 事实上,上面所说的所有目录结构都是可以改变的,它们都由OpenSSL配置文件的CA字段所决定,让我们来看看默认的opensl.cnf文件的这些相关配置选项:

  • 如果你愿意,你可以通过更改上述这些选项的值来更改ca指令使用的目录结构和文件。事实上,在使用ca指令时,指定特定的OpenSSL配置文件也是必备的条件之一。为了方便起见,本书后面的章节在介绍ca指令时,都以默认的目录结构为准

建立基于OpenSSL的CA服务器

手动创建一个CA目录结构

  • 假设我们已经拥有了ca指令程序和配置文件,为了使ca指令能够正确运行,首先就是按前面介绍的CA目录结构的要求创建这样一个CA目录结构和相应的文件。如果你愿意自己来一步一步建立这么一个目录,那么可以按照下面的步骤进行。

    • 1 在opensl可执行程序(Windows下是opensl.exe)所在目录下创建一个名为“demoCA”的目录。
    • 2 在demoCA目录下创建newcerts,private,crl和certs子目录。
    • 3 在demoCA目录下创建一个空的名为index.txt的文本文件。
    • 4 在demoCA目录下创建一个空的名为serial的文件,用文本编辑器打开(vi或者记事本),在文件中填入01,保存退出。
    • 5 将CA证书文件转换成PEM格式,复制到demoCA根目录下,并重新命名为cacert.pem。
    • 6 将CA私钥文件转换成PEM格式,复制到demoCA/private目录下,并重新命名为cakey.pem。
  • 经过上述两个步骤,你就建立了一个ca程序能够使用的CA目录结构。如果你的CA使用上级CA签发的证书,那么你可能需要将证书和私钥文件转换成PEM编码的格式以完成第5和第6步的配置
  • 如果你使用的是自签名根证书,那么可以使用下面的req指令生成一个自签名根证书和私钥:

自动创建一个CA目录结构

  • 手动创建一个CA目录的过程是很烦琐的,OpenSSL开发者能够理解大家的这种心情,提供了一个基于Perl的脚本帮助大家自动创建一个CA目录结构
  • 前提是,你正确安装了Perl软件。首先你将OpenSSL的apps目录下的ca.pl文件复制到你想要放置CA目录结构的目录
  • 接着,在指令行界面进入到ca.pl所在的目录,运行下面的指令:

证书配置文件选项config,name,extensions,extfile和policy

  • ca指令跟OpenSSL的配置文件关系非常紧密,ca指令的证书请求值域匹配策略、扩展项参数及其他默认的参数设置都是依赖于OpenSSL配置文件的相关字段
  • ca指令除了会自动寻找和使用默认的OpenSSL配置文件和字段外,还运行用户在指令中指定的配置文件及特定的字段
  • config选项指定将要使用的配置文件。在默认情况下,如果不使用config选项,ca指令首先会寻找环境变量OPENSSL_CONF或者SSLEAY_CONF定义的文件名,如果这两个环境变量都没有定义,那么就使用OpenSSL安装时默认的路径。这个默认的路径通常情况下是“/usr/local/sl/opensl.cnf”,当然,你可以在安装OpenSSL的时候使用configure脚本指令更改这个默认的安装目录
  • 比如通常在Windows下编译完OpenSSL后,可执行文件openssl.exe通常在目录out32dll下,而其配置文件则在apps目录下,为了在out32dll目录下能够正确使用OpenSSL的ca指令,可以使用config选项:

  • 在默认的情况下,ca指令使用的CA主配置字段由配置文件中ca字段的default_ca选项的参数值决定。其形式如:

  • 当然,某些情况下你可能想使用在同一配置文件下(由config选项指定或默认得到的配置文件值)另外一个字段作为CA的主配置字段,那么name选项就可以实现你这个目的。name选项的参数是字段名,比如上面的“CA_default”,指定的字段名应该是已经在使用的配置文件中定义好了的。
  • 例如在下面的名为openssl.cnf的配置文件中,定义了一个新的名为My_CA的CA主配置字段:

  • policy选项让指令使用其参数指定的字段名作为签发证书请求时的匹配策略字段,其参数是配置文件中定义的一个字段名称。事实上,在OpenSSL提供的openssl.cnf文件中,就已经定义了两个匹配策略字段:policy_match和policy_anything
  • 默认情况下,ca指令通过CA主配置字段的下列选项采用policy_match字段作为匹配策略:

  • 如果你不想更改openssl.cnf,但想使用policy_anything字段作为匹配策略字段,则可以使用下面的指令实现你的要求:

  • 假设你的CA需要管理不同的用户群,而每个用户群需要自己特定的匹配策略,比如每个用户群组织名称都不同但是要求同一用户群的用户组织名称必须相同,那么就可以在配置文件中预先定义不同的匹配策略字段,然后根据具体用户使用不同的匹配策略字段来签发证书。policy选项在这种情况下可以大显身手。
  • extensions和extfile两个选项用来选定签发证书时候使用的X.509v3扩展项定义字段。extensions的参数是字段名,用来选定配置文件中用于定义X.509v3扩展项的特定字段,默认的字段所在文件跟config选项选定的配置文件或者默认的配置文件是同一个文件。
  • 但是某些情况下你可能希望使用一个专用的文件用来保存X.509v3扩展项信息,那么这时候可以使用extfile选项指定这个文件。如果仅仅使用了extfile选项指定额外的X.509v3扩展项配置文件,而没有使用extensions选项,那么具体使用extfile指定的文件中那个字段,由默认配置文件中CA主配置字段的x509_extensions选项决定,类似如下的格式:

  • 如果extensions和extfile两个选项都没有使用,那么默认的情况下就会使用config选项指定或者默认配置文件的CA主配置字段中x509_extensions选项参数指定的字段。例如在opensl.cnf文件中指定的就是上面所描述的usr_cert字段。假设我们在my_con.fig.cnf文件中定义了一个X.509v3扩展项字段如下:

  • 使用好extensions和extfile两个选项能够使ca指令的运用更加灵活。例如,你管理的用户可能其证书用途各不相同,这可以通过在X.509v3的扩展项中来定义。为了方便签发各种不同用途的证书,如果你不使用extensions选项,或许你需要不断烦琐地更改配置文件的X.509v3扩展项字段(默认是usr_cert),相信这样下去,很快你就会产生辞职的想法。不过,如果你会使用extensions选项,事情就不一样了,你可以根据需要预先编辑好几个不同的x509_v3扩展项字段,然后根据签发证书的需要使用extensions和extfile选项选用不同的字段,从而实现不同权限的证书的签发。需要注意的是,如果你提供了有效的X.509v3扩展项字段(不管通过指令选项提供还是配置文件选项提供),即便字段是空的,指令也会生成一个X.509v3版本的证书。但是如果没有提供有效的X.509v3扩展项,那么就生成X.509v1证书。

输入和输出选项in,infiles,out和outdir

  • in选项的参数是一个可以包含路径的文件名,该文件保存的应该是一个PEM编码的PKCS#10格式的证书请求。事实上,in选项仅用于证书请求的输入,而不能输入其他类型的内容,也就是说,如果你使用了in选项,那么表示你要执行的操作就是签发一个证书
  • infiles选项的参数是一系列包含PEM编码证书请求的文件,跟in选项唯一不同的是,它可以一下子输入多个证书请求文件,而不是一个。该选项总是作为指令的最后一个选项,其后面的所有参数都被认为是证书请求文件。
  • out选项指定了输出签发好的证书或者新生成的CRL的文件。此外,如果没有使用notext选项,那么证书的明文信息也会输出到out选项指定的文件中,这在大多数Windows平台上会导致证书文件不能被正确解释,解决的最简单办法是使用notext选项禁止这些明文信息的输出。不过,在较新的Windows系统,如WindowsServer2003,这个问题得到了解决。
  • out选项指定的文件中输出的证书或者CRL都是PEM编码的
  • outdir选项指定了新生成证书的输出目录,在默认情况下,新生成证书总是输出到newcerts目录,并且是以序列号加“pem”后缀成为一个完整的证书文件名。这些证书都采用了PEM编码。如果使用outdir选项指定了新的目录,那么新生成的证书文件就会输出到这个新指定的目录。需要注意的是,不管out选项是否给出,都不会对输出到outdir或者其默认目录的证书文件产生影响

特殊的证书请求输入选项s_cert和spkac

  • 前面介绍的两种证书请求的输入方式,即使用in或者infiles选项。它们的区别是输入单个证书请求文件还是输入多个证书请求文件。而它们的共同点则是输入的都是PEM编码的符合PKCS#10标准的证书请求
  • OpenSSL还提供了其他两种输入证书请求的方法,即ss_cert选项和spkac选项支持的方法。
  • ss_cert选项允许用户输入一个自签名的证书作为申请证书的证书请求,ca指令将会从这个自签名证书中提取用户信息和公钥用于签发最后的用户证书。也就是说,你可以使用req指令生成一个自签名证书而不是证书请求,然后用这个自签名证书来向上级CA提供信息申请你的证书。
  • spkac选项允许用户输入一个SPKAC格式的文件作为申请证书请求的资料,spkac是Netscape规定的一种格式,该格式包含了一个签名的公钥和其他附加用户信息。需要注意的是,使用spkac作为证书请求输入时,输出的证书编码是DER格式,而不是PEM格式的。

证书有效期选项

  • startdate,days和enddate这三个都是用来设置证书有效日期的选项,分别是设置证书的生效时间、证书的到期时间及有效时间
  • startdate设置证书的生效时间,其参数格式是“YYMMDDHHMMSSZ”,每两位代表一个时间变量,分别是“年月日时分秒”。比如要定义签发的证书生效时间是2003年9月10日12时24分36秒(格林威治时间),那么startdate选项的参数就应该为“030910122436Z”。证书生效时间除了可以在ca指令的startdate选项指定外,也可以在配置文件的CA主配置字段的default_startdate选项指定,其参数格式跟startdate选项参数格式一致。如果没有设置startdate选项,也没有在配置文件中定义default_startdate选项,那么证书生效时间就是签发证书的时间
  • days选项设置证书的有效天数。所谓有效天数,也就是从证书生效的时间到证书到期的时间之间的天数。
  • enddate选项的参数格式跟startdate选项一样,用来设置证书的到期时间。同样,你也可以通过配置文件CA主配置字段中的default_enddate选项设定证书到期时间。如果设置了enddate选项,那么days选项将会被自动忽略。如果没有设置证书到期时间,那么就会根据days选项设置的有效时间来决定证书到期时间。如果指令中也没有使用days选项,那么指令就会从CA主配置字段读取default_days选项的参数来决定证书有效期。

证书内容选项subj,preserveDN,noemailDN,md和msie_hack

  • 一般情况下,签发证书的时候,证书的主体名称(subjectname,也称为特征名称)由证书请求中的主体名称决定。不过,有时候用户自己填写的资料可能并不能让你这个挑剔的CA管理员满意,那么你可以使用subj选项重新填写用户的证书主体名称。
  • subj选项的参数格式应该如下:

  • 其中,“type*”必须是已经由OpenSSL内部定义或者在配置文件中定义了的数据对象。preserveDN选项使指令在签发证书的时候让证书主体名称内的各项内容顺序跟证书请求中的顺序保持一致。
  • 而在默认情况下,证书主体名称内的各个选项顺序是按照配置文件中的证书匹配策略字段的选项顺序进行排列的。这个选项对于老版本的IE证书管理器是必要的,而现在则显得很不必要了。
  • 一般来说,证书的主体名称里面可以包含E-mail项目,但是,因为E-mail可能是一个经常变动的项目,所以如果不把它放在证书主体名称中而是放在主体别名中会更好一点。noemailDN选项可以帮你做到这一点,当证书请求中有E-mail这一项,但是你不希望在证书主体名称中出现E-mail时,可以使用这个选项来去除。如果你还使用了证书主体别名,并使用了“email:move”或者“email:copy”策略,那么使用该选项后指令会自动将证书请求中的E-mail项目移动到证书主体别名中。
  • 缺少 md 和 msie_hack

CA证书和私钥选项cert,keyfile,keyform,passin和key

  • 在签发证书的时候,需要使用CA的证书和私钥对用户的证书请求进行签发证书操作。默认情况下,证书和私钥文件都是通过配置文件的CA主配置字段的certificate和private_key两个选项决定的。
  • 不过,OpenSSL的ca指令提供了cert和keyfile选项让用户能够选择另外的证书和私钥文件作为签发证书的CA证书和私钥文件。或许你很难想像这种特殊的需要,为什么不使用预先设置好的证书和私钥文件呢?但是,至少在测试的时候,我们需要这些灵活的选项。事实上,这些选项不仅仅可以用于测试,因为CA的指令不仅仅用于签发证书,还可以用于吊销证书和发布CRL,某些时候,发布CRL的角色跟CA的角色可以是不同的,即需要使用不同的证书来完成证书签发工作和生成CRL的工作,但是它们都使用同一个ca指令,所以这些选项就能派上用场了。cert选项的参数是一个可以包括路径的文件名,文件里面是一个PEM编码的X.509证书文件
  • keyfile选项的参数也是一个可以包括路径的文件名,不过,该文件里面可以包含的私钥格式就比证书文件丰富多了。目前来说,支持的编码格式包括PEM编码格式、DER编码格式、PKCS#12编码格式、Netscape编码格式、旧版本的IISSGC编码格式及ENGINE格式。当然,OpenSSL指令不能自动识别这些格式,必须使用keyform选项指定某种具体的格式
  • pasin选项给定了读取私钥文件的时候需要提供的口令,当然,跟我们所熟悉的一样,提供口令的方式可以是多样的,比如从指令直接输入、从环境变量获取或者从文件获取,等等。
  • key选项是一个老选项,其作用是直接从指令输入一个口令,其功能可以被“-pasinpass:”选项所替代。

证书吊销选项revoke,crl_reason,crl_hold,crl_compromise和crl_CA_compromise

  • revoke选项让你能够轻松地吊销一个证书,其参数就是你需要吊销的证书文件名,revoke选项吊销的证书应该是PEM编码的X.509证书。
  • 当然,仅仅这样吊销可能还满足不了你的管理需求,某些情况下,你甚至希望告诉所有用户为什么要吊销这个证书以证明你是正确的。那么,使用crl_reason选项吧,crl_reason选项的参数是CRLv2版规定的一些吊销理由
  • 如表所示。

  • 上述的吊销参数对大小写是不敏感的。如果在吊销操作的时候使用了这些吊销参数,那么生成的CRL就是v2版本的,如果所有吊销证书操作都没有使用任何参数,那么生成的CRL将是v1版本的。
  • 当你希望使用certificateHold码作为吊销一个证书的理由时,还可以使用冻结指示代码扩展,这可以通过使用crl_hold参数来添加
  • 目前,crl_hold支持的参数包括holdInstructionNone,holdInstructionCalIsuer和holdInstructionReject
  • crl_hold选项使用后,设置证书吊销码为certificateHold,并且用其参数设置冻结指示代码扩展项。
  • crl_compromise选项使用后,将证书吊销原因设定为keyCompromise,其参数表示私钥泄密的时间。它的参数是符合“YYYYMMDDHHMMSSZ”格式的时间。其中“YYYY”代表4位的年份,而其他位跟startdate选项的参数代表的意义一样的。crl_CA_compromise选项使用后,将证书吊销原因设定为CACompromise,其参数表示私钥泄密的时间。它的参数格式跟crl_compromise格式一致。
  • 上述的crl_reason,crl_hold,crl_compromise和crl_CA_compromise只要同时使用一项即可,如果同时使用了多项,那么在指令中最靠后的一个将是有效的,而前面的都视为无效

CRL生成选项gencrl,crldays,crlhours和crlexts

  • 执行完证书吊销操作后,证书库中相应的证书记录会更新,但是,对于离线的应用验证程序而言,还是没有办法知道被吊销的证书的序列号。为了让所有证书用户及时得到吊销证书的消息,CA必须及时生成和发布CRL
  • gencrl选项用于生成一个CRL,并将生成的CRL使用PEM编码输出到out选项指定的文件,如果没有使用out选项,则输出到标准输出设备。为了保证CRL能及时反映证书库的更新信息,CRL也必须不断定期或者不定期更新,最好的方法就是,当发布一个CRL的时候,同时限定该CRL的有效期,那么到了有效期之后,用户就必须下载新的CRL来使用。CRL更新的间隔时间可以根据需要选择,如果是非常重要的证书应用系统,并且用户数量比较大,那么单位时间内执行吊销操作的可能性就大,这时候可以将CRL的更新时间设置得短一点。反之,如果系统用户数量不多,证书应用系统的安全性也不是要求特别高,那么更新时间可以设置得稍微长一点。
  • crldays和crlhours选项跟gencrl选项一起使用以设置CRL的更新时间。默认情况下,如果没有使用crldays选项或者crlhours选项,指令会从配置文件的CA主配置字段的default_crl_days或者default_crl_hours选项读取默认值。crldays以“天”为单位设置CRL的有效期,而crlhours则以小时为单位设置CRL有效期,这两个选项可以一起使用,比如你要设置CRL的有效期为5天12个小时,那么可以设置crldays的参数为5,而crlhours为12。crlexts指定了生成CRL的时候使用的扩展项定义字段,其参数为字段名称。CRL扩展项字段是在OpenSSL配置文件中定义的。如果定义了CRL扩展项字段,即便该字段是空的,生成的CRL也将是v2版本的。如果没有提供CRL扩展项字段,则将生成v1版的CRL。

证书管理选项status和updatedb

  • status选项用来查看证书库中指定证书的状态,比如是否有效、吊销或者过期等。该选项的参数是证书序列号。
  • updatedb选项用来更新文本数据库的证书状态,它主要用来更新证书库中已经过期的证书的状态信息。通常情况下,即便证书已经过了有效期,如果不使用这个选项,OpenSSL的ca指令也不会自动更新证书库中相应证书条目的状态,所以需要使用这个选 项来自动更新证书库的状态信息。

engine选项

  • engine选项告诉ca指令尽可能使用Engine设备提供的加密函数和算法替代OpenSSL本身的函数。对于ca指令来说,可能替代的算法包括:签名时使用的信息摘要算法、签名时使用的私钥加密算法、验证证书请求中的数字签名时使用的公钥解密算法、随机数函数及私钥数据。
  • engine选项对于使用硬件加密设备中的私钥作为CA的私钥具有重要的意义,因为硬件中的私钥一般是不能导出的,从而能够增加CA私钥的安全性。当然,这需要相应Engine接口的支持。

notext,batch和verbose选项

  • 使用ca指令签发完一个证书的时候,你是不是经常发现大部分版本的Windows都不能正确解释你的PEM编码的证书文件?事实上这是因为OpenSSL的ca指令在签发证书的时候,同时将证书的明文解析信息输出到了保存编码证书的文件前面,从而导致这些不怎么标准的Windows程序解码失败(WindowsServer2003已经解决了这个问题)。
  • 解决这个问题很简单,在签发证书的时候使用notext选项,那么指令就不会输出明文信息到证书文件。
  • 使用batch选项后ca指令以批处理方式工作,在这种方式下,ca指令不提示用户输入任何信息而直接签发所有输入的证书请求。
  • 使用verbose选项将会输出更详细的一些操作过程信息

例子

在证书中添加扩展项

  • 先前介绍了怎么在证书请求中增加自定义的扩展项。但是,证书请求中增加了扩展项,并不等于签发的证书就会自动增加扩展项。事实上,从严格意义上说,证书请求应该是用户生成的申请文件,也就是说,其所有内容基本上都是代表了用户的意愿,并不能由此推断CA的策略。所以,为了使证书中能够顺利增加扩展项信息,我们还需要在CA指令的配置文件上做一些工作。你可能已经可以想像得到,我们的证书扩展项工作同样需要在OpenSSL的配置文件中完成。首先,请确认你已经在OpenSSL配置文件opensl.cnf中增加了扩展项的OID,即以下信息:

  • 注意,如果证书请求指令(req)使用的配置文件跟证书签发指令(ca)使用的配置文件不相同,必须确保上面的信息在两个配置文件中都存在并且一致。
  • 下面,找到配置文件中的CA策略配置字段,如在openssl.cnf文件中是policy_match或者policy_anything字段,在其中增加新增扩展项:

  • 当然,跟其他DN字段信息一样,新增扩展项的匹配策略也可以根据CA的需要调整为optional或者match等。
  • 完成上面的配置之后,保存配置文件,并使用该配置文件签发证书,就可以生成增加了扩展项的证书。当然,上述配置方法使得扩展项信息是增加在证书主体名称中的。

签发用户证书

  • 先前介绍了怎么申请一个终端用户证书,即怎么使用OpenSSL的req指令生成一个终端用户证书请求。同样,签发什么类型的证书事实上是由CA决定的,也就是说,即便生成了一个有效的终端用户证书请求,但是如果接受申请的CA不签发终端用户证书,或者,甚至因为错误配置导致签发了CA证书,都是可能发生的。
  • 可以通过在OpenSSL配置文件中的X.509v3扩展项字段告诉ca指令签发用户证书。ca指令在使用默认的openssl.cnf作为配置文件的情况下,使用的X.509v3扩展项字段是user_cert字段
  • 在openssl.cnf文件中找到该字段,确保basicConstraints选项的参数如下: 证明颁发的是终端证书

  • 当然,默认情况下一般就是如此。使用该配置文件签发的证书就是一个终端用户证书。如果你使用的是自己定义的另外的X.509v3扩展字段,那么也只需要保证上述的basicConstraints选项值为CA:FALSE,就可以成功签发一个终端用户证书了。使用自定义的字段的方法就是在ca指令中使用extensions选项,当然,也可以通过修改配置文件中CA主配置字段的x509_extensions选项的值来实现。事实上,当OpenSSL的ca指令使用默认的openssl.cnf作为配置文件的时候,其签发的证书总是终端用户证书

签发下级CA证书

  • 如果你正在为一个大型的跨区域企业或者政府部门建立一个CA系统,那么你可能需要建立一个多级的CA体系,这就涉及签发下级CA证书的问题。从技术上来说,一个CA证书和一个用户证书并没有本质区别,它们的数据项是基本相同的,格式也是相同的,一个下级CA证书的合法性也是通过上级CA的数字签名来保证和证明的。事实上,区别普通终端用户证书和CA证书的唯一标记就是X.509v3扩展项字段中的选项basicConstraints。如果该选项值为CA:FALSE,则表示证书是普通的终端用户证书;如果该选项值是CA:TRUE,则表示该证书是CA证书。
  • 在OpenSSL的默认配置文件opensl.cnf文件中已经存在一个签发CA证书的X.509v3扩展字段v3_ca。
  • 将该字段的basicConstraints设置为如下格式:

  • 当然,你还可以使用自己定义的X.509v3扩展项字段,其使用方法是相同的。
  • 通过上面这些介绍,你就可以使用OpenSSL的指令顺利签发一个下级CA证书,从而建立整个证书域的分级管理,对于大型的企业或者机构来说,这非常方便

例子 建立多级CA

  • 在完成这些步骤的整个过程中,使用的OpenSSL指令只有req和ca两个,并且参数形式基本是相同的。此外,还需要配置OpenSSL的配置文件。

建立rootCA

  • 建立RootCA技术上抽象的任务有三部分:建立一个CA目录结构、生成一个自签名根证书和修改配置文件。
  • 为了管理方便,我们选定RootCA的根目录在C盘。首先,在C盘根目录创建一个名为“RootCA”的目录。从编译好的OpenSSL目录中复制“openssl.exe”程序,“opensl.cnf”和ca.pl文件到“C:\RootCA”目录下。
  • 打开Windows的指令行界面,进入到“C:\RootCA”目录,执行下面的指令:

  • 根据其提示步骤完成整个操作流程,就可以成功在C:\RootCA目录下创建一个demoCA目录。执行ca.pl脚本指令的过程中,会提示产生自签名的根证书,可以忽略。下面我们使用req指令来生成一个使用2048位密钥的自签名根证书作为RootCA的证书。
  • 首先执行如下指令启动OpenSSL.exe程序进入OpenSSL的运行环境。

  • 然后,将文件rootca_cert.pem重命名为cacert.pem,复制到“C:\RootCA\demo.CA”目录下取代原来的文件;将文件rootca_key.pem重命名为cakey.pem,复制到“C:\RootCA\demoCA\private”目录下取代原来的同名文件。这就完成了RootCA证书和其相应私钥的设置。
  • 为了使RootCA能够同时签发普通用户证书和下级CA证书,很多时候我们还需要对OpenSSL配置文件(C:\RootCA\opensl.cnf)进行一些配置,但是,由于OpenSSL默认的配置文件本身已经具有了两个不同的X.509v3扩展字段用于签发用户证书(usr_cert)和签发CA证书(v3_ca),所以在这里不需要再做更多的配置。当然,在实际的应用中,可能还需要对其他一些扩展项和匹配策略等配置信息进行修改。到此为止,我们已经成功建立了一个RootCA,是不是很简单?

建立SubCA

  • SubCA是RootCA的下级CA,它的证书的合法性需要由RootCA签名来证明。建立一个SubCA的简要步骤如下

  • SubCA跟RootCA是两个不同的CA,在实际情况下,它们一般不在同一个计算机内运行,但是,大家都应该明白,这里只是一个演示操作,所以我们选定在C盘根目录下建立一个名为“SubCA”的目录作为SubCA的主目录。然后,跟建立RootCA一样,从编译好的OpenSSL目录中复制“opensl.exe”、“opensl.cnf”和ca.pl文件到C:\SubCA目录下。
  • 打开Windows的指令行界面,进入到C:\SubCA目录,执行下面的指令:

  • 根据其提示步骤完成整个操作流程,就可以成功在“C:\SubCA”目录下创建一个demoCA目录。这样,SubCA的目录结构就建好了,但是SubCA还没有合法的经过RootCA签名的证书和相应的密钥,紧接下面的步骤就是完成这个任务。SubCA的证书跟普通证书是基本相同的,除了其X.509v3扩展项的某些选项的限制有一些区别。首先,为了向RootCA申请一个CA证书,需要生成一个密钥对和证书请求。因为要申请的是一个CA证书,所以证书请求的X.509v3扩展项跟普通证书请求有区别,我们通过修改OpenSSL的配置文件来达到这一目的。
  • 用文本编辑器打开C:\SubCA\openssl.cnf文件,修改其中v3_req字段的basicConstraints选项为下面的值:

  • 这个指令生成了一个2048位的密钥对作为SubCA的密钥,并同时生成了一个相应的证书请求。私钥保存在文件subca_key.pem中,而证书请求保存在subca_req.pem中。为了获得合法的CA证书,需要将证书请求提交给RootCA签发,提交的途径是多样的,可以通过网络连接提交,也可以通过远程数据库提交,而在这里,我们只需要将subca_req.pem文件复制到C:\RootCA目录下就可以了。

  • 上述的操作只是简单地使用新签发的证书和其相应私钥替换原来demoCA目录下的证书文件和私钥文件,从而完成SubCA证书和私钥的设置。SubCA并没有下级的CA,所以在OpenSSL配置文件中只要设定一个签发普通用户证书的X.509v3扩展字段即可。幸好,OpenSSL默认的配置文件已经设置好,我们不需要费神再去配置它。RootCA和SubCA都已经配置好了,现在可以签发用户证书了。

签发用户证书A

  • 结构显示,用户证书A是RootCA签发的普通用户证书,所以我们首先在指令行界面下到C:\RootCA目录下,启动openssl.exe程序。生成一个用户证书事实上包含三个部分:生成密钥对、生成证书请求及签发证书。在这里,我们使用req指令完成第一和第二个部分,使用ca指令完成第三部分。
  • 普通用户证书的密钥对一般使用1024位密钥就可以了,可使用下面的指令生成密钥对和证书请求:

  • 根据配置文件“C:\RootCA\opensl.cnf”的配置,ca指令默认X.509v3扩展项使用的是用于签发普通用户证书的usr_cert字段,所以我们执行下面的ca指令即可签发用户证书A:

  • 执行完上述指令后,用户A就拥有了一个合法的RootCA签发的证书A和相应的私钥,分别保存在C:\RootCA\userA_cert.pem和C:\RootCA\userA_key.pem文件中。

签发用户证书B

  • 用户证书B的申请和签发跟用户证书A的申请和签发基本相同,只是,因为用户证书B是SubCA签发的证书,所以应该在指令行界面下进入“C:\SubCA”目录并启动opensl.exe程序。然后,执行下面的两条指令完成用户证书B的申请和签发:

  • 执行完上述两条指令,用户B就拥有了一个合法的SubCA签发的证书B和相应的私钥,分别保存在C:\SubCA\userB_cert.pem和C:\SubCA\userB_key.pem文件中。到此为止,就完成了上述CA目录结构的构造任务。整个过程使用的指令非常简单,只有req和ca两个。

证书使用

X.509证书

x509指令功能概述和格式

  • x509指令是一个功能强大的指令,甚至超出了其名称所涉及的范围,它既可以以各种方式显示一个证书的内容,也可以对一个证书的格式进行各种有趣的转换,甚至可以签发证书等
  • 下面是x509指令的格式和选项:

输入和输出格式选项inform,outform,keyform,CAform和CAkeyform

  • inform选项指定了in选项所指定的输入文件的格式,输入的文件可能是证书,也可能是证书请求文件(当使用了req选项的时候)。无论哪种文件,该选项可以接受的格式包括PEM、DER编码和老式的Netscape的编码格式。
  • CAform跟inform参数的意义相类似,不过它指定的是CA选项所指定的输入文件的格式。
  • outform则指定了out选项输出的文件格式,但是,并非所有的内容都会受到这个选项的影响,仅输出文件是证书或者证书请求文件的时候会受到该选项的影响。目前,支持的格式同样包括PEM、DER和NET格式。
  • keyform选项指定了signkey选项指定的输入私钥文件的格式,支持PEM、DER和ENGINE三种格式,其中ENGINE是指通过第三方驱动设备提供的私钥。
  • CAkeyform的参数意义跟keyform相同,不过,它相关的文件是选项Cakey所指定的文件

输入和输出选项in,out,CA和CAkey

  • in选项指定了输入的证书文件的路径,如果使用了req选项,则输入文件将被视为是一个证书请求文件而不是证书文件。
  • 文件的编码格式由inform参数决定。默认情况下输入是标准输入设备。
  • out选项指定了接受输出的文件的路径,默认情况下,输出目标是标准输出设备。如果输出的是证书或者证书请求,则其输出格式由outform参数决定。
  • CA选项指定了在签发证书或者转换证书格式的时候需要的CA证书文件路径。其格式由CAform参数指定。
  • CAkey选项则指定了签发证书或者转换证书格式的时候需要使用的CA证书相对应的私钥文件路径,如果使用的私钥是Engine提供的,则是一个Engine的索引文件,如公钥文件等,根据具体的Engine私钥索引方法具体决定。普通的私钥文件格式由CAkeyform参数决定。

输入口令选项passin

  • passin参数给出了当使用signkey输入私钥文件时需要提供的口令字符串。在使用CA证书的私钥签发证书的时候,则给出的是使用CAkey选项输入私钥文件时需要提供的口令字符串。一般来说,signkey选项与CAkey选项是不会同时出现的。输入口令的方式可以是多样的。如果没有使用该选项,而指定的私钥又要求提供解密口令,那么指令会在指令行提示用户输入口令。

输出显示内容选项serial,hash,subject,isuer,email,purpose,modulus,fingerprint,ocspid,startdate,enddate,dates,pubkey,C和nout

输出证书更加灵活的内容的选项text和certopt

  • 使用text选项,就可以看到证书的内容
  • certopt选项可以帮助选择所需要的东西。certopt选项一般只有出现text选项的时候才使用,它的参数值很多,可以同时提供一个或者多个,如果是多个,它们之间要使用分号分开。certopt选项还可以在指令中多次使用,这可以让你更随意地更改你的想法。certopt的参数具体意义详见表10.3,但参数no_attributes在certopt选项中是无效的。

证书信任设置选项trustout,addtrust,clrtrust,addreject,clreject,setalias和alias

  • 这些选项都是对可信证书扩展字段进行设置的选项。事实上,所谓的可信证书就是普通的证书加上一些扩展字段,这些字段定义了该证书可以用来做什么和不能用来做什么,并定义了证书的别名。
  • 一般来说,在进行证书验证的过程中,证书链中至少有一个证书应该是“可信证书”,否则就不能完成验证过程。默认情况下,必须在本地保存一个可信证书,并且该可信证书应该是一个根CA证书,这种情况下,任何一个结束于该可信根CA的证书链上的证书可以用于指定用途。事实上,现在OpenSSL并没有要求那么严格,如果一个根证书没有可信选项,那么它就默认该证书是一个可以用于任何用途的可信证书。
  • 目前OpenSSL的版本仅在根CA上支持可信选项设置,从而实现在最终的CA上统一控制证书的用途,比如允许CA颁发的证书用于SSL客户端验证或者SSL服务器验证等。当然,OpenSSL的开发组承诺在以后的版本中将支持在所有证书中设置可信选项,而不仅仅限于根证书。下面回到x509指令的显示世界中来,让我们看看这些选项的具体含义和用法。
  • trustout选项是最容易明白的一个选项了,它会在输出的证书中加上可信的标记,从而使其成为一个可信证书。x509指令可以接受的输入包括可信证书和普通的X.509证书,但是,如果没有trustout选项,默认情况下输出的证书都会把可信选项去掉,成为普通的X.509证书。当然,如果你通过其他选项设置或者修改了证书的可信选项字段,那么会自动输出一个可信证书。
  • 设置证书的信任选项在OpenSSL的指令中显得很简单,使用addtrust选项就可以设置可信证书的用途,你可以在这里使用任何有效的参数,但是目前真正使用的参数仅仅包括clientAuth,serverAuth和emailProtection。其中,clientAuth参数表示用于SSL客户端验证,serverAuth参数表示用于SSL服务器验证,而emailProtection参数则用于S/MIME邮件的保护。
  • 相反,clrtrust则将清除证书中所有可信选项的用途设置
  • 相反,如果你想禁止证书用于某种用途,那么可以使用addreject选项,该选项的参数内容和addtrust相同。
  • 使用clrreject则可以清除所有设置好的禁止用途选项。我们猜你不会喜欢用一个证书的序列号来记忆或者标识一个证书,虽然实际的计算机系统是如此的,但毕竟人跟计算机还存在一些区别。
  • 那么我们的证书设计者充分利用了以人为本的设计理念,提供了一种定义证书的名称的方法,即证书的别名,setalias选项就是为了让你拥有这种自由。证书别名通常是一个好记的字符串,比如“OpenSSL‘sCertificate”,等等,看着比“0x00cd0e”愉快多了是不是?
  • alias则事实上只是一个输出选项,使用该选项,输出的内容中就会包括证书的别名了。

证书签发转换选项signkey,clrext,req,x509toreq,days,set_serial,CAserial,CAcreateserial,extfile和extensions

  • 首先来看看signkey选项,这个选项指定了输入的保存私钥的文件路径。这个选项使用后,会将输入的证书文件或者证书请求文件转换成一个自签名的证书。如果输入的是证书文件,那么x509指令会执行下面的操作:

    • 1 使用证书所有者名称替代证书签发者名称;
    • 2 更改证书有效期,其中生效期从当前时间开始,结束日期取决于days选项,而其他扩展项和内容都会保留,如果你想清除这些过时的扩展项,那么就需要使用clrext选项;
    • 3 使用signkey提供的私钥重新签发证书。
  • 但是如果在使用signkey的时候同时使用了x509toreq选项,过程则与上面不一样,signkey提供的私钥将会被用来对生成的证书请求进行签名。如果输入的是证书请求文件,事情就很简单,签发一个自签名证书即可,签发者名称当然跟证书持有人名称一致。
  • 通过上面signkey的介绍,clrext选项的功能大家已经有所了解,事实上clrext选项仅当x509指令通过一个证书创建另一个证书的时候有意义。也就是说,仅当输入是证书,并且使用signkey或者CA选项创建一个新的证书的时候,clrext选项会将原来证书中的扩展项全部清除,否则,默认情况下所有扩展项都会被保留下来形成新证书的一部分
  • 一般情况下,x509指令会认为输入选项in输入的是一个证书,如果你想输入的是一个证书请求,那么使用req选项就是通知x509指令的唯一途径。有些情况下,一些特殊需要总是会出现的,比如将一个证书转换成证书请求,这时候x509toreq选项就能帮助你达到这个目的。这功能看起来或许有些奇怪,但是在证书到期续签的时候可能就有些用处了。使用这个选项的时候,需要使用signkey选项提供相应的私钥在生产证书请求的时候进行数字签名。
  • 签发证书的时候需要指定有效期,days选项就定义了有效期的长短,默认情况下,x509指令证书签发的有效期是30天。我们知道证书都有一个序列号,这个序列号就像你的身份证号码一样独特而重要,ca指令是通过文本数据库中的serial文件来保存确定的。而在x509指令中,则可以有多种方法确定一个将要生成的证书的序列号。首先最直接的是可以使用set_serial选项来直接指定序列号,该方法优先级是最高的,如果使用了该方法,后面的两种方法即便在指令中使用了也会被忽略。
  • 其次是可以使用CAserial选项指定序列号文件来提供序列号,事实上,所谓序列号文件事实上是一个仅包含一个十六进制正整数的文件。使用CAserial选项后,指令会自动将该序列号文件中的整数加1并保存回文件,默认情况下,x509指令的序列号文件名称为证书文件名称加上.srl后缀,比如输出的证书文件名为certpem,那么指令会试图从文件cert.srl中获取序列号。最后,如果你这个文件也没有(其实你真的可以自己用文本编辑器编一个),就使用CAcreateserial选项生成一个证书序列号文件,该序列号文件保存的是2,而所签发的证书序列号是1,这时候你可以打开这个序列号文件好好研究一下了。
  • 有时候在证书中需要加入扩展项,这时候可以使用extfile选项extfile选项指定的是一个扩展项配置文件。指定扩展项定义文件之后,
  • 可能还需要使用extensions指定使用的扩展字段,因为一个扩展项配置文件中可能存在多个扩展字段,如果不使用该选项,那么需要加入的扩展项应该定义在文件的默认字段(未命名字段)或者默认字段中应该包含一个名为extensions的变量来指明扩展项所在的字段。

证书显示名称格式选项nameopt

  • 利用nameopt的参数,完全可以显示所有人和签发者的中文信息,包括名称、单位和城市,等等。首先,我们需要一个能够输入中文的控制台终端,比如普通的中文Windows指令行界面。在该控制台可以按照正常的req指令生成一个证书,其用户信息用中文填写完成,从而得到一个中文的证书。如果你直接使用下面的指令,

验证证书是否过期

  • 选项checkend这个选项非常简单实用,目的就是验证输入的证书是否在有效期内。如果本选项返回0,说明输入的证书没有过期,如果返回是1,则说明证书过期了

信息摘要算法选择选项md5,md2,sha1和mdc2

  • 对于这些名词,大家应该已经非常熟悉了,它们是进行信息摘要时可能用到的四种算法,在前面章节有对于这几种算法的详细介绍。信息摘要算法在证书中主要是用于CA颁发证书签名的时候,具体到x509指令来说,如果信息摘要算法变化了,对于前面介绍的-fingerprint,-signkey和-CA等证书信息的输入输出选项的结果都会有影响。在x509指令里,如果没有特别指定,默认使用的是MD5算法。由于DSA算法固定使用SHA1算法作为数字签名的信息摘要算法,所以如果你使用DSA密钥进行数字签名,则SHA1的使用将是固定不变的,这些选项也就没有任何使用的必要。

engine选项

  • engine选项告诉x509指令尽可能使用Engine设备提供的加密函数和算法替代OpenSSL本身的函数。对于x509指令来说,可能替代的算法包括:签名时使用的信息摘要算法、签名时使用的私钥加密算法、验证证书请求中的数字签名时使用的公钥解密算法、随机数函数及私钥数据等。

例子

  • 查看一个证书的内容

CRL

  • 当证书被CA吊销时,它将被添加到该CA的证书吊销名单中,CA中心必须定期发布更新吊销列表(CRL),以保证所有CA相关的应用都能及时得知证书的有效性信息。所谓CRL,事实上就是一系列已经被吊销的证书序列号组成的文件,并且为了确保该文件的真实性,该文件经过了CA的合法签名。一般来说,CRL都具备有效期限制,其有效期由CA决定,可能是一天、一周或者一个月等,当然,有效期越长,其跟实际情况相差的可能性越大。
  • CRL的颁发和公布都是由CA定期进行的,发布的方式是多种多样的,可以是在网上发布或者通过E-mail发布,无关紧要。CRL的使用者是所有使用该CA签发证书的系统和用户,他们需要随时获取最新的CRL,并在进行证书验证的时候查看该CRL,确定接收到的证书不在该CRL列表内(如果在该列表内,则证书就是无效的了)。

crl指令功能概述和格式

  • OpenSSL提供了crl指令用于显示、处理和验证CRL文件信息,而发布CRL文件则在前面介绍的CA指令中可以实现。
  • 下面是crl指令的格式和选项: 

输入和输出格式选项inform和outform

  • inform和outform选项指定了输入和输出文件格式,相对应于in和out选项,可以接受的格式包括PEM和DER编码格式,默认接受的格式是PEM。

输入和输出选项in和out

  • in选项指定了输入的CRL文件的路径,文件的编码格式由inform参数决定。默认情况下输入的是标准输入设备。
  • out选项指定了接受输出的文件的路径,默认情况下,输出目标是标准输出设备。其输出格式由outform参数决定。

输出显示内容选项hash,issuer,noout,text,lastupdate,nextupdate和date

  • hash选项显示CRL文件中CA签名的HASH值。
  • isuer选项显示CRL文件签发者信息,一般来说,就是CA的信息。
  • noout选项要求指令不输出编码CRL的内容。
  • text选项要求指令输出CRL文件的可理解的形式,也就是说,能够让你一看就懂的形式。
  • lastupdate和nextupdate选项分别显示CRL文件的最近更新时间和下次更新时间,
  • 而使用date选项则同时显示上述两种时间。事实上,所谓下次更新时间,也就是本CRL文件失效的时间。

输出字符编码选项nameopt

  • nameopt选项指定了如何显示主体名称和签发者名称,主要用于显示名称中不同编码的内容。没有使用该选项时,默认使用的是“oneline”参数。该选项可以同时使用多个参数,每个参数间使用“,”分开即可。具体的参数可以参照表10.4。

CA文件和目录选项CAfile和CApath

  • CAfile指定一个CA证书文件,该CA证书用于核实CRL中的签名是否正确和有效。
  • CApath则告诉指令从一个目录中查找有效的CA证书,此目录必须是标准证书目录,所谓标准目录,即OpenSSL要求的基于文件HASH值为文件名排序的一个目录,详见x509指令的介绍。

简单的例子

  • 把CRL文件的格式从PEM转化成DER:

PKCS#12证书

  • 事实上,除了Microsoft的产品,Netscape的浏览器也需要PKCS#12格式证书的支持。基于此,OpenSSL除了在一般的指令中对PKCS#12证书提供支持,还开发了专门用于处理PKCS#12证书的指令pkcs12,用于PCKS#12证书的生成、解释和验证等。

pkcs12指令功能概述和格式

  • pkcs12指令功能总体来说可以分成创建PKCS#12证书和解释PKCS#12证书。
  • 创建PKCS#12证书即将普通的X.509证书和私钥封装成PKCS#12证书;
  • 解释证书可以将PKCS#12证书转换成X.509证书,并提取出相应的私钥,并可以输出其他必要的信息。
  • 一般来说,PKCS#12证书的私钥是经过加密的,密钥由用户提供的口令产生。所以,在使用pkcs12指令编码或者解码PKCS#12证书的时候,一般都会要求用户输入密钥口令。
  • 下面是pkcs12指令的格式和选项:

  • 需要把PKCS#12证书转化成X.509证书时,仅仅用-in和-out选项就可以完成了。如果你想把X.509证书和其私钥封装成PKCS#12证书,再增加-export一个选项即可轻松完成。
  • 当然,如果你需要更加具体复杂的要求,你需要了解的指令选项也会多一些。

输入和输出文件选项in和out

  • 默认情况下,输入和输出指定的都是标准输入输出设备。
  • 在解释PKCS#12证书的时候,即没有使用-export选项的时候,
  • in选项的参数默认情况下是一个PKCS#12格式的文件,它将被解释为单独的证书和私钥,并总是以PEM格式写入到out选项指定的输出文件中。
  • 在创建PKCS#12证书的时候,out选项参数输出的是一个PKCS#12格式的证书文件。in选项输入的文件是包含一系列证书和私钥的文件。这些证书和私钥必须是PEM编码的,它们在该文件中的顺序不受限制,但要求至少有一个私钥和其相对应的证书存在。如果存在其他附加的证书,则这些证书都会被封装到输出的PKCS#12证书文件中。

输入和输出口令选项passin,passout,password

  • pasin选项指定了使用输入文件的时候需要的口令源。如果是解释PKCS#12证书,则是该证书文件解密口令源;如果是创建PKCS#12证书,则是读取私钥文件时候可能需要的口令源。
  • pasout选项则指定了输出文件时进行加密的口令源。如果是解释PKCS#12证书,则是输出私钥加密口令源;如果是创建PKCS#12证书,则是加密PKCS#12证书文件时可能需要的口令源。
  • password选项提供的总是PKCS#12证书的加密口令源,即在解释PKCS#12证书时,其参数为读取PKCS#12证书需要的口令源;在创建PKCS#12证书的时候,其参数为加密PKCS#12证书需要的口令源。
  • 口令源的形式多种多样,可以是直接输入,也可以是从文件、环境变量、标准输入输出等获取

输出内容选项noout,clcerts,cacerts,nocerts,nokeys和info

  • 这些选项都是在解释PKCS#12证书时使用的
  • noout选项告诉指令不要输出任何私钥和证书信息到输出文件中。
  • clcerts选项告诉指令只输出客户证书(不是CA证书)到输出文件中。
  • cacerts选项告诉指令只输出CA证书到输出文件中。
  • nocerts选项告诉指令不要输出任何证书到输出文件中。
  • nokeys选项告诉指令不要输出私钥到输出文件中。
  • info选项告诉指令输出一些其他PKCS#12证书文件相关的信息,如构成、算法及其迭代次数等。

加密算法选项des,des3,idea,aes128,aes192,aes256和nodes

  • 这些选项仅在解释PKCS#12证书的时候使用。
  • des,des3,idea,aes128,aes192和aes256选项用于指定在输出私钥时,对私钥进行加密使用的算法。默认情况下,pkcs12指令会使用des3作为加密算法。
  • nodes选项则告诉指令对私钥不进行加密处理。

nomacver和twopass

  • 这两个选项使用较少,也仅在解释PKCS#12证书的时候使用。
  • nomacver选项告诉指令在读取PKCS#12证书之前,不需要对文件进行MAC的完整性验证。
  • twopass选项告诉指令提示输入完整性验证和加密需要的密码源。
  • 大多数PKCS#12软件实现都假设这两个密码是一样的,不需要使用这个选项。

创建PKCS#12证书选项export

  • 该选项在创建PKCS#12证书的时候必须使用,告诉指令这时候需要创建一个PKCS#12证书,而不再是解释一个已有的PKCS#12证书。

证书内容输入选项inkey和certfile

  • 这两个选项在创建PKCS#12证书的时候使用。
  • inkey选项指定一个包含了私钥的文件,指令将从这个文件中读取创建PKCS#12证书需要的私钥。如果该选项没有使用,则在in参数指定的输入文件中必须包含一个私钥。
  • certfile选项指定向创建的pkcs#12证书中封装额外的证书,这些证书存储在该选项的参数文件中,可以是一个或者多个。

证书别名选项name和caname

  • 这两个选项在创建PKCS#12证书的时候使用。
  • name选项指定了证书和私钥的一个好记的别名,该名称通常显示在需要导入该PKCS#12证书文件的软件中的证书列表中。
  • caname选项用于为其他证书指定一个好记的别名,该选项可以使用多次以为多个证书指定名称,名称的顺序跟证书出现的顺序保持一致即可。该选项一般仅在IE里面有效,在Netscape软件中则通常被忽视。

证书加密算法选项descert,keypbe和certpbe

  • 这三个选项在创建PKCS#12证书的时候使用。descert选项告诉指令使用3DES算法加密证书,在默认情况下,指令使用3DES算法加密私钥,但是使用40位的RC2算法加密证书。
  • keypbe和certpbe选项分别指定对密钥和证书进行加密的算法。虽然,所有的PKCS#5v1。5或者PKCS#12算法都是支持的,但是OpenSSL还是建议你只用PKCS#12标准中的加密算法。这些算法包括DES,3DES,RC2和RC4等。这些参数的形式诸如:

  • 支持的具体算法和其参数形式见表11.1。

密钥用途选项keyex和keysig

  • 这两个选项在创建PKCS#12证书的时候使用,而且仅在Microsoft的IE和其他Microsoft软件中才有效。
  • keyex选项指定密钥和证书用于密钥交换,
  • keysig则指定密钥和证书用于数字签名。
  • 如果仅使用keysig选项,则密钥仅能用于进行签字。仅用于签名的密钥可以用来进行S/MIME签名、验证码(ActiveX控制签名)和SSL客户端验证。需要注意的是,由于OpenSSL本身存在的BUG,只有IE5.0和其后的版本才能够支持仅用于签名用途的密钥进行SSL客户端验证。

迭代次数选项nomaciter,noiter和maciter

  • 这几个选项在创建PKCS#12证书的时候使用,而且仅在你需要兼容Microsoft的IE4.0的时候需要。因为算法通常使用普通口令产生密钥,为了降低受到字典攻击的可能性,可以将口令进行多次迭代从而产生复杂的口令。这通常以重复密码算法中的一部分步骤和降低速度为代价。MAC虽然一般用于验证文件的完整性,但因为私钥和证书也是使用与其相同的口令,所以MAC同样存在被攻击的可能性。通常情况下,MAC和算法的迭代次数都设置为2048次如果使用了nomaciter和noiter选项,迭代次数将分别降为1
  • 显然,这两个选项大大降低了文件的安全性,所以,除非不得已,建议不要使用这两个选项。除了IE4.0不支持MAC迭代外,大部分软件都支持多次MAC和算法迭代。
  • maciter目前来说意义不大,指明需要使用MAC迭代,目前版本这已经是默认的,只是为了兼容以前的版本该选项才没有取消。

其他选项chain和rand

  • 这两个选项同样在创建PKCS#12证书的时候使用。chain选项告诉指令要建立一个完整的用户证书相关的证书链保存在PKCS#12文件中。指令会从一个标准的CA证书容器中寻找建立证书链需要的证书,如果失败,则视为发生致命性错误。这个功能当然比较特殊,不过,很多时候,验证方确实需要被验证方提供完整的证书链来进行验证操作,尤其当多级CA存在的情况下,这种要求就是常见的了。
  • 随机数文件选项rand提供了产生随机数的参考种子文件。如果没有提供该选项,那么程序会从标准输出设备的状态读取信息作为随机数种子。随机数文件可以为任意类型的文件。rand选项可以支持多个文件,用分隔符隔开即可,Windows平台使用“;”分隔,OpenVMS系统使用“,”分隔,其他系统都使用“;”分隔。

例子

PKCS#7证书

  • PKCS#7格式的证书可以封装X.509标准证书、相关证书链上的CA证书和CRL,这样就可以直接把PKCS#7证书发给验证方验证,免去了把以上的验证内容一个一个发给接收方的烦琐了。微软对PKCS#7证书的支持依赖文件后缀名p7,当然,OpenSSL则是从来不关心后缀名的。OpenSSL对PKCS#7协议提供了将普通用户证书、CA证书和CRL封装成PKCS#7格式证书的指令crl2pkcs7,此外还提供了pkcs7指令来解释PKCS#7格式证书,下面就具体介绍一下crl2pkcs7和pkcs7指令

crl2pkcs7指令功能概述和指令格式

  • crl2pkcs7指令名不符实,并不仅仅是把CRL转换成PKCS#7证书。其实,在OpenSSL中,该指令是唯一可以生产PKCS#7证书的指令,主要用于把CRL和一个或多个证书封装成一个PKCS#7格式的证书
  • 并且,CRL是一个可供选择项,即PKCS#7证书里面不一定需要一个CRL。
  • crl2pkcs7指令的格式如下:

输入和输出格式选项inform和outform

  • inform选项指出了输入的CRL文件的编码格式。目前只支持两种格式:PEM和DER。
  • outform选项指出了输出的PKCS#7文件的编码格式。目前支持PEM和DER两种格式。

输入和输出选项in,out和certfile

  • in选项指定了存储输入CRL的文件名。此选项如果不指定,默认采用标准输入。
  • out选项指定了存储输出PKCS#7证书的文件名,默认采用标准输出。
  • certfile选项指定的文件可以包含一个或多个证书,文件中的证书将会全部被封装到PKCS#7证书中,这个选项也可以多次使用以加入多个证书。需要注意的是,所有的证书都应该是PEM格式编码的。

不包含CRL的PKCS#7证书选项nocrl

  • nocrl选项指定在输出文件中不包含CRL文件。一般情况下,在输出的PKCS#7文件中包含CRL。指定此选项后,操作过程中将不会去读输入文件中的CRL。

简单的例子

  • crl2pkcs7指令最常用的用法是用来生成PKCS#7证书。
  • 下面就是生成PKCS#7简单例子。

pkcs7指令功能概述和指令格式

  • 查看这个包含多个X.509证书和CRL信息的文件里面的内容,OpenSSL提供pkcs7指令满足你的这种愿望。
  • pkcs7指令的格式如下:

(1)输入和输出格式选项inform和outform

  • inform和outform选项指定了in和out选项相关文件的格式,可以是PEM或者DER格式。

(2)输入和输出选项in和out

  • in选项指定了输入的证书文件的路径,文件的编码格式由inform参数决定。默认情况下输入的是标准输入设备。
  • out选项指定了接受输出的文件的路径,文件的编码格式由outform参数决定。默认情况下,输出目标是标准输出设备。

(3)输出显示内容选项ptint_certs,text和noout

  • print_certs选项要求输出该PKCS#7证书文件内的所有证书和CRL,该选项逐行输出所有证书的主题名和签名者。
  • text选项要求输出证书的所有内容。
  • noout选项要求不要输出编码结构的PKCS#7证书。

(4)engine选项

  • engine选项指定后,所指定的Engine(通过唯一的id指定)会使用Engine设备指定的库或者硬件设备相关接口来处理本指令的一些操作。

(5)简单的例子

验证证书

  • 证书的结构中的关键内容包括:序列号、公钥、用户名称、签发者、CA 签名和其他 一些附属信息等。证书验证过程就是依赖于这些信息和公钥对应的私钥进行。

通常的证书 验证过程包括以下要点:

  • 1确认证书内容是正确的和完整的,没有被篡改,CA签名是正确的;
  • 2确认证书是有效的,在有效期内并且没有被吊销(CRL中没有该证书序列号);
  • 3确认CA证书是可以被信任的证书,如果CA证书不是根证书,还要继续对CA证书进行验证;
  • 4通过与用户的交互,基于证书中的公钥和公开密钥算法确认用户的身份。其中,确认用户身份的过程是基于公开密钥算法的,基本过程如下:
    • 1被验证方发送自己的用户证书给验证方;
    • 2验证方提取证书中的公钥,并产生一个随机数Rp,使用该公钥加密该随机数得到加密的随机数Re并发给被验证方;
    • 3被验证方使用自己的私钥解密Re得到Rep并发回给验证方;
    • 4验证方对比Rp和Rep,如果一致,则验证通过,否则,验证不通过。
  • 从上述的过程可以知道,因为证书中公钥对应的私钥仅真正的证书所有者才可能持有(理论上是这样的,当然现实的系统和社会中不尽如此),所以如果被验证方能够正确解密使用该证书上的公钥加密的信息,即可认为被验证方确实是证书的持有人,也就可以确定其身份。
  • 无论何种类型的证书,其验证过程都是基本一致的,当然,根据具体的情况,其验证协议和要求提供的材料可能有一些区别。关于证书验证的更多情况,也可以参考前面。不过,在这一节,我们关心的是验证证书的有效性,而不对证书持有人的身份真实性进行验证
  • OpenSSL提供了证书验证的一些指令,包括普通验证指令和一种标准的OCSP协议处理指令

verify指令介绍

功能概述和指令格式

  • verify指令提供了证书或者说证书链的验证功能,下面是verify指令的选项和格式:

  • 在验证过程中遇到什么错误,虽然通常情况下这时候应该算作验证失败,应该停止验证过程了,但是我们OpenSSL中的verify指令还是不辞劳苦地将整个验证过程执行完。这样的好处是可以告诉用户在整个证书链的验证过程中存在的所有问题,而不需要用户一个一个问题进行逐步排除。
  • 为了执行验证过程,verify指令首先做的事情是试图从提供的所有证书里建立一个证书链证书链从提供的用户证书开始,而结尾应该是一个根CA证书
  • 证书链建立的规则是寻找当前证书的签发者证书,如果一个证书的签发者就是其自己,那么该证书就是根证书
  • 如果verify指令不能成功建立一个证书链,那么就认为验证失败。
  • 寻找当前证书的签发者证书这个过程本身也是一个复杂的过程。在OpenSSL早期版本中(0.9.5a),第一个找到的持有者名称跟当前证书签发者名称一致的证书,即被认为是当前证书的签发者证书。
  • 而在0.9.6和后面的版本中,所有找到的持有者名称与当前证书签发者名称一致的证书,都被认为是可能的签发者证书,需要进行进一步的验证来确定。也就是说,除了前面的条件,当前证书的密钥标识字段内容必须跟候选签发者证书的密钥标识、签发者和序列号等相匹配,此外,候选签发者证书的密钥用途扩展字段也应该包含允许签发证书的功能
  • 建立证书链的时候,程序首先查找不信任列表,如果找不到当前证书的签发者证书,则开始在信任列表中查找证书。而根CA证书总是在信任列表中被找到的。如果需要验证的证书本身就是一个根证书,那么必须在信任证书列表中找到一个完全一致的证书才能认为是验证通过。
  • 建立一个完整证书链后,verify程序开始检查每一个非信任证书的扩展项是否跟purpose选项提供的参数内容相一致。当然,如果purpose选项没有出现,则在本步骤verify指令将不进行任何操作。需要验证的证书或者“叶子”证书其扩展项必须跟要求验证的purpose参数一致,其他CA证书也必须是有效的证书。完成上述步骤后,verify开始检查根CA证书的信任设置,以确定其是否支持purpose的要求。OpenSSL为了兼容以前的版本,假定如果CA证书没有任何信任设置,则默认为支持任何用途。
  • 如果你使用的是0.9.7以后的版本,很幸运,OpenSSL将支持CRL验证的操作,这时候verify将根据CRL检查整个证书链的每个证书是否有效,即没有被管理员吊销。最后,verify程序将检查整个证书链上所有证书的有效期,根据当前的系统时间进行检测。需要注意的是,各个证书的数字签名也是在这个最后的时刻进行检验的。通过上面所有的验证步骤,证书验证才算成功,否则,任何一步的失败,都意味着证书验证不通过。

CA证书选项CApath和CAfile

  • CApath选项用来指定我们信任的CA的证书存放目录。
  • 但是这些证书的名称应该是下面这样的格式:xxxxxxxx.0(xxxxxxxx代表证书的哈希值,可以参看x509指令的-hash选项)。
  • CAfile选项用来指定我们信任的CA证书文件,其中可以包含多个CA证书。目前只支持PEM格式的文件

非信任证书选项untrusted

  • untrusted选项用来指定非信任证书文件,同样,该文件可以包含多个PEM格式的证书。
  • 所谓非信任的证书文件,一般是指在构造证书链的时候需要使用的CA证书,但一般都不是根证书。你千万不要以为这是不被信任的证书。通常,CRL也可以通过这个选项指定的文件输入到verify验证过程中。

证书用途选项purpose

  • 此选项主要验证证书的扩展字段,显示证书的用途。如果没有设置此选项,那么verify将不会对证书链进行验证操作。
  • 目前,purpose支持的参数包括:sslclient,sslserver,nssslserver,smimesign和smimeencrypt。

验证选项isuer_checks,crl_check,crl_check_al和ignore_critical

  • issuer_checks选项告诉指令输出在查找签发者证书过程中的详细信息,从而可以知道每个候选签发者证书被拒绝的原因。
  • crl_check选项告诉指令检查被验证证书的CRL,如果不幸CRL中存在被验证证书的序列号,则证书将不能通过验证。CRL通过untrusted选项的参数输入
  • crl_check_all选项告诉指令检查证书链中所有证书的CRL,即不仅仅要对被验证证书是否被吊销进行验证,还要对整个证书链中其他证书是否被吊销进行验证
  • ignore_critical选项告诉指令可以忽略一些比较少用的扩展项,即如果该扩展项指令没有处理的话,则忽略。

如何输入被验证的证书?

  • 在verify指令中,在指令所有参数最后面输入要验证的证书文件名即可指定需要验证的证书。如果有多个证书文件需要验证,可以以空格为间隔一起列在后面,但是这些证书都应该是PEM格式的数字证书。如果不提供证书文件,则指令将试图从标准输入中读取被验证的证书。
  • 使用verbose选项,指令将把验证过程中的所有详细过程输出。
  • engine选项用来指定可以用于替代OpenSSL的函数库的其他算法库或者硬件,详见前面章节。

诊断证书验证结果

  • 如果验证操作有问题,OpenSSL提供了一些输出来让我们弄明白到底出现了什么问题,虽然这些信息看起来有些难懂,不过还是有用的。诊断信息输出格式如下:

  • 第一行说明哪个证书文件出问题,后面是其证书的主题。
  • 第二行说明错误号,验证的深度,并给出错误的解释,虽然这些解释不甚明了。其中,验证深度是从0开始计算的。
  • 表10-6给出了错误号及其描述的详细说明。需要注意的是,有的错误虽然有定义,但没用使用,这里用unused标识。

 例子:

  • verify指定的选项应该是较少的,用起来也非常简单。只需要按上述的各个选项的操作进行。下面是证书certpem验证的例子,此证书用根证书cacert.pem生成:

在线证书状态服务协议指令 OCSP

  • 在许多情况下,需要验证证书真实性的人(当然也可能计算机或者程序)并不能完成证书验证的过程,也就是说,必须提供一种手段或者服务,能够帮助完成证书验证的需要。这就是为什么OCSP协议(OnlineCertificateStatusProtocol),即在线证书状态协议会出现在我们面前的原因。
  • OCSP协议使得普通证书应用程序可以通过服务方式知道一个特定证书的(吊销)状态,从而使得普通程序不需要了解证书验证的细节和实现方式。OCSP接受一个客户端发来的证书验证请求信息(通常是以HTTP协议发出),然后OCSP查询证书库的状态。
  • 当然,用户请求里面只是包含了证书的一些关键信息,而并不需要一个完整的证书。根据结果,OCSP响应器一般返回给客户端的状态信息包括三种:1良好,说明请求证书是正确的,而且没有被吊销;2吊销,说明证书已经被吊销;3未知,证书不在该OCSP响应器的范围内。
  • 为了防止可能发生的欺骗,每一个OCSP返回的回应信息都有签名,而签名者必须是用户所信任的,也就是说,用户还必须对每一个回应信息进行验证
  • 在OpenSSL实现上,这个签名者可能是以下三种之一。
  • 1 被验证证书的CA。即回应信息签名是用验证证书的CA证书签发的。
  • 2 被验证证书CA特殊授权的OCSP响应器。即使用OCSP本身的证书签发回应信息,OCSP的证书跟被验证证书是同一个CA颁发的,并且OCSP证书的用途被指明具有OCSP签名的权限。
  • 3 被信任的OCSP响应器。即使用OCSP本身的证书签发回应信息,OCSP证书本身的CA的根CA在信任设置里面必须是明确指明是可以用于OCSP签名的,或者是用户明确定义可以信任的OCSP响应器。
  • 可见,OpenSSL的实现跟OCSP协议规定的是基本相符合的,虽然在第三种方式上不完全一致。OpenSSL对OCSP回应信息的验证也是通过基于OCSP证书建立一个证书链来进行的,关于OCSP更多的详细内容在RFC2560中有明确定义。

功能概述和指令格式

  • OpenSSL提供的指令总是超出人们的预期,这次看到的ocsp指令也不例外。它几乎可以完成大部分OCSP协议通常的功能。该指令既可以用来输出OCSP请求和应答内容,也可以创建OCSP请求并发送给一个OCSP服务器,甚至,它还可以作为一个OCSP服务器运行。
  • 下面是ocsp指令格式和其参数:

  • ocsp指令里大部分选项都是用于测试和调试目的的,一般情况下,CAfile,Capath和VAfile才是要经常使用的选项
  • ocsp使用的时候可以作为客户端或者服务器两种模式,下面我们对其参数的具体介绍也分为这两部分来进行。区分ocsp指令在服务器模式还是在客户端模式工作的标志就是是否使用index选项:如果使用index选项,就是在服务器模式下工作,否则就是在客户端模式下工作。

输入和输出选项out,reqout,respout,reqin和respin

  • out选项指定通用的输出文件,可以在服务器模式或者客户端模式使用,默认情况下使用标准输出设备。一般来说,只有可读写的信息会在out参数指定的文件中输出,如提示信息、文本的请求或者响应解释信息等。
  • reqout选项告诉ocsp指令输出OCSP请求信息并且存储在参数指定的文件中。
  • respout则告诉指令输出OCSP响应并存储到该参数指定的文件中。上述选项输出的请求和响应都是以DER格式存储的。这两个选项同样都可以用于客户端和服务器模式。
  • reqin和respin选项分别告诉指令从这两个选项指定的文件中读取OCSP请求或者OCSP响应。
  • 如果创建请求或者响应的选项出现,如cert,serial或者host选项生效,那么这两个选项将会被自动忽略。reqin选项在服务器模式和客户端模式都可能使用,而respin选项则仅在客户端模式有效。

输出内容选项req_text,resp_text和text

  • req_text选项和resp_text选项分别告诉指令输出证书请求或者证书响应的文本信息,如果使用text选项,则指令将同时输出请求和响应文本信息。这些输出会保存在out指定的文件中或者标准输出设备中。这些选项在服务器和客户端模式都可以使用。

证书相关选项issuer,cert和serial

  • isuer选项指定存储要验证证书的签发者证书的文件,该证书必须是PEM格式的。该选项可以重复使用多次以选择多个签发者证书。该选项在创建OCSP请求的时候是必须的。
  • cert选项指定要验证的证书,即加到OCSP请求中的证书。签发该证书的CA证书必须在issuer选项中指定,否则指令就不能正常执行。
  • serial跟cert选项的功能一样,用于向OCSP请求中增加证书,不同的是,该选项使用证书序列号来标识要加入的证书。该序列号默认是以十进制表示,如果在参数前增加了0x,则认为是十六进制。
  • 如果你要输入负数序列号(似乎是很奇怪的需求),只要在输入参数前面增加“-”号作为标识即可。

请求相关选项signer,signkey,nonce和no_nonce

  • 如果需要对OCSP请求进行签名,则可以利用signer选项来指定签名的证书,其相应的私钥则可以在signkey选项指定的文件中输入。如果没有使用signkey选项,则ocsp指令将从signer选项指定的文件中读取私钥。
  • 如果signer和signkey都没有使用,那么OCSP请求就不会被加密。
  • 为了区分每个请求,OCSP定义了所谓的nonce,事实上,它是一个使用摘要算法生成的跟时间相关的随机数,为了防止重放攻击等行为的发生。使用reqin输入已有OCSP请求的时候,默认情况下是不会向请求中增加nonce的,如果选择了nonce选项,则将强制向OCSP请求中增加nonce扩展项。
  • 相反,当使用ocsp指令创建新的请求的时候(使用cert,serail或者host选项等),默认情况下会在请求中增加nonce扩展项,如果不想使用nonce扩展项,则可以使用no_nonce选项去除请求中可能增加的nonce扩展项。

OCSP响应器地址选项host,path和url

  • OpenSSL提供给我们的ocsp指令不仅仅可以处理一些OCSP请求或者响应信息,还可以实时模拟一个OCSP客户端,即时产生OCSP请求,发送给指定的OCSP响应器并得到返回的响应信息。OCSP响应器一般提供基于HTTP或者HTTPS的服务,其定位一般都是通过IP地址、端口和HTTP文件路径来进行。
  • host选项参数指定了OCSP响应器的地址和服务端口,一般是host:port的方式。
  • 而path选项则指定了HTTP文件的路径名,默认情况下使用“/”。
  • url选项是另外一种指定OCSP响应器地址的方式,使用HTTP或者HTTPS请求的格式。
  • 事实上,在OpenSSL的ocsp指令中,url参数也是被解释成host和path参数进行实际连接的建立的。

响应验证证书选项CAfile,CApath,verify_certs,trust_other和VAfile

  • CAfile和CApath选项大家已经非常熟悉,它们用来指定CA证书文件或者一个标准的存放CA证书文件的目录,这里输入的CA文件用于验证响应信息的签名。
  • 很多OCSP响应器在返回的响应信息中不会加入完整的OCSP证书,那么这使得客户端在验证响应信息的时候就会有一定麻烦。为了兼容这种情况,verify_certs选项可以指定增加一个或者多个证书,在验证OCSP响应时候可以查找使用这些附加的证书。
  • trust_other选项告诉指令,verify_certs指定的证书都是可信任的,不需要对这些证书进行进一步的验证工作,这时候,指令不会执行完整的证书验证过程,这对于不能够建立完整证书链的情况就非常有帮助。
  • VAfile选项的功能是verify_certs和trust_other选项的综合,该选项指定的证书都是默认为可信任的附加证书,不需要进行进一步验证。

响应验证策略选项noverify,no_signature_verify,no_cert_verify,no_cert_checks,no_intern,no_chain,validity_period和status_age

  • noverify选项告诉指令对OCSP响应签名和nonce字段不进行任何验证,该选项事实上放弃了所有对OCSP响应的验证。
  • no_signature_verify选项告诉指令不用验证OCSP响应中的签名信息,即便签名无效。
  • no_cert_verify选项告诉指令不用验证响应签名者的证书,也就是说,任何人签名的响应都是有效的。
  • no_cert_checks选项则告诉指令对响应签名证书的状态不用做任何附加的检查,即如果证书已经被吊销或者过期,也是不会被发现的。上述的选项因为都在不同程度降低了响应验证的强度和响应的安全性控制,所以理论上一般仅在测试的时候使用上述选项。
  • no_intern选项告诉指令忽略OCSP响应中包含的证书信息,在这种情况下,必须使用verify_certs或者VAfile选项来增加额外的OCSP响应者证书以保证验证响应签名过程的顺利完成。no_chain告诉指令不要使用响应中的证书作为附加的非信任CA证书,也就是说,不要让响应中的证书增加到验证过程中建立的证书链中去,这确保了验证过程中使用的证书完全是由用户来控制
  • 每个证书响应都会包括一个有效期,这个有效期由一个notBefore字段和一个可选的notAfter字段组成,当前的时间必须在这两个字段规定的时间之间,响应才有效。但是,这个时间间隔有时候是非常短的,可能只有几秒,而实际系统的客户端和服务器的时间可能不同步,存在误差。为了避免这种情况导致响应失效,OpenSSL提供了validity_period和status_age选项来设定可以允许的时间误差值,其参数单位是秒。其中,validity_period选项适用于notAfter扩展项存在的情况下,其设定的是一个误差秒数值,默认值是5分钟。如果notAfter扩展项不存在,这一般意味着该响应只是即时有效,这时候可以使用status_age选项来设定有效期,即notBefore时间比当前早的时间不应该超过status_age选项设定的值。
  • 默认情况下,这项检查是不会执行的,即响应在notBefore时间后总是有效。

OCSP服务器选项index和CA

  • 上面介绍的选项大部分是用于处理OCSP请求、OCSP响应或者模拟客户端,事实上,ocsp还可以用于模拟一个OCSP响应器(服务器)。
  • index选项是否在指令中出现是区分ocsp指令运行在服务器还是客户端的标记,如果使用了index选项,则表明指令已经运行在OCSP服务器(或者说响应器)的模式下。
  • 显然,OCSP响应器就是为了处理OCSP请求的,在OpenSSL的ocsp指令中,OCSP请求的输入方式是灵活多样的:第一种是指令行方式,即直接在ocsp指令行中输入,使用issuer和serial参数产生请求信息;第二种是采用文件输入方式,即使用reqin选项指定一个要处理的OCSP请求;第三种方式是采用其他OCSP客户端输入,即定义好OCSP运行的服务端口port或者服务URL即可。
  • index选项跟我们在ca指令中看到的index选项相同,指定的是OpenSSL提供的模拟CA中的证书库文件,该文件包含了该CA所有颁发的证书信息和其(吊销)状态。在服务器运行模式下,CA选项是必须使用的,它指定了index证书库相应的CA证书文件。

OCSP响应签发者选项rsigner,rkey和resp_key_id

  • OCSP响应必须是经过签名的,所以在服务器模式下,rsigner选项是务必要使用的,它指定了用于对OCSP响应签名的证书。
  • rkey则指定了rsigner证书选项相对应的私钥,如果rkey选项在指令中没有出现,那么在服务器模式下,指令会从rsigner指定的文件中读取用于响应签名的私钥。OCSP响应被签名后,还需要在响应中标识用于签名的私钥,默认情况下使用的是证书主题名。
  • 如果使用resp_key_id选项,则将使用私钥ID标识OCSP响应信息签名私钥。

OCSP响应内容选项rother,resp_no_certs,nmin和ndays

  • 如果想在返回给客户端的响应信息中包含其他附加证书信息(可能用于客户端验证响应签名时使用),那么可以使用rother选项指定存储这些附加证书的文件。
  • 相反,如果不想在响应信息中放入任何证书(包括签发响应的证书),那么可以使用resp_no_certs选项。
  • nmin和ndays选项用来填充响应信息中的nextUpdate字段,该字段告诉客户端下一次吊销列表更新的时间将会在多长时间之后,nmin和ndays分别以分钟和日为单位进行定义。
  • 如果在ocsp指令中这两个选项都没有使用,那么nextUpdate字段就会从响应信息中删除,这意味着吊销列表随时都会进行更新。

OCSP服务器运行方式选项port和nrequest

  • 这两个参数仅在ocsp指令以服务器方式运行且请求是从OCSP客户端输入的情况下使用。
  • 其中,port选项定义了OCSP服务器的服务端口,而nrequest选项则告诉指令在接受和处理该参数指定数量的OCSP请求后退出运行状态。
  • 事实上,还有其他一些参数没有一一介绍,比如engine选项,其意义跟其他指令中的同名选项是一样的,即使用第三方密码设备或者密码库来执行一些运算操作。读者可以根据指令的使用和源代码的阅读来进一步了解这些指令的更多参数。

密码学专题 证书和CA指令 申请证书|建立CA|CA操作|使用证书|验证证书相关推荐

  1. 密码学专题 OpenSSL标准转换指令

    概述 繁多复杂的各种文件编码格式.证书格式和密钥格式等.事实上,并非OpenSSL开发者想要将数字世界弄得如此令人头疼,只是由于各种原因,数字世界存在各种不同的标准,为了尽量兼容这些不同的标准,Ope ...

  2. OpenSSL之十三:证书和CA指令

    证书和CA指令 证书生命周期 证书封装类型 证书使用 证书应用模型 证书链 用户身份确认 OpenSSL支持的CA指令 申请证书 req指令 生成证书密钥 使用RSA密钥生成证书请求 使用DSA密钥生 ...

  3. 建立私有CA实现证书申请颁发

    CA和证书 PKI:Public Key Infrastructure 公共密钥加密体系 签证机构:CA(Certificate Authority) 注册机构:RA 证书吊销列表:CRL 证书存取库 ...

  4. 密码学专题 文本数据库

    应用概述 文本数据库是跟OpenSSL的CA应用程序紧密结合在一起的,它以文本的方式记录CA已经签发的证书的状态和摘要信息.这些状态信息可以用于跟证书库相关的一些操作,比如使用ca指令生成CRL主要就 ...

  5. 加密、解密以及Openssl建立私有CA

    一.openssl简介       OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法.常用 的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用.   SS ...

  6. 密码学专题 证书和CA指令 证书和CA功能概述

    为什么需要证书 实现了公钥和私钥的相互验证,但是任何人都可以生成很多的密钥对,密钥对并没有关联实体身份,因此诞生可数字证书 前提是CA是所有用户都信任的 用户需要将自己的信息和公钥交给CA进行认证生成 ...

  7. 搭建开源CA认证-申请颁发证书

    文章目录 一.CA机构分级管理 二.OpenSSL (一)生成随机数: (二)ASCII编码与Base64编码转换: (三)随机数生成器: 三.搭建私有CA (一)证书申请及签署步骤: (二)搭建CA ...

  8. Linux如何创建私有CA和申请证书

    openssl的配置文件:/etc/pki/tls/openssl.cnf 三种策略:匹配.支持和可选.匹配:指要求申请填写的信息跟CA设置信息必须一致:支持:指必须填写这项申请信息:可选:指可有可无 ...

  9. https证书互信解决方案—创建私有CA并申请证书

    前言 https相较于http而言有很大的安全性,当我们一个服务开启https并与之通信时,往往需要证书的认证,如果是浏览器访问服务,只要在浏览器内设置信任证书即可,而如果是程序内访问服务(如java ...

最新文章

  1. Oracle技术之实例恢复的顺序
  2. 构筑你的本地资料库——ScrapBook
  3. WPF: RenderTransform特效
  4. mysql 启动参数_MySQL启动相关参数 MySQL DBA学习
  5. 数据库连接用户名和密码加密
  6. 旧 WCF 项目迁移到 asp.net core + gRPC 的尝试
  7. ASP.NET Core 中文文档 第三章 原理(5)错误处理
  8. IOS 获取农历方法(转)
  9. javafx8配置参数列表
  10. 大团圆结局!苹果高通和解:双方撤销全球所有诉讼
  11. 和付费网盘说再见,自己起个网盘不香吗?| Java 开源项目
  12. 面向对象 —— 类设计(八)
  13. 仿迅雷播放器教程 -- 媒体播放器对比 (2)
  14. matlab验证dtft移位性质,7.DTFT的Matlab实现.ppt
  15. 出现Illegal invocation的报错
  16. 利用一个竞态漏洞root三星s8的方法
  17. win7总是显示加载计算机,win7系统打开“此电脑”很慢总是在加载不显示的具体办法...
  18. 深度学习环境配置避坑-CUDA11.0+DGL1.8
  19. 为什么安装好mysql打不开_MySQL安装完成之后怎么启动? mysql安装完成后怎么
  20. 数据治理与数据安全研读开篇

热门文章

  1. 马逊s3云存储接口_当对象存储“湖”有了强一致性
  2. python tkinter listbox_Python3 tkinter基础 Listbox for+insert 将list中元素导入listbox中
  3. 神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(Matplotlib绘图基础<散点图>python)
  4. 【转】CT解析重建**
  5. Asp.Net WebForm生命周期的详解
  6. 第四节: Quartz.Net五大构件之Trigger通用用法(常用方法、优先级、与job关联等)
  7. 一步步编写操作系统 76 用汇编语言编写字符打印函数
  8. java数据结构 -链表 -获取有效节点个数,单链表中倒数k个节点
  9. 【Python CheckiO 题解】The Most Numbers
  10. php跨域session共享,PHP中利用COOKIE与SESSION联合实现SESSION跨域