作者: hetao

  • openssl-genpkey

    openssl-genpkey

    名字

    openssl-genpkey – generate a private key or key pair

    概述

    openssl genpkey [-help] [-out filename] [-outpubkey filename] [-outform DER|PEM] [-verbose] [-quiet] [-pass arg] [-cipher] [-paramfile file] [-algorithm alg] [-pkeyopt opt:value] [-genparam] [-text] [-rand files] [-writerand file] [-engine id]

    [-provider name] [-provider-path path] [-propquery propq] [-config configfile]

    描述

    这个命令可以生成私钥或密钥对

    命令语法

    • -help

      帮助

    • -out

      指定要写入密钥的输出文件名,如果未指定此选项,则使用标准输出。如果设置了任何加密选项,则会提示输入密码。输出文件名不应与输入文件名相同。

    • -outpubkey filename

      把公钥写入到指定的文件,不指定时不生成公钥

    • -outform DER|PEM

      输出格式,除非指定-genparam,否者默认是PEM格式
      当指定-genparam时-outform选项忽略

    • -verbose

      显示寻找素数的状态点

    • -quiet

      不显示寻找素数的状态点

    • -pass arg

      输出文件的密码来源,参考:https://docs.openssl.org/3.4/man1/openssl-passphrase-options/#pass-phrase-option-arguments

    • -cipher

      加密私钥的算法

    • -algorithm alg

      公私钥算法,可以是RSA, DSA, DH, DHX,如果使用此选项,必须首先存在-pkeyopt 选项选项 -paramfile 和 -algorithm 是互斥的。Engines or providers可能会添加除标准内置算法之外的算法。

      生成私钥时可用的算法包括 RSA, RSA-PSS, EC, X25519, X448, ED25519 and ED448.
      生成参数(-genparam option)时可用的算法包括 DH, DSA and EC.
      请注意,算法名称 X9.42 DH 可用作 DHX 密钥的同义词,PKCS#3 指的是 DH 密钥。DH 和 DHX 密钥之间不共享某些选项。

    • -pkeyopt opt:value

      公钥算法的opt选项值。支持的选项的精确集合取决于所使用的公钥算法及其实现。有关更多详细信息,请参阅下面的“密钥生成选项”和“参数生成选项”。

      要列出算法的可能 opt 值,请使用:openssl genpkey -algorithm XXX -help

    • -genparam

      生成一组私钥参数而不是最终的私钥。如果使用此选项,则必须存在任何 -algorithm、-paramfile 或 -pkeyopt 选项。

    • -paramfile filename

      一些公钥算法根据一组参数生成私钥。可以使用此选项提供这些算法。如果使用此选项,则所使用的公钥算法由此处指定的参数决定。如果使用此选项,则必须存在 -pkeyopt 选项。选项 -paramfile 和 -algorithm 是互斥的。

    • -text

      打印私钥、公钥和参数的(未加密)文本表示以及 PEM 或 DER 结构。

    • -rand files, -writerand file

      指定随机数状态保存的文件,读取之前的随机数生成器状态并写入当前状态用于下次执行的时候继续使用。现在OpenSSL已经从操作系统中读取熵源,这个选项不再需要,只是在特殊情况下才有用。

    • -engine id

      指定engine id,这个选项已经废弃

    • -provider name

      指定provider name

    • -provider-path path

      provider的路径

    • -propquery propq

      provider中的属性

    • -config

      指定备用的配置文件,用于替代默认的openssl.cnf

    key生成选项

    每种算法支持的选项以及算法的每种实现都可能有所不同。OpenSSL 实现的选项详述如下。没有为 X25519、X448、ED25519 或 ED448 算法定义密钥生成选项。

    RSA选项

    -rsa_keygen_bits:numbits

    rsa密钥长度,默认2048位
    
    • rsa_keygen_primes:numprimes

      素数个数,默认是2

    • rsa_keygen_pubexp:value

      The RSA public exponent value. This can be a large decimal or hexadecimal value if preceded by 0x. Default value is 65537.
      RSA 公共指数值。可以是一个较大的10进制或16进制数(如果前面有 0x),默认是 65537。

    RSA-PSS选项

    RSA-PSS应该指的是PSS填充的RSA签名,由PKCS#1 v2.1定义。
    默认没有任何限制

    • rsa_keygen_bits:numbits, rsa_keygen_primes:numprimes, rsa_keygen_pubexp:value

      同RSA

    • rsa_pss_keygen_md:digest

      如果设置只能使用digest签名

    • rsa_pss_keygen_mgf1_md:digest

      如果设置只能使用digest作为 MGF1 parameter.

    • rsa_pss_keygen_saltlen:len

      限制salt的最小长度

    EC选项

    • ec_paramgen_curve:curve

      指定使用的EC曲线. OpenSSL支持NIST曲线,如 “P-256″,也支持国密,如 “SM2”.

    • ec_param_enc:encoding

      The encoding to use for parameters. The encoding parameter must be either named_curve or explicit. The default value is named_curve.
      用于参数的编码。编码参数必须是 named_curve 或 explicit 。默认值为 named_curve。
      使用named_curve时参数文件中只包含代表曲线的OID,使用explicit则包含定义曲线的参数的具体值(这些参数决定了不同的曲线,比如P-256和SM2的曲线参数是不同的)。可以用以下命令观察这两者的区别。

      openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:explicit -text
      openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -text
      

    DH选项

    • -group:name

      The paramfile option is not required if a named group is used here. See the “(DH Parameter Generation Options)(https://docs.openssl.org/3.4/man1/openssl-genpkey/#dh-parameter-generation-options)” section below.
      如果在这指定命名的group,则paramfile option不再是必须的,参考 “(DH Parameter Generation Options)(https://docs.openssl.org/3.4/man1/openssl-genpkey/#dh-parameter-generation-options)”

    参数生成选项

    每种算法支持的选项以及算法的每种实现都可能有所不同

    DSA选项

    DSA算法已被认为不安全,这里不再翻译

    • dsa_paramgen_bits:numbits

      The number of bits in the generated prime. If not specified 2048 is used.

    • dsa_paramgen_q_bits:numbits

    • qbits:numbits

      The number of bits in the q parameter. Must be one of 160, 224 or 256. If not specified 224 is used.

    • dsa_paramgen_md:digest

    • digest:digest

      The digest to use during parameter generation. Must be one of sha1, sha224 or sha256. If set, then the number of bits in q will match the output size of the specified digest and the dsa_paramgen_q_bits parameter will be ignored. If not set, then a digest will be used that gives an output matching the number of bits in q, i.e. sha1 if q length is 160, sha224 if it 224 or sha256 if it is 256.

    • properties:query

      The digest property query string to use when fetching a digest from a provider.

    • type:type

      The type of generation to use. Set this to 1 to use legacy FIPS186-2 parameter generation. The default of 0 uses FIPS186-4 parameter generation.

    • gindex:index

      The index to use for canonical generation and verification of the generator g. Set this to a positive value ranging from 0..255 to use this mode. Larger values will only use the bottom byte. This index must then be reused during key validation to verify the value of g. If this value is not set then g is not verifiable. The default value is -1.

    • hexseed:seed

      The seed seed data to use instead of generating a random seed internally. This should be used for testing purposes only. This will either produced fixed values for the generated parameters OR it will fail if the seed did not generate valid primes.

    DH选项

    对于大多数用例,建议使用 group 选项而不是 type 选项。请注意,如果未指定参数生成选项,则默认不使用 group 选项。

    • group:name

    • dh_param:name

      通过命名的的DH group选择DH参数,如果这里指定值所有其它选项会被忽略
      DH算法的有效的值是:”ffdhe2048″, “ffdhe3072”, “ffdhe4096”, “ffdhe6144”, “ffdhe8192”, “modp_1536”, “modp_2048”, “modp_3072”, “modp_4096”, “modp_6144”, “modp_8192”.
      DHX算法的有效值使用是RFC5114命名,包括: “dh_1024_160”, “dh_2048_224”, “dh_2048_256”.
      group:name和dh_param:name是等效的

    • dh_rfc5114:num

      如果设置这个选项则使用RFC5144参数值生成DHX参数,num可以是1,2,3,分别代表 “dh_1024_160”, “dh_2048_224” or “dh_2048_256″(与使用group:name相同的效果)。使用这个选项时所有其它选项会被忽略。

    • pbits:numbits

    • dh_paramgen_prime_len:numbits

      The number of bits in the prime parameter p. The default is 2048.

    • qbits:numbits

    • dh_paramgen_subprime_len:numbits

      The number of bits in the sub prime parameter q. The default is 224. Only relevant if used in conjunction with the dh_paramgen_type option to generate DHX parameters.

    • safeprime-generator:value

    • dh_paramgen_generator:value

      The value to use for the generator g. The default is 2. The algorithm option must be “DH” for this parameter to be used.

    • type:string

      The type name of DH parameters to generate. Valid values are:

      • “generator”

        Use a safe prime generator with the option safeprime_generator The algorithm option must be “DH”.

      • “fips186_4”

        FIPS186-4 parameter generation. The algorithm option must be “DHX”.

      • “fips186_2”

        FIPS186-4 parameter generation. The algorithm option must be “DHX”.

      • “group”

        Can be used with the option pbits to select one of “ffdhe2048”, “ffdhe3072”, “ffdhe4096”, “ffdhe6144” or “ffdhe8192”. The algorithm option must be “DH”.

      • “default”

        Selects a default type based on the algorithm. This is used by the OpenSSL default provider to set the type for backwards compatibility. If algorithm is “DH” then “generator” is used. If algorithm is “DHX” then “fips186_2” is used.

    • dh_paramgen_type:value

      The type of DH parameters to generate. Valid values are 0, 1, 2 or 3 which correspond to setting the option type to “generator”, “fips186_2”, “fips186_4” or “group”.

    • digest:digest

      The digest to use during parameter generation. Must be one of sha1, sha224 or sha256. If set, then the number of bits in qbits will match the output size of the specified digest and the qbits parameter will be ignored. If not set, then a digest will be used that gives an output matching the number of bits in q, i.e. sha1 if q length is 160, sha224 if it is 224 or sha256 if it is 256. This is only used by “fips186_4” and “fips186_2” key generation.

    • properties:query

      The digest property query string to use when fetching a digest from a provider. This is only used by “fips186_4” and “fips186_2” key generation.

    • gindex:index

      The index to use for canonical generation and verification of the generator g. Set this to a positive value ranging from 0..255 to use this mode. Larger values will only use the bottom byte. This index must then be reused during key validation to verify the value of g. If this value is not set then g is not verifiable. The default value is -1. This is only used by “fips186_4” and “fips186_2” key generation.

    • hexseed:seed

      The seed seed data to use instead of generating a random seed internally. This should be used for testing purposes only. This will either produced fixed values for the generated parameters OR it will fail if the seed did not generate valid primes. This is only used by “fips186_4” and “fips186_2” key generation.

    EC选项

    与生成密钥时相同

    注意:

    与算法特定的实用程序相比,鼓励使用 genpkey 程序,因为可以使用附加算法选项和 ENGINE 提供的算法。

    Views: 1

  • openssl-genrsa

    openssl-genrsa

    名称

    openssl-genrsa – generate an RSA private key

    概述

    openssl genrsa [-help] [-out filename] [-passout arg] [-aes128] [-aes192] [-aes256] [-aria128] [-aria192] [-aria256] [-camellia128] [-camellia192] [-camellia256] [-des] [-des3] [-idea] [-F4] [-f4] [-3] [-primes num] [-verbose] [-quiet] [-traditional] [-rand files] [-writerand file] [-engine id] [-provider name] [-provider-path path] [-propquery propq] [numbits]

    描述

    这个命令可以生成RSA私钥

    命令语法

    • -help

      帮助

    • -passout arg

      写入密钥文件时的密码

    • -out

      指定要写入密钥的输出文件名,如果未指定此选项,则使用标准输出。如果设置了任何加密选项,则会提示输入密码。输出文件名不应与输入文件名相同。

    • -aes128, -aes192, -aes256, -aria128, -aria192, -aria256, -camellia128, -camellia192, -camellia256, -des, -des3, -idea

      指定加密密钥的算法
      输出私钥之前,会使用指定的加密算法对其进行加密。系统会提示输入密码。如果未指定任何加密算法,则密钥将以纯文本形式写入。如果使用加密,则如果未通过 -passout 参数提供密码,则会提示输入密码。

    • -F4, -f4, -3

      要使用的公共指数,65537 或 3。默认值为 65537。-3 选项已被弃用。

    • -primes num

      指定生成 RSA 密钥时要使用的素数数量。num 参数必须是大于 1 且小于 16 的正整数。如果 num 大于 2,则生成的密钥称为“多素数”RSA 密钥,该用法在 RFC 8017 中定义。多素数会减少计算量,但也会降低复杂度,素数越多素数的长度越短。
      默认情况下是2个素数,经过我的测试可以指定以下值

      素数数量 最短私钥长度
      5 8192
      4 4096
      3 1024
      2 512
    • -verbose

      执行时输出更多的信息

    • -quiet

      输出更少的信息,这在批处理和使用管道时很方便,尤其是密钥生成期间抑制进度.的输出。

    • -traditional

      写入密钥时使用PKCS#1格式,默认是PKCS#8格式。PKCS#1仅能存储RSA密钥,PKCS#8是对PKCS#1的升级可以支持多种算法密钥存储。

    • -rand files, -writerand file

      指定随机数状态保存的文件,读取之前的随机数生成器状态并写入当前状态用于下次执行的时候继续使用。现在OpenSSL已经从操作系统中读取熵源,这个选项不再需要,只是在特殊情况下才有用。

    • -engine id

      指定engine id,这个选项已经废弃

    • -provider name

      指定provider name

    • -provider-path path

      provider的路径

    • -propquery propq

      provider中的属性

    • numbits

      要生成的私钥的大小(以bit为单位)。这必须是指定的最后一个选项。默认值为 2048,不允许小于 512 的值。注意这个是参数而不是选项。

    NOTES

    RSA 私钥生成本质上涉及两个或多个素数的生成。生成私钥时,将输出各种符号以指示生成的进度。 . 表示每个数字都已通过初始筛选测试,+ 表示数字已通过一轮 Miller-Rabin 素数测试,* 表示当前素数由于一些测试失败而开始重新生成。换行符表示数字已通过所有素数测试(实际数量取决于密钥大小)。

    由于 Miller-Rabin 素数测试是概率性测试,测试素数时根据待测试数的位长度自动选择合适的轮数来增加准确性。以下是一些常见位长度下的默认轮数:

    • 对于512位以下的数,默认轮数为 8。
    • 对于512位到1024位的数,默认轮数为 5。
    • 对于1024位到2048位的数,默认轮数为 4。
    • 对于2048位到4096位的数,默认轮数为 3。
    • 对于4096位以上的数,默认轮数为 2。

    由于密钥生成是一个随机过程,因此生成密钥所需的时间可能会有所不同。但一般来说,素数越多,密钥的生成时间越短。

    Views: 3

  • openssl-pkeyutl

    公钥算法命令

    概要

    openssl pkeyutl [-help] [-in file] [-rawin] [-digest algorithm] [-out file] [-sigfile file] [-inkey filename|uri] [-keyform DER|PEM|P12|ENGINE] [-passin arg] [-peerkey file] [-peerform DER|PEM|P12|ENGINE] [-pubin] [-certin] [-rev] [-sign] [-verify] [-verifyrecover] [-encrypt] [-decrypt] [-derive] [-kdf algorithm] [-kdflen length] [-pkeyopt opt:value] [-pkeyopt_passin opt[:passarg]] [-hexdump] [-asn1parse] [-engine id] [-engine_impl] [-rand files] [-writerand file] [-provider name] [-provider-path path] [-propquery propq] [-config configfile]

    描述

    这个命令用于执行low-level的公钥操作,支持任何openssl支持的算法
    默认情况下假定使用-sign操作

    选项

    • -help

      Print out a usage message.

    • -in filename

      指定输入数据的文件名,如果不指定则从标准输入读取

    • -rawin

      这个选项指示要签名和验证的输入数据是raw数据,即没有使用摘要算法处理过,除EdDSA外还可以指定-digest选项。对于签名算法,像RSA,DSA,ECDSA,默认的摘要算法是SHA-256,对于SM2则是SM3摘要算法。
      这个选项只能与-sign和-verify一起使用,对于EdDSA(Ed25519和Ed448算法)这个选项是必须的。

    • -digest algorithm

      此选项只能与 -sign 和 -verify 一起使用。它指定在使用输入密钥对输入数据进行签名或验证之前用于对输入数据进行哈希处理的摘要算法。如果签名算法在签名之前不需要通过pluggable哈希函数对输入进行预处理(例如,EdDSA),则可以省略此选项。如果省略此选项但签名算法需要该选项并且给出了 -rawin 选项,则将使用默认值(有关详细信息,请参阅 -rawin)。如果存在-digest选项,则需要与 -rawin 选项一起使用。
      目前,不支持 HashEdDSA(EdDSA 的 ph 或“prehash”变体),因此 -digest 选项不能与 EdDSA 一起使用。

    • -out filename

      指定输出文件名,默认写入到标准输出

    • -sigfile file

      签名的数据文件,只与-verify选项一起使用。

    • -inkey filename|uri

      输入的密钥,默认是一个私钥。

    • -keyform DER|PEM|P12|ENGINE

      密钥格式; unspecified by default

    • -passin arg

      The input key password source. For more information about the format of arg see openssl-passphrase-options(1).

    • -peerkey file

      指定的文件包含对方的公钥,用于密钥交换(派生)操作

    • -peerform DER|PEM|P12|ENGINE

      The peer key format; unspecified by default. See openssl-format-options(1) for details.

    • -pubin

      当存在这个选项时从-inkey读取的是公钥而不是私钥,如果输入是一个私钥,则使用其公钥部分。

    • -certin

      从证书中读取公钥

    • -rev

      反转输入缓冲区的字节序。这对于某些以小端格式表示缓冲区的库(如 CryptoAPI)很有用。这不能与 -rawin 一起使用。

    • -sign

      对输入数据进行签名并输出签名结果。这需要私钥。建议同时使用消息摘要操作,如适用,请参阅 -rawin 和 -digest 选项了解详情。否则,使用 -in 选项给出的输入数据将被视为已经是摘要,但在某些情况下可能需要额外的 -pkeyopt digest:md(例如,使用默认 PKCS#1 填充模式的 RSA)。即使对于其他算法(如 ECDSA),额外的 -pkeyopt 选项不会影响签名输出,也建议使用,因为它可以检查输入长度是否与预期摘要一致。

    • -verify

      根据 -sigfile 选项给出的签名验证输入数据,并指示验证是成功还是失败。除非指定或暗示了 -rawin 选项,否则 -in 选项给出的输入数据将被视为哈希值。对于原始数据,当摘要算法适用时,尽管可以从签名推断出所用的摘要算法或采用默认值,但也应指定摘要算法。

    • -verifyrecover

      验证给定的签名并输出恢复的recovered data(signature payload,即原始数据,如果有的话)。例如,对于 RSA PKCS#1,恢复的数据是摘要算法 OID 和值的 EMSA-PKCS-v1_5 DER 编码,如 RFC8017(PKCS#1 2.2) 第 9.2 节中所述。
      请注意,此处使用 -in 选项给出的输入不是签名输入(待签名数据)(与 -sign 和 -verify 选项一样),而是签名输出值(签名结果),通常使用 -sign 选项生成。
      此选项仅适用于 RSA 密钥。

    • -encrypt

      使用一个公钥加密数据

    • -decrypt

      使用一个私钥解密数据

    • -derive

      使用peer key派生(Derive)一个共享秘密值

    • -kdf algorithm

      使用的密钥派生函数算法。目前支持的算法有 TLS1-PRF 和 HKDF。注意:通常必须设置附加参数和 KDF 输出长度才能使其正常工作。请参阅 EVP_PKEY_CTX_set_hkdf_md(3) 和 EVP_PKEY_CTX_set_tls1_prf_md(3) 了解每种算法支持的字符串参数。

    • -kdflen length

      指定KDF函数的输出长度

    • -pkeyopt opt:value

      用opt:value格式指定的公钥选项。详情看下面NOTES部分

    • -pkeyopt_passin opt[:passarg]

      允许从 stdin 或密码源读取公钥选项 opt。如果仅指定 opt,系统将提示用户在 stdin 上输入密码。或者,可以指定 passarg,它可以是 openssl-passphrase-options(1) 支持的任何值。

    • -hexdump

      输出数据的16进制

    • -asn1parse

      解析 ASN.1 输出数据以检查其 DER 编码并打印任何错误。与 -verifyrecover 选项结合使用时,这可能仅在 ASN.1 DER 编码结构已直接签名(未对其进行哈希处理)的情况下才有用。

    • -engine id

      See “Engine Options” in openssl(1). This option is deprecated.

    • -engine_impl

      When used with the -engine option, it specifies to also use engine id for crypto operations.

    • -rand files, -writerand file

      See “Random State Options” in openssl(1) for details.

    • -provider name

    • -provider-path path

    • -propquery propq

      See “Provider Options” in openssl(1), provider(7), and property(7).

    • -config configfile

      See “Configuration Option” in openssl(1).

    NOTES

    支持的操作和选项因密钥算法及其实现而异。OpenSSL 操作和选项如下所示。

    除非另有说明,所有算法都支持 digest:alg 选项,该选项指定用于签名和验证操作的摘要。值 alg 应表示 EVP_get_digestbyname() 函数中使用的摘要算法名称,例如 sha1。此值不用于对输入数据进行哈希处理。它(由某些算法)用于对传入的数据长度进行健全性检查,并用于创建组成签名的结构(例如 RSASSA PKCS#1 v1.5 签名中的 DigestInfo)。

    此命令不对输入数据进行哈希处理(使用 -rawin 的情况除外),而是将数据直接用作签名算法的输入。根据密钥类型、签名类型和填充模式,输入数据的最大可接受长度会有所不同。签名数据不能长于 RSA 的密钥模数。对于 ECDSA 和 DSA,数据的长度不应超过字段大小,否则将被默默截断为字段大小。无论如何,输入大小不得大于支持的最大摘要大小。

    换句话说,如果摘要的值是 sha1,则输入应该是 SHA-1 哈希函数输出的 20 字节长的二进制编码。(所以输入数据应该事先用Hash处理,避免数据超过长度,使用 -rawin 的情况除外)

    RSA算法

    RSA-PSS 算法是 RSA 算法的受限版本,仅支持使用 PSS 填充的签名和验证操作。支持以下附加 -pkeyopt 值:

    • rsa_padding_mode:mode, rsa_pss_saltlen:len, rsa_mgf1_md:digest

      这些与 RSA 算法含义相同,但有一些额外的限制。填充模式只能设置为 pss,这是默认值。
      如果密钥有参数限制,则摘要、MGF1 摘要和盐长度将设置为参数中指定的值。摘要(-digest指定,且本命令不做Hash处理)和 MG(mgf1) 不能更改,盐长度不能设置为小于最小限制的值。

    DSA算法

    DSA 算法仅支持签名和验证操作。目前除了 digest 之外没有其他 -pkeyopt 选项。默认采用 SHA1 摘要。

    DH算法

    DH算法只支持密钥派生操作,没有-pkeyopt选项

    EC ALGORITHM

    EC 算法支持签名、验证和派生操作。签名和验证操作使用 ECDSA,派生使用 ECDH。-pkeyopt digest选项默认采用 SHA1。

    X25519 AND X448 算法

    X25519 and X448算法只支持密钥派生操作,没有-pkeyopt选项

    SM2

    SM2 算法支持签名、验证、加密和解密操作。对于签名和验证操作,SM2 需要传入 Distinguishing ID 字符串。支持以下 -pkeyopt 值:

    • distid:string

      设置SM2签名或验证操作中使用的ID字符串。验证SM2签名时,ID字符串必须与签名数据时使用的相同。否则验证将失败。

    • hexdistid:hex_string

      此项设置 SM2 签名或验证操作中使用的 ID 字符串。验证 SM2 签名时,ID 字符串必须与签名数据时使用的字符串相同。否则验证将失败。此选项提供的 ID 字符串应为有效的十六进制值。

    示例

    • DH

      生成公共参数p和g(DH参数,p是个素数)

      openssl dhparam -out dhparam.pem 2048

      生成本地的随机秘密值及对应的公开参数(本地密钥对,a是私钥,A = ga mod p是公钥)

      openssl genpkey -paramfile dhparam.pem -out local_private_key.pem
      openssl pkey -in local_private_key.pem -pubout -out local_public_key.pem

      生成方对的随机秘密值及对应的公开参数(对方密钥对,b,B = gb mod p)

      openssl genpkey -paramfile dhparam.pem -out peer_private_key.pem
      openssl pkey -in peer_private_key.pem -pubout -out peer_public_key.pem

      计算共享秘密值

      openssl pkeyutl -derive -inkey local_private_key.pem -peerkey peer_public_key.pem -out shared_key.bin

    • ECDH

      生成本地ECC密钥对(ECDH的域参数对于一个特定的曲线来说是固定的,所以已经包含在密钥对中了,域参数包含了G值,G值双方共享的公共参数,对应DH算法中的p和g)

      openssl ecparam -name prime256v1 -genkey -noout -out local_private_key.pem
      openssl ec -in local_private_key.pem -pubout -out local_public_key.pem

      生成对方ECC密钥对

      openssl ecparam -name prime256v1 -genkey -noout -out peer_private_key.pem
      openssl ec -in peer_private_key.pem -pubout -out peer_public_key.pem

      派生共享秘密值

      openssl pkeyutl -derive -inkey local_private_key.pem -peerkey peer_public_key.pem -out shared_key.bin

    • RSA加解密

      生成私钥

      openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

      生成公钥

      openssl pkey -in private_key.pem -pubout -out public_key.pem

      公钥加密

      openssl pkeyutl -in .\msg.txt -inkey .\public_key.pem -pubin -encrypt -out encrypted.bin

      私钥解密

      openssl pkeyutl -in .\encrypted.bin -inkey private_key.pem -decrypt

      openssl虽然支持私钥加密,但没有提供私解解密的功能

    • SM2加解密

      生成sm2密钥对

      openssl genpkey -algorithm sm2 -out sm2.key -outpubkey sm2_pub.pem

      公钥加密

      openssl pkeyutl -in .\msg.txt -inkey .\sm2.key -encrypt -out enc_pub.txt

      私钥解密

      openssl pkeyutl -decrypt -inkey .\sm2.key -in .\enc_pub.txt

    • RSA签名和验签

      签名

      openssl pkeyutl -sign -in msg.txt -rawin -inkey rsa.key -out msg.txt.sig

      验签

      openssl pkeyutl -verify -in msg.txt -sigfile msg.txt.sig -inkey .\rsapub.pem -pubin -rawin

    • RSA带数据恢复签名

      pkeyutl命令签名(不要使用-rawin选项,否者恢复出来的就是hash值了,而且仅支持pkcs1.5填充)

      openssl pkeyutl -sign -in msg.txt -inkey rsa.key -out msg.txt.sig -pkeyopt rsa_padding_mode:pkcs1

      rsautl命令

      openssl rsautl -sign -in msg.txt -inkey rsa.key -out sig -pkcs

      pkeyutl命令恢复数据

      openssl pkeyutl -verifyrecover -in sig -inkey .\rsapub.pem -pubin

      rsautl命令恢复数据

      openssl rsautl -verify -in sig -inkey rsapub.pem -pubin

    Views: 52

  • openssl-pkeyparam

    公钥算法参数处理命令

    概要

    openssl pkeyparam [-help] [-in filename] [-out filename] [-text] [-noout] [-check] [-engine id] [-provider name] [-provider-path path] [-propquery propq]

    描述

    此命令处理公钥算法参数。可以检查它们的正确性并打印出它们的组成部分。

    选项

    -help

    Print out a usage message.
    

    -in filename

    如果未指定此选项,则标准输入读取数据。
    

    -out filename

    如果不指定,则写入标准输出
    

    -text

    除了编码版本之外,还打印出纯文本形式的参数。
    

    -noout

    Do not output the encoded version of the parameters.
    不输出编码格式的参数
    

    -check

    该选项检查参数的正确性。
    

    -engine id

    See "Engine Options" in openssl(1). This option is deprecated.
    

    -provider name
    -provider-path path

    -propquery propq

    See "Provider Options" in openssl(1), provider(7), and property(7).~~
    

    Views: 2

  • openssl-pkey

    openssl-pkey

    名称

    openssl-pkey – public or private key processing command

    概述

    openssl pkey [-help] [-engine id] [-provider name] [-provider-path path] [-propquery propq] [-check] [-pubcheck] [-in filename|uri] [-inform DER|PEM|P12|ENGINE] [-passin arg] [-pubin] [-out filename] [-outform DER|PEM] [-cipher] [-passout arg] [-traditional] [-pubout] [-noout] [-text] [-text_pub] [-ec_conv_form arg] [-ec_param_enc arg]

    描述

    此命令处理公钥或私钥。它们可以在各种形式之间转换,并打印其组成部分。

    命令语法

    通用命令

    • -help

      帮助

    • -engine id

      指定engine id,这个选项已经废弃

    • -provider name

      指定provider name

    • -provider-path path

      provider的路径

    • -propquery propq

      provider中的属性

    输入命令

    • -in filename|uri

      指定密钥文件的路径,如果不指定则从终端读取,如果有密码还会提示输入密码

    • -inform DER|PEM|P12|ENGINE

      读取的密钥格式

    • -passin arg

      指定读取密钥文件时的密码

    • -pubin

      默认情况下,从输入中读取私钥。使用此选项则改为读取公钥。如果输入不包含公钥但包含私钥,则使用其公钥部分(This option is automatically set if the input is a public key.)。
      实际测试指定这个选项时只读取公钥,不指定时私钥和公钥都会读取。

    输出命令

    • -out

      指定要写入密钥的输出文件名,如果未指定此选项,则使用标准输出。如果没有指定-passout,则会提示输入密码。输出文件名不应与输入文件名相同。

    • -outform DER|PEM

      写入的密钥格式

    • -cipher

      加密私钥pem的算法。EVP_get_cipherbyname() 接受的任何算法名称都是可以接受的,例如 aes128。DER 输出不支持加密。

    • -passout arg

      指定写入密钥文件时的密码

    • -traditional

      写入密钥时使用PKCS#1格式,默认是PKCS#8格式。PKCS#1仅能存储RSA密钥,PKCS#8是对PKCS#1的升级可以支持多种算法密钥存储。
      所以并不是所有算法都支持-traditional选项,我测试的结果是指定-traditional选项时RSA会用PKCS#1格式,P-256会用CMP PKI Mesaage格式,SM2和Ed25519等较新的算法则完全不支持

    • -pubout

      输出公钥而不是私钥
      实际测试指定这个选项时只输出公钥,不指定时私钥和公钥都会输出,如果都有的话。

    • -noout

      不打印编码的私钥

    • -text

      除了编码版本外还以文本方式打印私钥的内容

    • -text_pub

      仅输出公钥的文本部分 (also for private keys). 输出PEM格式时不可用.

    • -ec_conv_form arg

      仅支持ECC算法

      This specifies how the points on the elliptic curve are converted into octet strings. Possible values are: compressed (the default value), uncompressed and hybrid. For more information regarding the point conversion forms please read the X9.62 standard. Note Due to patent issues the compressed option is disabled by default for binary curves and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at compile time.
      曲线的点转换到字节组时的方法,可以是compressed (the default value), uncompressed and hybrid,因为专利问题binary curves默认是禁用压缩的。(啥是binary curves我也不懂)

    • -ec_param_enc arg

      仅支持ECC算法
      This specifies how the elliptic curve parameters are encoded. Possible value are: named_curve, i.e. the ec parameters are specified by an OID, or explicit where the ec parameters are explicitly given (see RFC 3279 for the definition of the EC parameters structures). The default value is named_curve. Note the implicitlyCA alternative, as specified in RFC 3279, is currently not implemented in OpenSSL.
      用于曲线参数的编码。编码参数必须是 named_curve 或 explicit 。默认值为 named_curve。
      使用named_curve时参数文件中只包含代表曲线的OID,使用explicit则包含定义曲线的参数的具体值(这些参数决定了不同的曲线,比如P-256和SM2的曲线参数是不同的)。

    Views: 4

  • openssl-rsautl

    RSA算法命令

    概要

    openssl rsautl [-help] [-in file] [-passin arg] [-rev] [-out file] [-inkey filename|uri] [-keyform DER|PEM|P12|ENGINE] [-pubin] [-certin] [-sign] [-verify] [-encrypt] [-decrypt] [-pkcs] [-x931] [-oaep] [-raw] [-hexdump] [-asn1parse] [-engine id] [-rand files] [-writerand file] [-provider name] [-provider-path path] [-propquery propq]

    描述

    此命令已弃用。应改用 openssl-pkeyutl(1) 命令。
    此命令可用于使用 RSA 算法对数据进行签名、验证、加密和解密。

    选项

    -help

    Print out a usage message.
    

    -in filename

    指定输入数据的文件名,如果不指定则从标准输入读取
    

    -passin arg

    The passphrase used in the output file. See see openssl-passphrase-options(1).
    原文是不是写错了,应该是输入文件的密码吧
    

    -rev

    反转输入缓冲区的字节序
    

    -out filename

    指定输出文件名,默认写入到标准输出
    

    -inkey filename|uri

    输入的密钥,默认是一个RSA私钥。
    

    -keyform DER|PEM|P12|ENGINE

    密钥格式; unspecified by default
    

    -pubin

    当存在这个选项时从-inkey读取的是公钥而不是私钥,如果输入是一个私钥,则使用其公钥部分。
    

    -certin

    从证书中读取公钥
    

    -sign

    对输入的数据进行签名并输出签名的结果。要求指定RSA私钥。
    

    -verify

    验证输入的数据并输出恢复的数据。
    

    -encrypt

    使用RSA公钥加密输入的数据
    

    -decrypt

    使用RSA私钥解密输入的数据
    

    -pkcs, -oaep, -x931, -raw

    使用的填充方式: PKCS#1 v1.5 (the default), PKCS#1 OAEP, ANSI X9.31, or no padding, respectively. 对于签名, only -pkcs and -raw 能使用.
    注意:由于有针对 Bleichenbacher 攻击的保护,如果填充检查失败,使用 PKCS#1 v1.5 模式解密将不会返回错误。使用 -raw 并手动检查返回值以检查填充是否正确。
    

    -hexdump

    输出数据的16进制
    

    -asn1parse

    解析 ASN.1 输出数据以检查其 DER 编码并打印任何错误。通常与 -verify 选项结合使用时
    

    -engine id

    See "Engine Options" in openssl(1). This option is deprecated.
    

    -rand files, -writerand file

    See "Random State Options" in openssl(1) for details.
    

    -provider name
    -provider-path path

    -propquery propq

    See “Provider Options” in openssl(1), provider(7), and property(7).

    NOTES

    由于该命令直接使用RSA算法,因此只能用于签名或验证小块数据。

    Views: 18

  • openssl-rsa

    openssl-rsa

    名字

    openssl-rsa – RSA key processing command

    概述

    openssl rsa [-help] [-inform DER|PEM|P12|ENGINE] [-outform DER|PEM] [-in filename|uri] [-passin arg] [-out filename] [-passout arg] [-aes128] [-aes192] [-aes256] [-aria128] [-aria192] [-aria256] [-camellia128] [-camellia192] [-camellia256] [-des] [-des3] [-idea] [-text] [-noout] [-modulus] [-traditional] [-check] [-pubin] [-pubout] [-RSAPublicKey_in] [-RSAPublicKey_out] [-pvk-strong] [-pvk-weak] [-pvk-none] [-engine id] [-provider name] [-provider-path path] [-propquery propq]

    描述

    此命令处理 RSA 密钥。它们可以在各种形式之间转换,并打印出它们的组成部分。

    选项

    • -help

      帮助

    • -inform DER|PEM|P12|ENGINE

      读取的密钥格式

    • -outform DER|PEM

      写入的密钥格式

    • -traditional

      写入密钥时使用PKCS#1格式,默认是PKCS#8格式。PKCS#1仅能存储RSA密钥,PKCS#8是对PKCS#1的升级可以支持多种算法密钥存储。

    • -in filename|uri

      指定密钥文件的路径,如果不指定则从终端读取,如果有密码还会提示输入密码

    • -passin arg, -passout arg

      指定读取和写入密钥文件时的密码

    • -out

      指定要写入密钥的输出文件名,如果未指定此选项,则使用标准输出。如果设置了任何加密选项,则会提示输入密码。输出文件名不应与输入文件名相同。

    • -aes128, -aes192, -aes256, -aria128, -aria192, -aria256, -camellia128, -camellia192, -camellia256, -des, -des3, -idea

      指定加密密钥的算法
      输出私钥之前,会使用指定的加密算法对其进行加密。系统会提示输入密码。如果未指定任何加密算法,则密钥将以纯文本形式写入。这意味着,此命令可用于通过不提供任何加密选项来从密钥中删除密码,或者通过设置密码来添加或更改密码。这些选项只能用于 PEM 格式的输出文件(These options can only be used with PEM format output files.DER不加密吗)。

    • -text

      除了编码版本外还以文本方式打印私钥的内容

    • -noout

      不打印编码的私钥

    • -modulus

      打印私钥的模数

    • -check

      检查私钥的完整性

    • -pubin

      默认情况下,从输入中读取私钥。使用此选项则改为读取公钥。如果输入不包含公钥但包含私钥,则使用其公钥部分(This option is automatically set if the input is a public key.)。
      实际测试指定这个选项时只读取公钥,不指定时私钥和公钥都会读取。

    • -pubout

      输出公钥而不是私钥
      实际测试指定这个选项时只输出公钥,不指定时私钥和公钥都会输出,如果都有的话。

    • RSAPublicKey_in, -RSAPublicKey_out

      同-pubin和-pubout,只不过用RSAPublicKey格式代替

    • -pvk-strong

      开启强PVK encoding level,默认开启。
      pvk是微软开发的私钥存储格式,使用pvk格式文件时生效,我测试时使用-outform pvk只有指定-pvk-none才成功生成pvk格式的私钥

    • -pvk-weak

      开启弱PVK encoding level

    • -pvk-none

      不使用PVK encoding

    • -engine id

      指定engine id,这个选项已经废弃

    • -provider name

      指定provider name

    • -provider-path path

      provider的路径

    • -propquery propq

      provider中的属性

    Views: 2

  • OpenSSL配置文件

    OpenSSL配置文件

    语法

    1. 包含其它文件

      “`openssl cnf
      .include [=] pathname # 相对路径
      .pragma [=] abspath:value # 绝对路径
      .pragma [=] dollarid:value # 路径包含变量
      “`
      注释使用`#`

    2. section

      一个配置文件包含若干个section,一个section由用方括号包围的secton name开始,直到另一个section结束。section name和方括号之间的空白符会被忽略。
      环境变量会映射到ENV section。
      如下所示:

      “`openssl cnf
      [ section ]
      name1 = This is value1
      name2 = Another value

      [ newsection ]
      name1 = New value1
      name3 = Value 3

      <pre><code class="line-numbers">从文件开始到第一个section出现之前的配置属于default section,default section是OpenSSL首先读取的section。
      在一个section不允许出现重复的字段名,后面的值会覆盖前面的值,但是有时候又需要配置重复的字段,所以当需要一个字段多次配置时需要加前缀。
      如下所示:
      “`openssl cnf
      1.OU = First OU
      2.OU = Second OU

      “.”及前面的数字会被忽略,把这些字段当成相同的字段。
      value在”=”号后面直到行尾,两边的空白符会被移除
      通过$var or ${var}可以引用当前section中的变量,通过$section::name or ${section::name}可以引用其它section的变量,通过$ENV::name引用环境变量。
      如果一个value超过64k会报错,value可以使用单/双引号包围,可以使用转义字符,如查多行字符则以\结尾。

    模块配置

    “`openssl cnf
    config_diagnostics = 1
    openssl_conf = openssl_init

    [openssl_init]
    oid_section = oids
    providers = providers
    alg_section = evp_properties
    ssl_conf = ssl_configuration
    engines = engines
    random = random

    [oids]
    shortName = a very long OID name, 1.2.3.4
    newoid1 = 1.2.3.4.1
    some_other_oid = 1.2.3.5

    [providers]
    … provider stuff here …

    [evp_properties]
    … EVP properties here …

    [ssl_configuration]
    … SSL/TLS configuration properties here …

    [engines]
    … engine properties here …

    [random]
    … random properties here …

    <pre><code class="line-numbers">openssl_init section中指定了每个模块对应的section。
    oids section是用来新增自己的oid的,由两种语法

    – 包含长名称

    shortName = a very long OID name, 1.2.3.4

    – 不包含长名称

    newoid1 = 1.2.3.4.1
    some_other_oid = 1.2.3.5
    字段的名称就是oid的短名称,长名称是可选的

    ## Provider 配置

    Openssl3.0引入了Provider的概念,把一组算法独立出来放在一个模块中称为一个Provider。对Provider使用动态加载,使算法的实现独立于Openssl本身。

    </code></pre>

    [providers]
    foo = foo_provider # providers列表

    [foo_provider]
    identity = my_fips_module # 备用名
    module = /var/lib/openssl/module1.so # 模块位置
    activate = yes # 是否激活

    <h3>EVP 配置</h3>

    用于指定EVP算法的默认属性

    “`openssl cnf
    [evp_properties]
    default_properties = fips=yes

    ## SSL 配置
    
    

    [ssl_configuration]
    server = server_tls_config
    client = client_tls_config
    system_default = tls_system_default

    [server_tls_config]
    … configuration for SSL/TLS servers …

    [client_tls_config]
    … configuration for SSL/TLS clients …

    [tls_system_default]
    MinProtocol = TLSv1.2
    MinProtocol = DTLSv1.2

    initialization section中的ssl_conf配置指定TLS模块的配置,其它每个配置项都指向另一个section name。
    system_default配置有特殊含义,如果存在的话,指示系统范围内的最低TLS/DTLS版本。同样也可以指定MaxProtocol限定最大版本。
    
    ## Engine 配置
    
    硬件加速器的配置
    
    

    [engines]
    foo = foo_engine

    [foo_engine]
    dynamic_path = /some/path/fooengine.so
    init = 1 # 指定0不初始化,指定1立即初始化,不指定则在所有其它命令处理完后初始化
    some_ctrl = some_value
    default_algorithms = ALL # 应用的默认算法集合
    other_ctrl = EMPTY

    “`

    <h2>Random 配置</h2>

    配置随机数生成器的参数

    <ul>
    <li>random 指定随机数生成器

    “`openssl cnf
    [random]
    random = CTR-DRBG # 支持CTR-DRBG,HASH-DRBG,HMAC-DRBG
    “`

  • cipher

    指定生成器的算法,默认值是AES-256-CTR

  • digest

    指定随机数的摘要算法,HASH-DRBG or HMAC-DRBG

  • properties

    指定底层算法的属性

  • seed

    使用的随机数来源,默认为SEED-SRC,表示使用FIPS provider。

  • seed_properties

    随机数源的属性

环境变量

  • OPENSSL_CONF

    配置文件的路径

  • OPENSSL_ENGINES

    ENGINES的路径,ENGINE是对硬件加速器的封装。

  • OPENSSL_MODULES

    指定openssl模块的路径,也就是provider

  • OPENSSL_CONF_INCLUDE

    指定include时的目录前缀

以上配置是OpenSSL主命令的配置,具体命令的配置还要参考具体命令下的说明。通常子命令的名字就是section的名字。

openssl version -d命令可以显示默认openssl.cnf文件的位置,这是默认的配置文件。很多命令会通过-config选项指定配置文件读取部分或全部配置参数。可以通过OPENSSL_CONF环境变量指定不同的默认配置文件或者禁用配置文件(环境变量指定空字符串)

Views: 67

  • x509v3_config

    X509 V3 certificate extension configuration format

    描述

    多个 OpenSSL 命令可以根据配置文件的内容和 CLI 选项(例如 -addext)向证书或证书请求添加扩展。配置文件的语法在 config(5) 中描述。这些命令通常有一个选项来指定配置文件的名称以及该文件中的部分;有关详细信息,请参阅单个命令的文档。

    本文档使用extensions作为v3扩展的section name.
    在扩展section中每个项目如下所示:

    “`openssl cnf
    name = [critical, ]value(s)

    <pre><code class="line-numbers">如果critical关键词存在则标记为关键扩展

    如果为同一扩展名处理多个条目,则后面的条目将覆盖前面的同名条目。

    值的格式取决于名称的值,许多值具有type-value对,其中类型和值由冒号分隔。扩展主要有四种类型:string,multi-valued,raw,arbitrary.
    以下段落将描述每种类型:

    string扩展仅包含一个字符串,其中包含值本身或获取值的方式。

    multi-valued扩展具有短格式和长格式。短格式是逗号分隔的名称和值列表:
    “`openssl cnf
    basicConstraints = critical, CA:true, pathlen:1

    长格式允许将值放在单独的section中:

    “`openssl cnf
    [extensions]
    basicConstraints = critical, @basic_constraints

    [basic_constraints]
    CA = true
    pathlen = 1

    <pre><code class="line-numbers">两种格式是等效的。

    如果扩展是多值的,并且字段值包含逗号,则必须使用长格式,否则逗号将被误解为字段分隔符。例如:
    “`openssl cnf
    subjectAltName = URI:ldap://somehost.com/CN=foo,OU=bar
    ““
    这样会产生错误,但与以下格式等效
    “`openssl cnf
    [extensions]
    subjectAltName = @subject_alt_section

    [subject_alt_section]
    subjectAltName = URI:ldap://somehost.com/CN=foo,OU=bar
    </code></pre>

    OpenSSL 不支持在一个section中多次出现同一字段。在此示例中:

    “`openssl cnf
    [extensions]
    subjectAltName = @alt_section

    [alt_section]
    email = steve@example.com
    email = steve@example.org

    只会识别最后一个值。要指定多个值,请附加数字标识符,如下所示:
    ```opensl cnf
    [extensions]
    subjectAltName = @alt_section
    
    [alt_section]
    email.1 = steve@example.com
    email.2 = steve@example.org
    </code></pre>
    
    The syntax of raw extensions is defined by the source code that parses the extension but should be documented. See "Certificate Policies" for an example of a raw extension.
    raw扩展的语法由解析扩展的源代码定义,但应有文档记录。请参阅"<a class="wp-editor-md-post-content-link" href="https://docs.openssl.org/3.4/man5/x509v3_config/#certificate-policies">Certificate Policies</a>" 了解raw扩展的示例。
    
    如果扩展类型不受支持,则必须使用arbitrary扩展语法,有关更多详细信息,请参阅<a class="wp-editor-md-post-content-link" href="https://docs.openssl.org/3.4/man5/x509v3_config/#arbitrary-extensions">"ARBITRARY EXTENSIONS"</a>部分。
    
    <h2>STANDARD EXTENSIONS</h2>
    
    <ul>
    <li>Basic Constraints
    
    这是一个multi-valued扩展,用于指示证书是否为 CA 证书。第一个值是 CA,后跟 TRUE 或 FALSE。如果 CA 为 TRUE,则可以包含可选的路径长度名称,后跟非负值。
    
    ```openssl cnf
    basicConstraints = CA:TRUE
    
    
    basicConstraints = CA:FALSE
    
    basicConstraints = critical, CA:TRUE, pathlen:1
    
    ```
    CA 证书必须包含 basicConstraints ,并将 CA 参数设置为 TRUE。最终用户证书必须具有 CA:FALSE 或完全省略此扩展。pathlen 参数指定链中可在此 CA 下出现的 CA 的最大数量。pathlen 为零表示 CA 不能签署任何子 CA,而只能签署最终实体证书。
    </p></li>
    <li><p>Key Usage
    
    Key Usage是一个multi-valued扩展,由允许的密钥用法的name列表组成。定义的值有:digitalSignature、nonRepudiation、keyEncipherment、dataEncipherment、keyAgreement、keyCertSign、cRLSign、encipherOnly 和 decipherOnly。
    示例:
    
    ```openssl cnf
    keyUsage = digitalSignature, nonRepudiation
    
    
    keyUsage = critical, keyCertSign
    
    ```
    </p></li>
    <li><p>Extended Key Usage
    
    This extension consists of a list of values indicating purposes for which the certificate public key can be used. Each value can be either a short text name or an OID. The following text names, and their intended meaning, are known:
    此扩展由一系列指示证书公钥的用途的值组成。每个值都可以是短文本名称或 OID。以下是已知的文本名称及其预期含义:
    
    <table>
    <thead>
    <tr>
      <th>Value</th>
      <th>Meaning according to RFC 5280 etc.</th>
    </tr>
    </thead>
    <tbody>
    <tr>
      <td>serverAuth</td>
      <td>SSL/TLS WWW Server Authentication</td>
    </tr>
    <tr>
      <td>clientAuth</td>
      <td>SSL/TLS WWW Client Authentication</td>
    </tr>
    <tr>
      <td>codeSigning</td>
      <td>Code Signing</td>
    </tr>
    <tr>
      <td>emailProtection</td>
      <td>E-mail Protection (S/MIME)</td>
    </tr>
    <tr>
      <td>timeStamping</td>
      <td>Trusted Timestamping</td>
    </tr>
    <tr>
      <td>OCSPSigning</td>
      <td>OCSP Signing</td>
    </tr>
    <tr>
      <td>ipsecIKE</td>
      <td>ipsec Internet Key Exchange</td>
    </tr>
    <tr>
      <td>msCodeInd</td>
      <td>Microsoft Individual Code Signing (authenticode)</td>
    </tr>
    <tr>
      <td>msCodeCom</td>
      <td>Microsoft Commercial Code Signing (authenticode)</td>
    </tr>
    <tr>
      <td>msCTLSign</td>
      <td>Microsoft Trust List Signing</td>
    </tr>
    <tr>
      <td>msEFS</td>
      <td>Microsoft Encrypted File System</td>
    </tr>
    </tbody>
    </table>
    
    虽然 IETF RFC 5280 规定 id-kp-serverAuth 和 id-kp-clientAuth 仅用于 WWW,但实际上它们用于各种 TLS 客户端和服务器,这也是 OpenSSL 所假定的。
    
    Examples:
    
    ```openssl cnf
    extendedKeyUsage = critical, codeSigning, 1.2.3.4
    
    
    extendedKeyUsage = serverAuth, clientAuth
    
    ```
    </p></li>
    <li><p>Subject Key Identifier
    
    subject密钥标识符扩展可以指定以下3个值.
    
    <ul>
    <li>none
    
    No SKID extension will be included.</p></li>
    <li><p>hash
    
    The process specified in RFC 5280 section 4.2.1.2. (1) is followed: The keyIdentifier is composed of the 160-bit SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits).</p></li>
    <li><p>A hex string (possibly with : separating bytes)
    
    The provided value is output directly. 千万不要这么干.</p></li>
    </ul>
    
    <p>By default the x509, req, and ca apps behave as if hash was given.
    
    Example:
    
    ```openssl cnf
    subjectKeyIdentifier = hash
    ```
    </p></li>
    <li><p>Authority Key Identifier
    
    If issuer is present, and in addition it has the option always specified or keyid is not present, then the issuer DN and serial number are copied from the issuer certificate. If this fails, an error is returned.
    AKID 扩展规范可能具有值 none,表示不应包含任何 AKID。否则,它可能具有值 keyid 或 issuer 或两者,以 , 分隔。其中一个或两个还可以具有 always参数,通过在值和此选项之间放置冒号 : 来表示。对于自签名证书,除非 always 存在,否则 AKID 将被抑制。
    
    默认情况下,x509、req 和 ca 应用程序的默认值为 none,其它情况为 keyid、issuer。
    
    如果 keyid 存在,则尝试从颁发者证书复制主题密钥标识符 (SKID),除非颁发者证书与当前证书相同且不是自签名的。如果颁发者证书与当前证书相同,则使用签名密钥相关的公钥的哈希值作为替代值。如果 always 存在但无法获取任何值,则返回错误。
    
    如果issuer name存在,并且它还具有issuer选项或不存在 keyid,则从颁发者证书中复制颁发者 DN 和序列号。如果失败,则返回错误。
    Examples:
    
    ```openssl cnf
    authorityKeyIdentifier = keyid, issuer
    
    
    authorityKeyIdentifier = keyid, issuer:always
    
    ```
    </p></li>
    <li><p>Subject Alternative Name
    
    这是一个multi-valued扩展,支持多种类型的名称标识符,包括 email(电子邮件地址)、URI(统一资源指示器)、DNS(DNS 域名)、RID(注册 ID:对象标识符)、IP(IP 地址)、dirName(可分辨名称)和 otherName。以下段落描述了每种语法。
    
    <ul>
    <li>email 选项有两个特殊值。copy 将自动在扩展中包含证书 subject name 中包含的任何电子邮件地址。move 将自动将任何电子邮件地址从证书主题名称subject name到扩展。</p></li>
    <li><p>IP 选项中使用的 IP 地址可以是 IPv4 或 IPv6 格式。</p></li>
    <li><p>dirName 的值指定包含要使用的DN,其值为一个section name,具体的DN在section中给出,作为一组name-value对。可以通过在名称前面加上 + 字符来形成多值 AVAs。</p></li>
    <li><p>otherName 的值可以包括与 OID 相关联的任意数据;该值应为 OID 后跟分号和使用 ASN1_generate_nconf(3) 中的语法指定的内容。</p></li>
    </ul>
    
    <p>Examples:
    
    ```openssl cnf
    subjectAltName = email:copy, email:my@example.com, URI:http://my.example.com/
    
    
    subjectAltName = IP:192.168.7.1
    
    subjectAltName = IP:13::17
    
    subjectAltName = email:my@example.com, RID:1.2.3.4
    
    subjectAltName = otherName:1.2.3.4;UTF8:some other identifier
    
    [extensions]
    subjectAltName = dirName:dir_sect
    
    [dir_sect]
    C = UK
    O = My Organization
    OU = My Unit
    CN = My Name
    
    
    非 ASCII 电子邮件地址应符合 RFC 6531 第 3.3 节中定义的语法的以 otherName.SmtpUTF8Mailbox 形式提供。根据 RFC 8398,电子邮件地址应以 UTF8String 形式提供。为了强制证书中的有效表示,SmtpUTF8Mailbox应按如下方式提供:
    
    ```openssl cnf
    subjectAltName=@alts
    [alts]
    otherName = 1.3.6.1.5.5.7.8.9;FORMAT:UTF8,UTF8String:nonasciiname.example.com
    </code></pre></li>
    <li>Issuer Alternative Name
    
    此扩展支持大多数Subject Alternative Name选项;不支持 email:copy但添加了 issuer:copy 作为允许值,如果可能,它会从颁发者证书中复制任何subject alternative names。
    Example:
    
    ```openssl cnf
    issuerAltName = issuer:copy
    ```
    </p></li>
    <li><p>Authority Info Access
    
    此扩展详细说明了如何检索与 CA 提供的证书相关的信息。语法为 access_id;location,其中 access_id 是对象标识符(尽管只有少数值是众所周知的),location 的语法与主题备用名称相同(但不支持 email:copy)。
    允许的值包括 access_id include OCSP (OCSP responder), caIssuers (CA Issuers), ad_timestamping (AD Time Stamping), AD_DVCS (ad dvcs), caRepository (CA Repository).
    
    Examples:
    
    ```openssl cnf
    authorityInfoAccess = OCSP;URI:http://ocsp.example.com/,caIssuers;URI:http://myca.example.com/ca.cer
    authorityInfoAccess = OCSP;URI:http://ocsp.example.com/
    ```
    </p></li>
    <li><p>CRL distribution points
    
    这是一个multi-valued扩展,其值可以是使用与subject alternative name相同形式的name-value对,也可以是指定section的name,该section包含所有分发点值。
    When a name-value pair is used, a DistributionPoint extension will be set with the given value as the fullName field as the distributionPoint value, and the reasons and cRLIssuer fields will be omitted.
    当使用name-value对时,将设置 DistributionPoint 扩展,并使用给定的值作为 fullName 字段作为 distributionPoint 值,并且将省略reasons和 cRLIssuer 字段。
    当使用单选项值时, 指定的section中可以包含以下项:
    
    <ul>
    <li>fullname
    
    distribution point的全名,格式与subject alternative name相同</p></li>
    <li><p>relativename
    
    这是distribution points的RDN,会附加到CRLIssuer的DN中形成分发点的DN,通常不会使用这个项目</p></li>
    <li><p>CRLIssuer
    
    格式与subject alternative name相同</p></li>
    <li><p>reasons
    
    multi-value 字段,包含吊销原因. 可识别的值包括: keyCompromise, CACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn, and AACompromise.</p></li>
    </ul>
    
    <p>Only one of fullname or relativename should be specified.
    fullname 和 relativename 只能指定一个。
    
    Simple examples:
    
    
    ```openssl cnf
    crlDistributionPoints = URI:http://example.com/myca.crl
    
    
    crlDistributionPoints = URI:http://example.com/myca.crl, URI:http://example.org/my.crl
    
    Full distribution point example:
    
    [extensions]
    crlDistributionPoints = crldp1_section
    
    [crldp1_section]
    fullname = URI:http://example.com/myca.crl
    CRLissuer = dirName:issuer_sect
    reasons = keyCompromise, CACompromise
    
    [issuer_sect]
    C = UK
    O = Organisation
    CN = Some Name
    
    ```
    </p></li>
    <li><p>Issuing Distribution Point
    
    这个选项的格式与CRL distribution points是类似的,只不过它指定的是issuer的Distribution Point
    This extension should only appear in CRLs. It is a multi-valued extension whose syntax is similar to the "section" pointed to by the CRL distribution points extension. The following names have meaning:
    
    <ul>
    <li>fullname
    
    distribution point的全名,格式与subject alternative name相同</p></li>
    <li><p>relativename
    
    这是distribution points的RDN,会附加到CRLIssuer的DN中形成分发点的DN,通常不会使用这个项目</p></li>
    <li><p>onlysomereasons
    
    multi-value 字段,包含吊销原因. 可识别的值包括: keyCompromise, CACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn, and AACompromise.</p></li>
    <li><p>onlyuser, onlyCA, onlyAA, indirectCRL
    
    The value for each of these names is a boolean.</p></li>
    </ul>
    
    <p>Example:
    
    ```openssl cnf
    [extensions]
    issuingDistributionPoint = critical, @idp_section
    
    
    [idp_section]
    fullname = URI:http://example.com/myca.crl
    indirectCRL = TRUE
    onlysomereasons = keyCompromise, CACompromise
    
    ```
    

  • Certificate Policies 这是一个raw扩展,可以支持证书定义的所有扩展。 policy qualifiers指策略的内容部分。 不带policy qualifiers的策略可以通过OID指定,多个策略以逗号分隔,例如:

    certificatePolicies = 1.2.4.5, 1.1.3.4
    

    要包含policy qualifiers需使用"@section"语法指向一个section,这个section中会指定所有信息,而且引用的section必须包括一个名为policyIdentifier的项指定策略OID。
    cPSuri qualifiers 可以用以下语法表示。

    CPS.nnn = value
    

    where nnn is a number.

    userNotice qualifiers 可以用以下语法表示:

    userNotice.nnn = @notice
    

    userNotice qualifier的值需要相关section中指定。此部分可以包含explicitText、organization和noticeNumbers选项。explicitText and organization是文本字符串,noticeNumbers是以逗号分隔的数字列表。organization and noticeNumbers选项(如果包含)必须同时存在。某些软件可能需要 ia5org 选项在最前面;这会将编码从 Displaytext 更改为 IA5String。

    Example:

    [extensions]
    certificatePolicies = ia5org, 1.2.3.4, 1.5.6.7.8, @polsect
    
    [polsect]
    policyIdentifier = 1.3.5.8
    CPS.1 = "http://my.host.example.com/"
    CPS.2 = "http://my.your.example.com/"
    userNotice.1 = @notice
    
    [notice]
    explicitText = "Explicit Text Here"
    organization = "Organisation Name"
    noticeNumbers = 1, 2, 3, 4
    

    可以通过添加一个前缀来指定explicitText的字符编码,如: UTF8, BMP, or VISIBLE 后跟一个冒号. 例如:

    [notice]
    explicitText = "UTF8:Explicit Text Here"
    
  • Policy Constraints

    这是一个multi-valued扩展,由name requireExplicitPolicy 或 inhibitPolicyMapping 和一个非负整数值组成。必须至少存在一个组件。
    Example:

    policyConstraints = requireExplicitPolicy:3
    
  • Inhibit Any Policy

    这是一个string扩展,必须包含一个非负数

    Example:

    inhibitAnyPolicy = 2
    
  • Name Constraints

    这是一个multi-valued扩展。名称应以单词“permitted”或“excluded”开头,后跟 ;。名称的其余部分和值遵循 subjectAltName 的语法,但不支持 email:copy,并且 IP 形式应由 IP 地址和子网掩码组成,并用 / 分隔。

    Examples:

    nameConstraints = permitted;IP:192.168.0.0/255.255.0.0
    
    nameConstraints = permitted;email:.example.com
    
    nameConstraints = excluded;email:.com
    
  • OCSP No Check

    This is a string extension. It is parsed, but ignored.

    Example:

    noCheck = ignored
    
  • TLS Feature (aka Must Staple)

    这是一个multi-valued扩展,由 TLS 扩展标识符列表组成。每个标识符可能是一个数字(0..65535)或受支持的名称。当 TLS 客户端发送列出的扩展时,TLS 服务器应在其回复中包含该扩展。

    支持的 names 包括: status_request and status_request_v2.

    Example:

    tlsfeature = status_request
    
  • 废弃的扩展

    以下扩展是非标准的、特定于 Netscape 的且大部分已过时。不鼓励在新应用程序中使用它们。

    Acceptable values for nsCertType are: client, server, email, objsign, reserved, sslCA, emailCA, objCA.

    ARBITRARY 扩展

    如果 OpenSSL 代码不支持某个扩展,则必须使用任意扩展格式对其进行编码。对于受支持的扩展,也可以使用任意格式。应特别小心,确保数据针对给定的扩展类型正确格式化。

    There are two ways to encode arbitrary extensions.

    The first way is to use the word ASN1 followed by the extension content using the same syntax as ASN1_generate_nconf(3). For example:

    [extensions]
    1.2.3.4 = critical, ASN1:UTF8String:Some random data
    1.2.3.4.1 = ASN1:SEQUENCE:seq_sect
    
    [seq_sect]
    field1 = UTF8:field1
    field2 = UTF8:field2
    

    It is also possible to use the word DER to include the raw encoded data in any extension.

    1.2.3.4 = critical, DER:01:02:03:04
    1.2.3.4.1 = DER:01020304
    

    The value following DER is a hex dump of the DER encoding of the extension Any extension can be placed in this form to override the default behaviour. For example:

    basicConstraints = critical, DER:00:01:02:03
    

    警告

    无法保证特定实现会正确处理给定的扩展。因此,有时可能会将证书用于其扩展所禁止的用途,因为特定应用程序不识别或不遵守相关扩展的值。
    应谨慎使用 DER 和 ASN1 选项。如果不谨慎使用,可能会创建无效的扩展。

    Views: 7

  • Certificate Management Protocol

    CMP(Certificate Management Protocol)

    CMP是由IETF开发的协议,用于证书管理,包括证书申请、更新、撤销等。CMP协议的标准由IETF的RFC 4210定义。CMP协议消息的格式基于ASN.1(Abstract Syntax Notation One)描述,并使用DER(Distinguished Encoding Rules)进行编码。
    RFC4210定义的是CMP V2,最新的CMP V3(RFC9480)也已经发布了。

    以下是关于CMP协议格式的详细说明

    1. CMP协议消息的基本结构

    CMP协议消息的基本结构由以下几个部分组成:

    1.1. PKIMessage

    PKIMessage是CMP协议的基本消息类型,包含了所有CMP消息的通用结构。其ASN.1描述如下:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader,
    body PKIBody,
    protection [0] PKIProtection OPTIONAL,
    extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate OPTIONAL
    }

    <pre><code class="line-numbers">- **header**:PKIHeader,包含消息的元数据,如消息类型、发送者和接收者信息等。
    – **body**:PKIBody,包含实际的消息内容,如证书请求、证书响应等。
    – **protection**:PKIProtection,可选字段,用于保护消息的完整性和真实性。
    – **extraCerts**:SEQUENCE OF CMPCertificate,可选字段,包含额外的证书。

    ### 1.2. PKIHeader

    PKIHeader包含消息的元数据,其ASN.1描述如下:

    “`asn.1
    PKIHeader ::= SEQUENCE {
    pvno INTEGER { cmp1999(1), cmp2000(2) },
    sender GeneralName,
    recipient GeneralName,
    messageTime [0] GeneralizedTime OPTIONAL,
    protectionAlg [1] AlgorithmIdentifier OPTIONAL,
    senderKID [2] KeyIdentifier OPTIONAL,
    recipKID [3] KeyIdentifier OPTIONAL,
    transactionID [4] OCTET STRING OPTIONAL,
    senderNonce [5] OCTET STRING OPTIONAL,
    recipNonce [6] OCTET STRING OPTIONAL,
    freeText [7] PKIFreeText OPTIONAL,
    generalInfo [8] SEQUENCE SIZE (1..MAX) OF InfoTypeAndValue OPTIONAL
    }

    • pvno:协议版本号。
    • sender:发送者的标识。
    • recipient:接收者的标识。
    • messageTime:消息的时间戳(可选)。
    • protectionAlg:用于保护消息的算法标识符(可选)。
    • senderKID:发送者的密钥标识符(可选)。
    • recipKID:接收者的密钥标识符(可选)。
    • transactionID:事务ID(可选)。
    • senderNonce:发送者的随机数(可选)。
    • recipNonce:接收者的随机数(可选)。
    • freeText:自由文本(可选)。
    • generalInfo:一般信息(可选)。

    1.3. PKIBody

    PKIBody包含实际的消息内容,其ASN.1描述如下:

    “`asn.1
    PKIBody ::= CHOICE {
    ir [0] CertReqMessages, — Initialization Request
    ip [1] CertRepMessage, — Initialization Response
    cr [2] CertReqMessages, — Certification Request
    cp [3] CertRepMessage, — Certification Response
    p10cr [4] CertificationRequest, — PKCS #10 Certificate Request
    popdecc [5] POPODecKeyChallContent, — Proof-of-Possession Challenge
    popdecr [6] POPODecKeyRespContent, — Proof-of-Possession Response
    kur [7] CertReqMessages, — Key Update Request
    kup [8] CertRepMessage, — Key Update Response
    krr [9] CertReqMessages, — Key Recovery Request
    krp [10] KeyRecRepContent, — Key Recovery Response
    rr [11] RevReqContent, — Revocation Request
    rp [12] RevRepContent, — Revocation Response
    ccr [13] CertReqMessages, — Cross-Certification Request
    ccp [14] CertRepMessage, — Cross-Certification Response
    ckuann [15] CAKeyUpdAnnContent, — CA Key Update Announcement
    cann [16] CertAnnContent, — Certificate Announcement
    rann [17] RevAnnContent, — Revocation Announcement
    crlann [18] CRLAnnContent, — CRL Announcement
    pkiconf [19] PKIConfirmContent, — Confirmation
    nested [20] NestedMessageContent, — Nested Message
    genm [21] GenMsgContent, — General Message
    genp [22] GenRepContent, — General Response
    error [23] ErrorMsgContent, — Error Message
    certConf [24] CertConfirmContent, — Certificate Confirmation
    pollReq [25] PollReqContent, — Polling Request
    pollRep [26] PollRepContent — Polling Response
    }

    <pre><code class="line-numbers">- **ir**:初始化请求(Initialization Request)。
    – **ip**:初始化响应(Initialization Response)。
    – **cr**:认证请求(Certification Request)。
    – **cp**:认证响应(Certification Response)。
    – **p10cr**:PKCS #10证书请求(PKCS #10 Certificate Request)。
    – **popdecc**:证明密钥拥有权挑战(Proof-of-Possession Challenge)。
    – **popdecr**:证明密钥拥有权响应(Proof-of-Possession Response)。
    – **kur**:密钥更新请求(Key Update Request)。
    – **kup**:密钥更新响应(Key Update Response)。
    – **krr**:密钥恢复请求(Key Recovery Request)。
    – **krp**:密钥恢复响应(Key Recovery Response)。
    – **rr**:撤销请求(Revocation Request)。
    – **rp**:撤销响应(Revocation Response)。
    – **ccr**:交叉认证请求(Cross-Certification Request)。
    – **ccp**:交叉认证响应(Cross-Certification Response)。
    – **ckuann**:CA密钥更新公告(CA Key Update Announcement)。
    – **cann**:证书公告(Certificate Announcement)。
    – **rann**:撤销公告(Revocation Announcement)。
    – **crlann**:CRL公告(CRL Announcement)。
    – **pkiconf**:确认(Confirmation)。
    – **nested**:嵌套消息(Nested Message)。
    – **genm**:一般消息(General Message)。
    – **genp**:一般响应(General Response)。
    – **error**:错误消息(Error Message)。
    – **certConf**:证书确认(Certificate Confirmation)。
    – **pollReq**:轮询请求(Polling Request)。
    – **pollRep**:轮询响应(Polling Response)。

    ## 2. CMP协议消息的保护

    CMP协议消息可以通过PKIProtection字段进行保护,确保消息的完整性和真实性。PKIProtection字段的ASN.1描述如下:

    “`asn.1
    PKIProtection ::= BIT STRING

    • PKIProtection:包含消息的保护信息,通常是消息的签名或MAC(消息认证码)。

    3. CMP协议消息的编码

    CMP协议消息使用ASN.1描述,并通过DER(Distinguished Encoding Rules)进行编码。DER是一种二进制编码规则,确保消息的唯一编码。

    4. 示例:CMP协议消息

    以下是一个简单的CMP协议消息示例,展示了初始化请求(Initialization Request)的结构:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader {
    pvno cmp2000,
    sender GeneralName { directoryName { rdnSequence { commonName "Client" } } },
    recipient GeneralName { directoryName { rdnSequence { commonName "CA" } } },
    messageTime GeneralizedTime "20230101000000Z",
    senderNonce OCTET STRING "1234567890abcdef",
    transactionID OCTET STRING "abcdef1234567890"
    },
    body PKIBody {
    ir CertReqMessages {
    CertReqMsg {
    certReq CertRequest {
    certReqId INTEGER 1,
    certTemplate CertTemplate {
    version Version v3,
    subject Name { rdnSequence { commonName "Client" } },
    publicKey SubjectPublicKeyInfo { algorithm { algorithm rsaEncryption }, subjectPublicKey BIT STRING "…" }
    }
    },
    popo ProofOfPossession { raVerified },
    regInfo SEQUENCE { }
    }
    }
    },
    protection PKIProtection "…"
    }

    <pre><code class="line-numbers">## PKI管理模型

    ### PKI实体

    – 最终实体(End Entities,EE)

    最终实体就是subject字段所代表的主体。后面最终实体都用EE表示。

    – 证书颁发机构(Certification Authority,CA)

    CA是issuer字段所代表的主体,CA可以是第三方主体,也可以是与EE相同的主体,可以是离线的也可以是在线的。root CA是EE需要直接信任的CA。

    – 注册机构(Registration Authority,RA)

    许多环境需要独立于CA的注册机构。
    注册机构可能执行的功能因情况而异,但可能包括个人身份验证、令牌分发、撤销报告、名称分配、密钥生成、密钥对存档等。
    RA是可选的,当没有RA时CA完成RA的所有功能。

    RA本身也是一个EE,RA其实就是具有可以签名私钥(签名CSR)的经过认证的EE,CA把哪体EE识别为RA取决于具体实现。一个RA可以属于多个CA。

    ### PKI管理操作

    管理操作的流程图
    “`ascii
    +—+ cert. publish +————+ j
    | | <——————— | End Entity | <——-
    | C | g +————+ “out-of-band”
    | e | | ^ loading
    | r | | | initial
    | t | a | | b registration/
    | | | | certification
    | / | | | key pair recovery
    | | | | key pair update
    | C | | | certificate update
    | R | PKI “USERS” V | revocation request
    | L | ——————-+-+—–+-+——+-+——————-
    | | PKI MANAGEMENT | ^ | ^
    | | ENTITIES a | | b a | | b
    | R | V | | |
    | e | g +——+ d | |
    | p | <———— | RA | <—–+ | |
    | o | cert. | | —-+ | | |
    | s | publish +——+ c | | | |
    | i | | | | |
    | t | V | V |
    | o | g +————+ i
    | r | <————————| CA |——->
    | y | h +————+ “out-of-band”
    | | cert. publish | ^ publication
    | | CRL publish | |
    +—+ | | cross-certification
    e | | f cross-certificate
    | | update
    | |
    V |
    +——+
    | CA-2 |
    +——+

    PKI管理操作包括:

    1. CA建立

      生成自签名证书或者中间CA证书,生成初始CRL,生成证书序列号文件,生成证书数据库

    2. EE初始化

      导入CA证书,获取CA的其它信息

    3. Certification(创建新证书的各种操作)

      3.1. initial registration/certification

      生成密钥对,注册或生成自己的证书请求

      3.2. key pair update

      更新密钥对并颁发新的证书

      3.3. certificate update

      证书过期时如果环境没有任何其它的变化则会refreshed证书

      3.4. CA key pair update

      与EE一样,CA密钥对也需要进行更新,但是会使用不同的机制

      3.5. cross-certification request

      一个CA向另一个CA请求交叉证书

      3.6. cross-certificate update

      同普通证书update

    4. Certificate/CRL discovery operations

      后面具体讲

    5. Recovery operations

      主要是key pair recovery,如果EE丢失了自己的私钥并且CA备份了EE的私钥的情况下可以请求CA恢复私钥

    6. Revocation operations

      证书吊销

    7. PSE operations

      PSE是啥RFC4210中也没说,我想指的应该是发布证书的时候确保提供一个安全渠道。

    Assumptions and Restrictions

    rfc4210中是叫这个标题,我也不知道啥意思

    1. Initiation of Registration/Certification

      第一条PKI消息的产生意味着触发Initiation of Registration/Certification,这可以发生在任何地方,包括EE,RA,CA。

    2. End Entity Message Origin Authentication

      EE与RA或CA通信时需要经过身份认证,也可以不认证。本规范中是通过secret value(用于生成保护字段的MAC,同时用于初始化请求的身份验证,华为的文档中叫秘密值)和reference value(就是senderKID的referenceNum,华为的文档中叫参考值)来认证的,secret value和reference value由CA生成并通过带外途径发送给EE。

    3. Location of Key Generation

      密钥生成的位置等同于PKI消息中首次出现密钥的地方,这可以是EE,RA,CA。

    4. Confirmation of Successful Certification

      CA生成证书后,可以让EE明确接收或不接受证书。

    Mandatory Schemes

    1. Centralized Scheme

      即中心化方案

      • Initiation of Registration/Certification由CA完成
      • 不需要End Entity Message Origin Authentication
      • Location of Key Generation生成在CA
      • 不需要Confirmation of Successful Certification
    2. Basic Authenticated Scheme
      • Initiation of Registration/Certification由EE完成
      • 需要End Entity Message Origin Authentication
      • Location of Key Generation生成在EE
      • 需要Confirmation of Successful Certification

    Proof-of-Possession (POP) of Private Key

    EE持有的私钥,需要向CA/RA证明自己是对应公钥的私钥持有者,这包括用自己的私钥对证书请求进行签名,向CA/RA发送私钥,使用私钥加密一个值。对于Key Agreement Keys,例如DH密钥,可以通过生成一个共享密钥来证明。
    POP证明有很多种,包括包含私钥,直接法(质询响应),间接法(公钥加密证书),后面还有更多说明。

    Root CA Key Update

    更新root CA的密钥是一个比较麻烦的事,因为需要所有EE,RA都要同步处理。
    需要执行的操作包括:

    1. 创建新的密钥对;

    2. 创建一个包含用新私钥签名的旧CA公钥的证书(the “old with new” certificate);

    3. 创建一个包含用旧私钥签名的新CA公钥的证书(the “new with old” certificate);

    4. 创建一个包含用新私钥签名的新CA公钥证书(the “new with new” certificate);

    5. 通过repository and/or 其它方式发送新证书(perhaps using a CAKeyUpdAnn message);

    6. 导出新的CA公钥,以便end entities可以通过”out-of-band”机制获取它(if required).

    然后,旧 CA 私钥将不再​​需要。但是,旧 CA 公钥仍将使用一段时间。当此 CA 的所有终端实体都已安全地获取新 CA 公钥时,旧 CA 公钥将也不再需要(除非出于non-repudiation目的)。”old with new”证书的有效期必须从旧密钥对的生成时间开始,到旧公钥的到期日结束(也就是与旧CA一致)。
    “new with old”证书的有效期必须从新密钥对的生成时间开始,到该 CA 的所有终端实体安全拥有新 CA 公钥的时间结束(最迟为旧公钥的到期日)。
    “new with new”证书的有效期必须从新密钥对的生成时间开始,并在 CA 下次更新其密钥对的时间或之前结束。

    数据结构

    总体PKI消息

    ```asn1
        PKIMessage ::= SEQUENCE {
            header           PKIHeader,
            body             PKIBody,
            protection   [0] PKIProtection OPTIONAL,
            extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                            OPTIONAL
        }
        PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
    ```
    
    protection 就是消息的签名或者完整性验证
    extraCerts 如果颁发证书的CA不是rootCA,则需要一个证书链来验证证书的有效性,所以这就是新证书的证书链(如果有的话)。在证书请求中还可以用于包含当前用于签名验证的证书。Root CA Key Update消息中则用于发布证书。所以这个字段在不同场景下用途也不一样。
    

    PKI消息头

        PKIHeader ::= SEQUENCE {
            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
            sender              GeneralName,
            recipient           GeneralName,
            messageTime     [0] GeneralizedTime         OPTIONAL,
            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
            senderKID       [2] KeyIdentifier           OPTIONAL,
            recipKID        [3] KeyIdentifier           OPTIONAL,
            transactionID   [4] OCTET STRING            OPTIONAL,
            senderNonce     [5] OCTET STRING            OPTIONAL,
            recipNonce      [6] OCTET STRING            OPTIONAL,
            freeText        [7] PKIFreeText             OPTIONAL,
            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
                                InfoTypeAndValue     OPTIONAL
        }
        PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
    

    pvno 就是cmp协议的版本号,对于rfc4210来说始终是2
    sender 发送者的DN名称
    recipient 接收者的DN名称
    messageTime 消息发送时间
    protectionAlg protection字段的算法标识符
    senderKID,recipKID DH算法的密钥标识符,有多对密钥时才需要,在初始化请求中senderKID就是用于身份认证的referenceNum(参考值)
    transactionID 事务ID,也就是会话ID,一般由发起会话者生成,后面保持不变
    senderNonce,recipNonce 每个报文生成一个随机数(为什么不用递增序列?),用于防重放攻击
    freeText 包含人类可读信息(可以由多个),回复消息时使用与第一个Text相同的语言。
    generalInfo 向对方发送附加的机器可处理信息,这是一个generalInfo类型的数组,一共定义了以下generalInfo扩展:

    • ImplicitConfirm
      implicitConfirm OBJECT IDENTIFIER ::= {id-it 13}
      ImplicitConfirmValue ::= NULL
      

      如果存在这个generalInfo扩展则不发送证书确认

    • ConfirmWaitTime

      confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14}
      ConfirmWaitTimeValue ::= GeneralizedTime
      

      证书确认的超时时间,如果超时则撤销证书并删除会话。

    PKI消息体

            PKIBody ::= CHOICE {
              ir       [0]  CertReqMessages,       --Initialization Req
              ip       [1]  CertRepMessage,        --Initialization Resp
              cr       [2]  CertReqMessages,       --Certification Req
              cp       [3]  CertRepMessage,        --Certification Resp
              p10cr    [4]  CertificationRequest,  --PKCS #10 Cert.  Req.
              popdecc  [5]  POPODecKeyChallContent --pop Challenge
              popdecr  [6]  POPODecKeyRespContent, --pop Response
              kur      [7]  CertReqMessages,       --Key Update Request
              kup      [8]  CertRepMessage,        --Key Update Response
              krr      [9]  CertReqMessages,       --Key Recovery Req
              krp      [10] KeyRecRepContent,      --Key Recovery Resp
              rr       [11] RevReqContent,         --Revocation Request
              rp       [12] RevRepContent,         --Revocation Response
              ccr      [13] CertReqMessages,       --Cross-Cert.  Request
              ccp      [14] CertRepMessage,        --Cross-Cert.  Resp
              ckuann   [15] CAKeyUpdAnnContent,    --CA Key Update Ann.
              cann     [16] CertAnnContent,        --Certificate Ann.
              rann     [17] RevAnnContent,         --Revocation Ann.
              crlann   [18] CRLAnnContent,         --CRL Announcement
              pkiconf  [19] PKIConfirmContent,     --Confirmation
              nested   [20] NestedMessageContent,  --Nested Message
              genm     [21] GenMsgContent,         --General Message
              genp     [22] GenRepContent,         --General Response
              error    [23] ErrorMsgContent,       --Error Message
              certConf [24] CertConfirmContent,    --Certificate confirm
              pollReq  [25] PollReqContent,        --Polling request
              pollRep  [26] PollRepContent         --Polling response
              }
    
    

    一共27种报文,还是比较多的。
    具体描述在下在面。

    Common Data Structures

    在说明具本的PKIBody前要先说一下通用的数据结构

    • 发送证书

    当需要包含证书内容时使用CertTemplate语法,CA/RA可能修改证书请求的内容,EE也可以选择拒绝CA签置的证书(如果内容被修改)。

    • Encrypted Values

    通常是私钥和证书(接收新证书),需要使用EncryptedValue数据结构,要求双方事先有能解密秘密数据的密钥。

    • 状态码和故障信息

    状态码

            PKIStatus ::= INTEGER {
                accepted               (0),
                grantedWithMods        (1),
                rejection              (2),
                waiting                (3),
                revocationWarning      (4),
                revocationNotification (5),
                keyUpdateWarning       (6)
            }
    

    故障

            PKIFailureInfo ::= BIT STRING {
                badAlg              (0),
                badMessageCheck     (1),
                badRequest          (2),
                badTime             (3),
                badCertId           (4),
                badDataFormat       (5),
                wrongAuthority      (6),
                incorrectData       (7),
                missingTimeStamp    (8),
                badPOP              (9),
                certRevoked         (10),
                certConfirmed       (11),
                wrongIntegrity      (12),
                badRecipientNonce   (13),
                timeNotAvailable    (14),
                unacceptedPolicy    (15),
                unacceptedExtension (16),
                addInfoNotAvailable (17),
                badSenderNonce      (18),
                badCertTemplate     (19),
                signerNotTrusted    (20),
                transactionIdInUse  (21),
                unsupportedVersion  (22),
                notAuthorized       (23),
                systemUnavail       (24),
                systemFailure       (25),
                duplicateCertReq    (26)
            }
            PKIStatusInfo ::= SEQUENCE {
                status        PKIStatus,
                statusString  PKIFreeText     OPTIONAL,
                failInfo      PKIFailureInfo  OPTIONAL
            }
    
    • 证书标识

    用于标只特定的证书,使用CertId数据结构

    • root CA
    OOBCert ::= Certificate
    # or
    OOBCertHash ::= SEQUENCE {
        hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
        certId      [1] CertId                  OPTIONAL,
        hashVal         BIT STRING
    }
    

    对于Certificat要求:

    • 证书是自签名的,即可以使用SubjectPublicKeyInfo中的公钥验证签名
    • subject和issuer相同
    • 如果subject为空则要求SubjectAltName和issuerAltNames相同
    • key identifiers for subject and issuer相同

    OOBCertHash用途是通过带外方式获取root CA时对root CA进行验证。

    • Archive Options

    请求者希望PKI使用PKIArchiveOptions结构存档私钥

    • Publication Information

    请求者希望PKI通过PKIPublicationInfo结构发布证书

    • Proof-of-Possession Structures

      如果请求的是一个签名证书,私钥的所有权证明是通过POPOSigningKey结构完成的。

      参考附录 C and [CRMF] for POPOSigningKey 语法,

          POPOSigningKey ::= SEQUENCE {
              poposkInput           [0] POPOSigningKeyInput OPTIONAL,
              algorithmIdentifier   AlgorithmIdentifier,
              signature             BIT STRING
              #这个签名是用私钥对poposkInput的DER编码的签名,如果EE能用公钥验证这个签名就完成了私钥所有权证明
          }
          POPOSigningKeyInput ::= SEQUENCE {
              authInfo            CHOICE {
                  sender              [0] GeneralName,
                  publicKeyMAC        PKMACValue
              },
              publicKey           SubjectPublicKeyInfo
          }
      

      另一方面, 如果请求的是一个加密证书, 那么私钥的所有权证明可以用下面三种方法中的一个(包含私钥,直接法,间接法)

    • Inclusion of the Private Key

      在CertRequest请求的POPOPrivKey的thisMessage,或者通过PKIArchiveOptions字段包含私钥,这取决于是否需要私钥存档

      POPOPrivKey ::= CHOICE {
          thisMessage       [0] BIT STRING,
      -- **********
      -- * the type of "thisMessage" is given as BIT STRING in
      -- * [CRMF]; it should be "EncryptedValue" (in accordance
      -- * with Section 5.2.2, "Encrypted Values", of this specification).
      -- * Therefore, this document makes the behavioral clarification
      -- * of specifying that the contents of "thisMessage" MUST be encoded
      -- * as an EncryptedValue and then wrapped in a BIT STRING.  This
      -- * allows the necessary conveyance and protection of the
      -- * private key while maintaining bits-on-the-wire compatibility
      -- * with [CRMF].
      -- **********
      subsequentMessage [1] SubsequentMessage,
      dhMAC             [2] BIT STRING }
      
    • Indirect Method

      返回公钥加密的证书,只有用EE的私钥才能解密。

    • Challenge-Response Protocol(direct method)

      通过Challenge-Response Protocol证明EE私钥的POP

    • PoP选项总结

      下面列出了代表各种POP技术的选项. Using “SK” for “signing key”, “EK” for “encryption key”,and “KAK” for “key agreement key”, 总结如下:

      RAVerified;
      SKPOP;
      EKPOPThisMessage;
      KAKPOPThisMessage;
      KAKPOPThisMessageDHMAC;
      EKPOPEncryptedCert;
      KAKPOPEncryptedCert;
      EKPOPChallengeResp; and
      KAKPOPChallengeResp.
      

      考虑到这一系列选项,自然会问EE如何知道CA/RA支持什么选项/技术(即,在请求证书时可以使用哪些选项)。以下指南应该为EE实现者澄清这种情况。

      • RAVerified

        这是RA向CA请求是用的,EE不需要考虑

      • SKPOP

        如果EE有一个签名密钥对,则这是唯一可用选项

      • EKPOPThisMessage and KAKPOPThisMessage

        如果决定向CA/RA公开私钥,则只有这里的方法可以做到,根据密钥类型选择EKPOPThisMessage 还是 KAKPOPThisMessage

      • KAKPOPThisMessageDHMAC

        仅当CA有可用于此目的的DH证书,以及EE已经有此证书的副本时,EE才能使用此方法。如果这两个条件都成立,那么这种技术就得到了明确的支持。

      • EKPOPEncryptedCert, KAKPOPEncryptedCert, EKPOPChallengeResp, KAKPOPChallengeResp

        EE在请求消息中选择其中一个(在subsequentMessage字段中),具体取决于偏好和密钥对类型。EE在此处没有做POP;它只是向CA/RA指示要使用哪种方法。因此,如果CA/RA回复“badPOP”错误,则EE可以使用在后续消息中选择的其他POP方法重新请求。但是,请注意,本规范鼓励使用EncryptedCert选项,并且还指出,当涉及RA并进行POP验证时,通常会使用质询响应。间接方法需要发送的消息更少,也比较简单是EE尽可能使用这种方法,如果是向RA提交POP证明则会使用直接方法(质询响应)

    特定操作的数据结构

    一共定义了27个操作类型,怪不得CMP是最复杂的证书协议

    • Initialization Request

      一个Initialization请求包含CertReqMessages数据结构作为PKI Body,该数据结构指定要请求的证书(CRMF格式(RFC4211),类似于PKCS#10),通常会包含SubjectPublicKeyInfo、KeyId和Validity字段。此消息用于首次初始化PKI实体时。
      因为是首次请求证书需要带外方式获取身份验证信息,使用MSG_MAC_ALG进行身份验证,MAC信息是用共享的Secret加了盐的。senderKID就是参考值。
      一个请求可以包含多个证书,证书模板(要请求的证书)放在CertTemplate字段中。

      CertReqMessages在Rfc4211中定义,很复杂,以下是ASN.1代码:

      -- Core definitions for this module
      
      CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
      
      CertReqMsg ::= SEQUENCE {
      certReq   CertRequest,
      popo       ProofOfPossession  OPTIONAL,
      -- content depends upon key type
      regInfo   SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL }
      
      CertRequest ::= SEQUENCE {
      certReqId     INTEGER,          -- ID for matching request and reply
      certTemplate  CertTemplate,  -- Selected fields of cert to be issued
      controls      Controls OPTIONAL }   -- Attributes affecting issuance
      
      CertTemplate ::= SEQUENCE {
      version      [0] Version               OPTIONAL,
      serialNumber [1] INTEGER               OPTIONAL,
      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
      issuer       [3] Name                  OPTIONAL,
      validity     [4] OptionalValidity      OPTIONAL,
      subject      [5] Name                  OPTIONAL,
      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
      issuerUID    [7] UniqueIdentifier      OPTIONAL,
      subjectUID   [8] UniqueIdentifier      OPTIONAL,
      extensions   [9] Extensions            OPTIONAL }
      
      OptionalValidity ::= SEQUENCE {
      notBefore  [0] Time OPTIONAL,
      notAfter   [1] Time OPTIONAL } -- at least one MUST be present
      
      Controls  ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue
      AttributeTypeAndValue ::= SEQUENCE {
      type         OBJECT IDENTIFIER,
      value        ANY DEFINED BY type }
      
      ProofOfPossession ::= CHOICE {
      raVerified        [0] NULL,
      -- used if the RA has already verified that the requester is in
      -- possession of the private key
      signature         [1] POPOSigningKey,
      keyEncipherment   [2] POPOPrivKey,
      keyAgreement      [3] POPOPrivKey }
      
      POPOSigningKey ::= SEQUENCE {
      poposkInput           [0] POPOSigningKeyInput OPTIONAL,
      algorithmIdentifier   AlgorithmIdentifier,
      signature             BIT STRING }
      -- The signature (using "algorithmIdentifier") is on the
      -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
      -- certReq CertTemplate contains the subject and publicKey values,
      -- then poposkInput MUST be omitted and the signature MUST be
      -- computed over the DER-encoded value of CertReqMsg certReq.  If
      -- the CertReqMsg certReq CertTemplate does not contain both the
      -- public key and subject values (i.e., if it contains only one
      -- of these, or neither), then poposkInput MUST be present and
      -- MUST be signed.
      
      
      POPOSigningKeyInput ::= SEQUENCE {
      authInfo            CHOICE {
          sender              [0] GeneralName,
          -- used only if an authenticated identity has been
          -- established for the sender (e.g., a DN from a
          -- previously-issued and currently-valid certificate)
          publicKeyMAC        PKMACValue },
          -- used if no authenticated GeneralName currently exists for
          -- the sender; publicKeyMAC contains a password-based MAC
          -- on the DER-encoded value of publicKey
      publicKey           SubjectPublicKeyInfo }  -- from CertTemplate
      
      PKMACValue ::= SEQUENCE {
      algId  AlgorithmIdentifier,
      -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13}
      -- parameter value is PBMParameter
      value  BIT STRING }
      
      PBMParameter ::= SEQUENCE {
      salt                OCTET STRING,
      owf                 AlgorithmIdentifier,
      -- AlgId for a One-Way Function (SHA-1 recommended)
      iterationCount      INTEGER,
      -- number of times the OWF is applied
      mac                 AlgorithmIdentifier
      -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
      }   -- or HMAC [HMAC, RFC2202])
      
      POPOPrivKey ::= CHOICE {
      thisMessage       [0] BIT STRING,         -- Deprecated
      -- possession is proven in this message (which contains the private
      -- key itself (encrypted for the CA))
      subsequentMessage [1] SubsequentMessage,
      -- possession will be proven in a subsequent message
      dhMAC             [2] BIT STRING,         -- Deprecated
      agreeMAC          [3] PKMACValue,
      encryptedKey      [4] EnvelopedData }
      
      -- for keyAgreement (only), possession is proven in this message
      -- (which contains a MAC (over the DER-encoded value of the
      -- certReq parameter in CertReqMsg, which MUST include both subject
      -- and publicKey) based on a key derived from the end entity's
      -- private DH key and the CA's public DH key);
      
      SubsequentMessage ::= INTEGER {
      encrCert (0),
      -- requests that resulting certificate be encrypted for the
      -- end entity (following which, POP will be proven in a
      -- confirmation message)
      challengeResp (1) }
      -- requests that CA engage in challenge-response exchange with
      -- end entity in order to prove private key possession
      
      -- Object identifier assignments --
      
      -- Registration Controls in CRMF
      id-regCtrl OBJECT IDENTIFIER ::= { id-pkip 1 }
      
      
      id-regCtrl-regToken OBJECT IDENTIFIER ::= { id-regCtrl 1 }
      --with syntax:
      RegToken ::= UTF8String
      
      id-regCtrl-authenticator OBJECT IDENTIFIER ::= { id-regCtrl 2 }
      --with syntax:
      Authenticator ::= UTF8String
      
      id-regCtrl-pkiPublicationInfo OBJECT IDENTIFIER ::= { id-regCtrl 3 }
      --with syntax:
      
      PKIPublicationInfo ::= SEQUENCE {
      action     INTEGER {
                  dontPublish (0),
                  pleasePublish (1) },
      pubInfos  SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
      -- pubInfos MUST NOT be present if action is "dontPublish"
      -- (if action is "pleasePublish" and pubInfos is omitted,
      -- "dontCare" is assumed)
      
      SinglePubInfo ::= SEQUENCE {
      pubMethod    INTEGER {
          dontCare    (0),
          x500        (1),
          web         (2),
          ldap        (3) },
      pubLocation  GeneralName OPTIONAL }
      
      id-regCtrl-pkiArchiveOptions     OBJECT IDENTIFIER ::= { id-regCtrl 4 }
      --with syntax:
      PKIArchiveOptions ::= CHOICE {
      encryptedPrivKey     [0] EncryptedKey,
      -- the actual value of the private key
      keyGenParameters     [1] KeyGenParameters,
      -- parameters that allow the private key to be re-generated
      archiveRemGenPrivKey [2] BOOLEAN }
      -- set to TRUE if sender wishes receiver to archive the private
      -- key of a key pair that the receiver generates in response to
      -- this request; set to FALSE if no archival is desired.
      
      EncryptedKey ::= CHOICE {
      encryptedValue        EncryptedValue,   -- Deprecated
      envelopedData     [0] EnvelopedData }
      -- The encrypted private key MUST be placed in the envelopedData
      -- encryptedContentInfo encryptedContent OCTET STRING.
      
      EncryptedValue ::= SEQUENCE {
      intendedAlg   [0] AlgorithmIdentifier  OPTIONAL,
      -- the intended algorithm for which the value will be used
      symmAlg       [1] AlgorithmIdentifier  OPTIONAL,
      -- the symmetric algorithm used to encrypt the value
      encSymmKey    [2] BIT STRING           OPTIONAL,
      -- the (encrypted) symmetric key used to encrypt the value
      keyAlg        [3] AlgorithmIdentifier  OPTIONAL,
      -- algorithm used to encrypt the symmetric key
      valueHint     [4] OCTET STRING         OPTIONAL,
      -- a brief description or identifier of the encValue content
      -- (may be meaningful only to the sending entity, and used only
      -- if EncryptedValue might be re-examined by the sending entity
      -- in the future)
      encValue       BIT STRING }
      -- the encrypted value itself
      -- When EncryptedValue is used to carry a private key (as opposed to
      -- a certificate), implementations MUST support the encValue field
      -- containing an encrypted PrivateKeyInfo as defined in [PKCS11],
      -- section 12.11.  If encValue contains some other format/encoding
      -- for the private key, the first octet of valueHint MAY be used
      -- to indicate the format/encoding (but note that the possible values
      -- of this octet are not specified at this time).  In all cases, the
      -- intendedAlg field MUST be used to indicate at least the OID of
      -- the intended algorithm of the private key, unless this information
      -- is known a priori to both sender and receiver by some other means.
      
      KeyGenParameters ::= OCTET STRING
      
      id-regCtrl-oldCertID          OBJECT IDENTIFIER ::= { id-regCtrl 5 }
      --with syntax:
      OldCertId ::= CertId
      
      CertId ::= SEQUENCE {
      issuer           GeneralName,
      serialNumber     INTEGER }
      
      id-regCtrl-protocolEncrKey    OBJECT IDENTIFIER ::= { id-regCtrl 6 }
      --with syntax:
      ProtocolEncrKey ::= SubjectPublicKeyInfo
      
      -- Registration Info in CRMF
      id-regInfo OBJECT IDENTIFIER ::= { id-pkip 2 }
      
      id-regInfo-utf8Pairs    OBJECT IDENTIFIER ::= { id-regInfo 1 }
      --with syntax
      UTF8Pairs ::= UTF8String
      
      
      id-regInfo-certReq       OBJECT IDENTIFIER ::= { id-regInfo 2 }
      --with syntax
      CertReq ::= CertRequest
      
      -- id-ct-encKeyWithID is a new content type used for CMS objects.
      -- it contains both a private key and an identifier for key escrow
      -- agents to check against recovery requestors.
      
      id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21}
      
      EncKeyWithID ::= SEQUENCE {
      privateKey           PrivateKeyInfo,
      identifier CHOICE {
          string             UTF8String,
          generalName        GeneralName
      } OPTIONAL
      }
      
      PrivateKeyInfo ::= SEQUENCE {
      version                   INTEGER,
      privateKeyAlgorithm       AlgorithmIdentifier,
      privateKey                OCTET STRING,
      attributes                [0] IMPLICIT Attributes OPTIONAL
      }
      
      Attributes ::= SET OF Attribute
      
    • Initialization Response

      初始化请求的响应,返回请求的证书
      CertRepMessage数据结构作为PKIBody,该数据结构为每个请求的证书提供一个PKIStatusInfo字段、一个主题证书,可能还有一个私钥(通常使用会话密钥加密,会话密钥本身使用ProtocolEncrey加密。
      CertRepMessage的asn.1代码

          CertRepMessage ::= SEQUENCE {
              caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                              OPTIONAL,
              response         SEQUENCE OF CertResponse
          }
      
          CertResponse ::= SEQUENCE {
              certReqId           INTEGER,
              -- to match this response with corresponding request (a value
              -- of -1 is to be used if certReqId is not specified in the
              -- corresponding request)
              status              PKIStatusInfo,
              certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
              rspInfo             OCTET STRING        OPTIONAL
              -- analogous to the id-regInfo-utf8Pairs string defined
              -- for regInfo in CertReqMsg [CRMF]
          }
      
          CertifiedKeyPair ::= SEQUENCE {
              certOrEncCert       CertOrEncCert,
              privateKey      [0] EncryptedValue      OPTIONAL,
              -- see [CRMF] for comment on encoding
              publicationInfo [1] PKIPublicationInfo  OPTIONAL
          }
      
          CertOrEncCert ::= CHOICE {
              certificate     [0] CMPCertificate,
              encryptedCert   [1] EncryptedValue
          }
      
          KeyRecRepContent ::= SEQUENCE {
              status                  PKIStatusInfo,
              newSigCert          [0] CMPCertificate OPTIONAL,
              caCerts             [1] SEQUENCE SIZE (1..MAX) OF
                                                  CMPCertificate OPTIONAL,
              keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
                                                  CertifiedKeyPair OPTIONAL
          }
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              -- allows requester to specify as much as they can about
              -- the cert. for which revocation is requested
              -- (e.g., for cases in which serialNumber is not available)
              crlEntryDetails     Extensions       OPTIONAL
              -- requested crlEntryExtensions
          }
      
          RevRepContent ::= SEQUENCE {
              status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              -- in same order as was sent in RevReqContent
              revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId
                                                  OPTIONAL,
              -- IDs for which revocation was requested
              -- (same order as status)
              crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                                                  OPTIONAL
              -- the resulting CRLs (there may be more than one)
          }
      
          CAKeyUpdAnnContent ::= SEQUENCE {
              oldWithNew   CMPCertificate, -- old pub signed with new priv
              newWithOld   CMPCertificate, -- new pub signed with old priv
              newWithNew   CMPCertificate  -- new pub signed with new priv
          }
      
          CertAnnContent ::= CMPCertificate
      
          RevAnnContent ::= SEQUENCE {
              status              PKIStatus,
              certId              CertId,
              willBeRevokedAt     GeneralizedTime,
              badSinceDate        GeneralizedTime,
              crlDetails          Extensions  OPTIONAL
              -- extra CRL details (e.g., crl number, reason, location, etc.)
          }
      
          CRLAnnContent ::= SEQUENCE OF CertificateList
      
          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
              certHash    OCTET STRING,
              -- the hash of the certificate, using the same hash algorithm
              -- as is used to create and verify the certificate signature
              certReqId   INTEGER,
              -- to match this confirmation with the corresponding req/rep
              statusInfo  PKIStatusInfo OPTIONAL
          }
          CMPCertificate ::= CHOICE {
          x509v3PKCert        Certificate
          }
      
    • Certification Request(证书请求)

      现有PKI EE获得其它证书(用已有证书提供身份验证),报文格式同Initialization Request。
      PKI主体可以是CertificationRequest(此结构由[PKCS10]中给出的ASN.1结构CertificationRequest完全指定,用于支持PKCS #10证书请求)。当需要与遗留系统进行互操作时,签名密钥对的证书请求可能需要此结构,但如果不是绝对必要,强烈建议不要使用此结构(为什么不建议呢?)。

    • Certification Response

      报文格式同Initialization Response

    • Key Update Request Content

      仍然使用CertReqMessages PKI Body,但是要包括SubjectPublicKeyInfo、KeyId和Validity字段,此消息用于请求对现有(未吊销和未过期)证书的更新(因此,有时称为“Certificate Update”操作)。更新是包含新subject公钥或当前subject公钥的替换证书(尽管后一种做法可能不适用于某些环境)。

    • Key Update Response Content

      报文格式同Initialization Response

    • Key Recovery Request Content

      报文格式同Initialization Request,但SubjectPublicKeyInfo和KeyId是必选字段可用于提供需要证书的签名公钥

    • Key Recovery Response Content

      使用以下结构作为Key Recovery Request Content的响应

          KeyRecRepContent ::= SEQUENCE {
              status          PKIStatusInfo,
              newSigCert  [0] Certificate                   OPTIONAL,
              caCerts     [1] SEQUENCE SIZE (1..MAX) OF
                                          Certificate      OPTIONAL,
              keyPairHist [2] SEQUENCE SIZE (1..MAX) OF
                                          CertifiedKeyPair OPTIONAL
          }
      
    • Revocation Request Content

      请求吊销证书
      PKI Body结构:

          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              crlEntryDetails     Extensions       OPTIONAL
          }
      
    • Revocation Response Content

      撤销响应是对上述消息的响应。如果生成,则发送给撤销请求者。(可向请求撤销的证书主体发送单独的撤销公告消息。)

          RevRepContent ::= SEQUENCE {
              status        SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              revCerts  [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
              crls      [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                          OPTIONAL
          }
      
    • Cross Certification Request Content

      请求交叉认证证书
      交叉认证请求使用与普通认证请求相同的语法(CertReqMessages),但有一个限制,即密钥对必须由请求CA生成,并且私钥不得发送到响应CA。下级CA也可以使用此请求来获取由父CA签名的证书。

    • Cross Certification Response Content

      交叉认证响应使用与正常认证响应相同的语法(CertRepMessage),但限制不能发送加密的私钥。

    • CA Key Update Announcement Content

      当CA更新其自己的密钥对时,可以使用以下数据结构来宣布此事件。

        CAKeyUpdAnnContent ::= SEQUENCE {
           oldWithNew         Certificate,
           newWithOld         Certificate,
           newWithNew         Certificate
        }
    
    • Certificate Announcement

      此结构可用于宣布证书的存在。 请注意,此消息旨在用于没有其它证书发布方法的情况;例如,如果X.500(LDAP)是发布证书的方法,则不打算使用该方法。

      CertAnnContent ::= Certificate
      
    • Revocation Announcement

      当CA已撤销或即将撤销特定证书时,它可能会发布此事件的公告。

              RevAnnContent ::= SEQUENCE {
                  status              PKIStatus,
                  certId              CertId,
                  willBeRevokedAt     GeneralizedTime,
                  badSinceDate        GeneralizedTime,
                  crlDetails          Extensions  OPTIONAL
              }
      

      CA可以使用此类公告警告(或通知)主体其证书即将(或已)被吊销。这通常用于撤销请求并非来自相关主体的情况。
      willBeRevokedAt字段包含将新条目添加到相关CRL的时间。

      • CRL Announcement
        当CA发布新的CRL(或一组CRL)时,可以使用以下数据结构来宣布此事件。
      CRLAnnContent ::= SEQUENCE OF CertificateList
      
    • PKI Confirmation Content

      此数据结构在协议交换中用作最终PKI消息。它的内容在所有情况下都是相同的——实际上没有内容,因为PKI头包含所有必需的信息。

      PKIConfirmContent ::= NULL
      

      不建议将此消息用于证书确认;应改用certConf。在收到证书响应的PKIConfirm后,接收方可以将其视Certificate Confirmation Content,并接受所有证书。

    • Certificate Confirmation Content

      客户端使用此数据结构向CA/RA发送确认以接受或拒绝证书。

          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
          certHash    OCTET STRING,
          certReqId   INTEGER,
          statusInfo  PKIStatusInfo OPTIONAL
          }
      

      对于任何特定的CertStatus,省略statusInfo字段表示接受指定的证书。或者,可以在statusInfo字段中提供明确的状态详细信息(关于接受或拒绝),可能用于CA/RA的审计目的。
      在CertConfirmContent中,省略与前一响应消息中提供的证书对应的CertStatus结构表示拒绝证书。因此,空CertConfirmContent(零长度序列)可用于指示拒绝所有提供的证书。有关占有证明的certHash字段的讨论,请参见第5.2.8节第(2)项。

    • PKI General Message Content

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      

      没有归类的估计都放这了吧,这部分又包含了13种报文结构

      • CA Protocol Encryption Certificate

        用于EE向CA获取证书用于保护CMP会话

        GenMsg:    {id-it 1}, < absent >
        GenRep:    {id-it 1}, Certificate | < absent >
        

        这里面的absent应该表示的是只有表示infoType的oid,没有infoValue(猜测)

      • Signing Key Pair Types

        获取CA支持的签名算法

        GenMsg:    {id-it 2}, < absent >
        GenRep:    {id-it 2}, SEQUENCE SIZE (1..MAX) OF
                AlgorithmIdentifier
        
      • Encryption/Key Agreement Key Pair Types

        获取CA的加密或KAK算法列表

        GenMsg:    {id-it 3}, < absent >
        GenRep:    {id-it 3}, SEQUENCE SIZE (1..MAX) OF
                                AlgorithmIdentifier
        
      • Preferred Symmetric Algorithm

        获取CA的首选对称加密算法

        GenMsg:    {id-it 4}, < absent >
        GenRep:    {id-it 4}, AlgorithmIdentifier
        
      • Updated CA Key Pair

        CA可用此消息宣布CA密钥对更新(直接发送,不需要请求,但需要最终实体保持监听状态)

        GenMsg:    {id-it 5}, CAKeyUpdAnnContent
        

        在RFC9480中还定义了rootCaCert消息,rootCaCert消息遵循请求/响应模型(有请求才会响应)

      • CRL
        EE用此报文获取最新的CRL

        GenMsg:    {id-it 6}, < absent >
        GenRep:    {id-it 6}, CertificateList
        
      • Unsupported Object Identifiers

        服务器使用它从客户端提交的列表中返回它不识别或不支持的对象标识符列表。
        GenRep: {id-it 7}, SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER

      • Key Pair Parameters

        这可由EE用于请求域参数以用于生成特定公钥算法的密钥对。例如,它可以用于请求适当的P、Q和G以生成DH/DSA密钥,或者请求一组众所周知的椭圆曲线。

        GenMsg:    {id-it 10}, OBJECT IDENTIFIER -- (Algorithm object-id)
        GenRep:    {id-it 11}, AlgorithmIdentifier | < absent >
        

        GenRep中缺少infoValue表示不支持GenMsg中指定的算法。
        EEs必须确保参数是可接受的,并且GenRep消息经过身份验证(以避免替代攻击)。
        跟openssl genpkey的-genparam选项是不是有点类似

      • Revocation Passphrase

        这可由EE用于向CA/RA发送密码短语,以便认证稍后的撤销请求(在适当的签名私钥不再可用于认证请求的情况下)。有关此机制使用的更多详细信息,请参见附录B。

        GenMsg:    {id-it 12}, EncryptedValue
        GenRep:    {id-it 12}, < absent >
        
      • ImplicitConfirm

        不发送确认消息,这个前面通用部分已经说过

      • ConfirmWaitTime

        确认超时时间,前面通用部分已经说过

      • Original PKIMessage

        RA如果修改了EE的请求,再向CA发关请求时携带的原始PKIMessage(EE向RA发送消息)

      • Supported Language Tags

        这可用于确定在后续消息中使用的适当语言标记。发送方发送其支持的语言列表(按顺序,从最优先到最不优先);接收者返回它想要使用的那个。(注意:每个UTF8String必须包含一个语言标记。)如果不支持任何提供的标记,则必须返回错误。

        GenMsg:    {id-it 16}, SEQUENCE SIZE (1..MAX) OF UTF8String
        GenRep:    {id-it 16}, SEQUENCE SIZE (1) OF UTF8String
        
    • PKI General Response Content

      对General Message的响应

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      
    • Error Message Content
      EE、CA或RA可以使用此数据结构来传递错误信息

          ErrorMsgContent ::= SEQUENCE {
              pKIStatusInfo          PKIStatusInfo,
              errorCode              INTEGER           OPTIONAL,
              errorDetails           PKIFreeText       OPTIONAL
          }
      

      此消息可在PKI交易期间的任何时间生成。如果客户端发送此请求,服务器必须使用PKIConfirm响应进行响应,如果标头的任何部分无效,则必须使用另一个ErrorMsg进行响应。双方必须将此消息视为会话的结束(如果会话正在进行)。
      如果需要对消息进行保护,则客户端必须使用与Initialization Request相同的技术(即签名或MAC)对其进行保护。CA必须始终使用签名密钥对其进行签名。

    • Polling Request and Response
      这对消息用于处理客户端需要轮询服务器以确定未完成的ir、cr或kur会话的状态(即,当收到“waiting”PKIStatus时)的场景。

          PollReqContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER }
      
          PollRepContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER,
              checkAfter   INTEGER,  -- time in seconds
              reason       PKIFreeText OPTIONAL }
      

      以下子句描述何时使用轮询消息以及如何使用它们。假定在事务期间可以发送多个certConf消息。对于包含已颁发证书的CertStatus的每个ip、cp或kup,将发送一个响应。

      1. 如果EE收到对ip、cp或kup消息的响应,将为所有已颁发的证书发送certConf,并在确认之后为所有待定证书发送pollReq。
      2. 如果CA收到pollReq,如果一个或多个挂起证书就绪,CA/RA将返回ip、cp或kup的响应;否则,它将返回一个pollRep。
      3. 如果EE收到一个pollRep,它将在发送另一个pollReq之前等待至少与checkAfter值相同的时间。
      4. 如果在pollReq响应期间接收到ip、cp或kup,会按initial response相同的方法处理
                            START
                                |
                                v
                            Send ir
                                | ip
                                v
                            Check status
                            of returned <------------------------+
                            certs                             |
                                |                               |
        

        +————————>|<——————+ |
        | | | |
        | (issued) v (waiting) | |
        Add to <----------- Check CertResponse ------> Add to |
        conf list for each certificate pending list |
        / |
        / |
        (conf list) / (empty conf list) |
        / ip |
        / +—————-+
        (empty pending list) / | pRep
        END <---- Send certConf Send pReq------------>Wait
        | ^ ^ |
        | | | |
        +—————–+ +—————+
        (pending list)

      在以下交互中,EE在一个请求中注册两个证书。

      Step  End Entity                       PKI
      --------------------------------------------------------------------
      1   Format ir
      2                    -> ir      ->
      3                                    Handle ir
      4                                    Manual intervention is
                                          required for both certs.
      5                    <- ip      <-
      6   Process ip
      7   Format pReq
      8                    -> pReq     ->
      9                                    Check status of cert requests
      10                                   Certificates not ready
      11                                   Format pRep
      12                   <- pRep     <-
      13  Wait
      14  Format pReq
      15                   -> pReq     ->
      16                                   Check status of cert requests
      17                                   One certificate is ready
      18                                   Format ip
      19                   <- ip       <-
      20  Handle ip
      21  Format certConf
      22                   -> certConf ->
      23                                   Handle certConf
      24                                   Format ack
      25                   <- pkiConf   <-
      26  Format pReq
      27                   -> pReq     ->
      28                                   Check status of certificate
      29                                   Certificate is ready
      30                                   Format ip
      31                   <- ip       <-
      31  Handle ip
      32  Format certConf
      33                   -> certConf ->
      34                                   Handle certConf
      35                                   Format ack
      36                   <- pkiConf  <-
      

    强制性的PKI功能

    这些功能是EE,RA,CA必须实现的

    • Root CA初始化

      Root CA证书必须是自签名证书,为了支持EE通过带外方式获取Root CA证书还需要生成证书指纺,用OOBCertHash结构表示

    • Root CA密钥更新

      CA密钥(与所有其他密钥一样)具有有限的生存期,必须定期更新。CA可颁发证书NewWithNew、NewWithOld和OldWithNew(见第4.4.1节),以帮助持有当前自签名CA证书(OldWithOld)的现有终端实体安全地过渡到新自签名CA证书(NewWithNew),并帮助持有NewWithNew的新终端实体安全地获取OldWithOld,以验证现有数据。

    • 下级CA(中间CA)的初始化

      从PKI管理协议的角度来看,下级CA的初始化与终端实体的初始化相同。唯一的区别是下级CA还必须生成初始吊销列表.

    • CRL生成

      新成立的CA在颁发任何证书之前必须生成每个 CRL 的“空”版本,这些版本将定期生成。

    • PKI信息请求

      当PKI实体(CA、RA或EE)希望获取有关CA当前状态的信息时,它可以向该CA发送获取此类信息的请求。请求是通过一般消息中的PKI General Message Content消息实现的,响应是通过PKI General Response Content。

    • 交叉认证

      请求者CA是将成为交叉证书subject的CA;响应者CA将成为交叉证书的issuer。

    • EE初始化

      包括获取PKI信息(Root CA证书和其它信息),和Root CA的带外验证(指纹)

    • 证书请求(初始化请求只能执行一次,后续的证书申请需要通过其它请求完成)

      已初始化的EE可随时(出于任何目的)请求额外的证书。此请求将使用证书请求(cr)消息发出。如果EE已经拥有签名密钥对(具有相应的验签证书),则该cr消息通常将受到EE数字签名的保护。CA在CertRepMessage中返回新证书(如果请求成功)。

    • 密钥更新

      当密钥对到期时,相关EE可请求密钥更新;也就是说,它可以请求CA为新密钥对颁发新证书(或者,在某些情况下,为同一密钥对颁发新证书)。使用密钥更新请求(kur)消息发出请求(在某些环境中称为“Certificate Update”操作)。如果EE已经拥有签名密钥对(具有相应的验证证书),则该消息通常将受到EE数字签名的保护。CA在密钥更新响应(kup)消息中返回新证书(如果请求成功),该消息在语法上与CertRepMessage相同。

    Views: 59