本文转自http://www.ibm.com/developerworks/cn/java/j-certgen/
有一些创建证书的工具。可以使用在 Java SDK 中自带的一个命令行工具 keytool 创建自签名的证书。但是证书链需要更复杂的软件,如 OpenSSL。
可以免费下载 OpenSSL (请参阅参考资料 )。如果使用 UNIX,那么很可能在操作系统中已经安装了 OpenSSL,或者它是操作系统的安装选项。Linux 用户应当查看: /usr/share/ssl。Microsoft MKS toolkit 也带有某个版本的 OpenSSL。 (在我的计算机中它是在 C:\Program Files\MKS Toolkit\etc\openssl。) 如果使用 Windows 但是没有 MKS,那么可以从 SourceForge 得到必要的二进制文件 (请参阅参考资料 )。大多数安装由三个主要文件组成:OpenSSL 二进制文件、一个 CA.sh shell 脚本和一个 openssl.cnf 配置文件。(SourceForge 的软件包缺少 CA.sh 文件。可以下载源代码包获得缺少的文件。)
安装后,保证 CA.sh 和 OpenSSL 可执行文件在路径中。然后就可以开始创建根证书了。
|
|
CA shell 脚本使创建根证书成为一项相对容易的工作。首先,进入要存放 CA 数据的目录。 (我使用 temp\OpenSSL 目录。) 然后键入:
CA -newca |
这会产生一个像清单 1 的对话框,它包括我在提示符下输入的示例信息:
$ CA.sh -newca CA certificate filename (or enter to create) Making CA certificate ... Using configuration from C:/PROGRA~1/MKSTOO~1/etc/openssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key ......++++++ ...++++++ writing new private key to './demoCA/private/./cakey.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. You will see a number of fields, but you can leave some blank. For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:UK State or Province Name (full name) [Some-State]:Hampshire Locality Name (e.g., city) []:Winchester Organization Name (e.g., company) [Internet Widgits Pty Ltd]:IBM UK Ltd Organizational Unit Name (e.g., section) []:JTC Common Name (e.g., YOUR name) []:Pauls Root Certificate Email Address []:[email protected] $ |
完成对话框后,OpenSSL 创建以下目录结构:
demoCA/ cacert.pem - root certificate index.txt - empty serial - text file containing "01" certs/ - empty crl/ - empty newcerts/ - empty private/cakey.pem - private key |
下面是在主目录中文件的简单说明:
您定义目录名 (在这个例子中是 demoCA) 和根证书的有效周期,在 CA.sh 中它默认为 365 天。如果想要改变这些值,必须编辑这个文件。
|
|
|
生成用户证书有两步:生成一个请求和对请求签名。CA shell 脚本可以用-newreq
(生成一个新的请求) 和-sign
(签名一个新请求) 操作符完成这两步。
执行CA -newreq
命令会启动一个类似于生成新根证书时看到的对话框。一个主要的不同是这个对话框提示您输入 PEM 密码短语,OpenSSL 将使用这个短语编码私钥,然后将它写入输出文件。
输出文件名为 newreq.pem,包含私钥和签名请求,可以将它想像为未签名的证书。清单 2 显示了一个新请求对话框的例子。
Using configuration from C:/PROGRA~1/MKSTOO~1/etc/openssl/openssl.cnf Loading 'screen' into random state - done Generating a 1024 bit RSA private key ......................++++++ ...++++++ writing new private key to 'newreq.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. You will see a number of fields, but you can leave some blank. For some fields there will be a default value. If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:UK State or Province Name (full name) [Some-State]:Hampshire Locality Name (e.g., city) []:Winchester Organization Name (e.g., company) [Internet Widgits Pty Ltd]:IBM Uk Ltd Organizational Unit Name (e.g., section) []:JET Common Name (e.g., YOUR name) []:Paul Abbott Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:qwerty An optional company name []: Request (and private key) is in newreq.pem |
执行CA -sign
命令会用包含在 private/cakey.pem 中的根 CA 的私钥签名请求。请求需要在一个名为 newreq.pem 的文件中,生成的证书写入到名为 newcert.pem 的文件中,这两个文件都在当前目录中。清单 3 显示了示例请求-签名对话框。
$ CA.sh -sign Using configuration from C:/PROGRA~1/MKSTOO~1/etc/openssl/openssl.cnf Loading 'screen' into random state - done Enter PEM pass phrase: Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows countryName :PRINTABLE:'UK' stateOrProvinceName :PRINTABLE:'Hampshire' localityName :PRINTABLE:'Winchester' organizationName :PRINTABLE:'IBM UK Ltd' organizationalUnitName:PRINTABLE:'JET' commonName :PRINTABLE:'Paul Abbott' emailAddress :IA5STRING:'[email protected]' Certificate is to be certified until Jun 22 20:50:55 2005 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Certificate: Data: Version: 3 (0x2) Serial Number: 2 (0x2) Signature Algorithm: md5WithRSAEncryption Issuer: C=UK, ST=Hampshire, L=Winchester, O=IBM UK Ltd, OU=JTC, CN=Paul H Abbott/[email protected] Validity Not Before: Jun 22 20:50:55 2004 GMT Not After : Jun 22 20:50:55 2005 GMT Subject: C=UK, ST=Hampshire, L=Winchester, O=IBM Uk Ltd, OU=JET, CN=Paul Abbott/[email protected] Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:e2:b5:90:50:e5:dd:7c:79:c3:49:a5:c9:ee:29: 3a:da:1d:8b:6a:b0:0b:a0:a1:cf:79:fc:be:50:db: cb:37:b7:54:00:bb:6e:74:e6:a4:11:d4:c6:5a:02: 46:3b:b4:33:72:97:5b:cf:9d:9a:32:9b:e6:34:e9: 4b:30:4e:b6:68:55:8a:3f:80:f3:5e:c9:63:cc:4e: c2:c0:c3:34:2f:93:9f:fa:ca:1b:44:f5:c8:87:ec: 1d:12:a9:8c:3a:b9:28:83:4d:b5:18:ff:34:3a:a9: e7:7e:4e:c4:21:8e:56:e7:dc:f5:07:46:39:c8:d8: ff:00:d3:87:20:2e:06:18:19 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: FA:65:44:FB:3A:E6:15:1F:C5:40:6C:EB:F4:DA:AB:B9:CD:F2:2D:54 X509v3 Authority Key Identifier: keyid:93:8C:B4:F0:30:95:77:59:2E:A1:3B:0C:A5:3A:C6:92:FA:16:31:6D DirName:/C=UK/ST=Hampshire/L=Winchester/O=IBM UK Ltd/ OU=JTC/CN=Paul H Abbott/[email protected] serial:00 Signature Algorithm: md5WithRSAEncryption 27:43:6d:89:c3:61:d4:af:3e:dc:55:a3:9a:a7:7d:66:4e:29: 2e:43:f0:90:c6:9c:0f:62:24:b2:4c:9e:2c:f7:d7:84:ce:7f: b6:c8:09:3d:b4:80:c8:26:9a:a8:6b:2f:df:8f:e3:8b:80:f5: 10:28:80:28:5e:94:55:be:61:e5:18:4e:d4:a8:c2:9e:6d:9b: 52:64:94:33:b3:a5:68:79:e2:85:86:01:e6:aa:0f:1e:54:2d: 80:b1:37:38:66:cc:09:9a:0e:30:0a:e8:b9:00:7d:da:a2:a1: bb:3c:83:37:2f:16:6a:5d:84:25:66:23:d2:67:a9:02:a4:33: 96:56 -----BEGIN CERTIFICATE----- MIID0jCCAzugAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVUsx EjAQBgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UE ChMKSUJNIFVLIEx0ZDEMMAoGA1UECxMDSlRDMRYwFAYDVQQDEw1QYXVsIEggQWJi b3R0MScwJQYJKoZIhvcNAQkBFhhQYXVsX0hfQWJib3R0QHVrLmlibS5jb20wHhcN MDQwNjIyMjA1MDU1WhcNMDUwNjIyMjA1MDU1WjCBmDELMAkGA1UEBhMCVUsxEjAQ BgNVBAgTCUhhbXBzaGlyZTETMBEGA1UEBxMKV2luY2hlc3RlcjETMBEGA1UEChMK SUJNIFVrIEx0ZDEMMAoGA1UECxMDSkVUMRQwEgYDVQQDEwtQYXVsIEFiYm90dDEn MCUGCSqGSIb3DQEJARYYUGF1bF9IX0FiYm90dEB1ay5pYm0uY29tMIGfMA0GCSqG SIb3DQEBAQUAA4GNADCBiQKBgQDitZBQ5d18ecNJpcnuKTraHYtqsAugoc95/L5Q 28s3t1QAu2505qQR1MZaAkY7tDNyl1vPnZoym+Y06UswTrZoVYo/gPNeyWPMTsLA wzQvk5/6yhtE9ciH7B0SqYw6uSiDTbUY/zQ6qed+TsQhjlbn3PUHRjnI2P8A04cg LgYYGQIDAQABo4IBJjCCASIwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3Bl blNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPplRPs65hUfxUBs 6/Taq7nN8i1UMIHHBgNVHSMEgb8wgbyAFJOMtPAwlXdZLqE7DKU6xpL6FjFtoYGg pIGdMIGaMQswCQYDVQQGEwJVSzESMBAGA1UECBMJSGFtcHNoaXJlMRMwEQYDVQQH EwpXaW5jaGVzdGVyMRMwEQYDVQQKEwpJQk0gVUsgTHRkMQwwCgYDVQQLEwNKVEMx FjAUBgNVBAMTDVBhdWwgSCBBYmJvdHQxJzAlBgkqhkiG9w0BCQEWGFBhdWxfSF9B YmJvdHRAdWsuaWJtLmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQAnQ22Jw2HUrz7c VaOap31mTikuQ/CQxpwPYiSyTJ4s99eEzn+2yAk9tIDIJpqoay/fj+OLgPUQKIAo XpRVvmHlGE7UqMKebZtSZJQzs6VoeeKFhgHmqg8eVC2AsTc4ZswJmg4wCui5AH3a oqG7PIM3LxZqXYQlZiPSZ6kCpDOWVg== -----END CERTIFICATE----- Signed certificate is in newcert.pem |
注意对话框中请求的 PEM 密码是用来加密根 CA 的私钥——而不是用户的私钥——的密码。
在签名后检查 demoCA 目录,可以看到 index.txt 和 serial 文件已经更新。生成的公钥也放到了 demoCA/newcert/ 目录中,文件名反映了其序列号——如 01.pem。
这时,有了一个用户证书、一个用户私钥和根证书。如果就需要这些,那么就可到此为止了。如果想要知道如何控制证书内容或者创建一个三(或者更多)证书链,则请继续往下读。
|
|
到目前为止,我展示了如何用 CA.sh shell 脚本简化证书生成过程。但是在背后,CA.sh 使用 OpenSSL 命令执行所有必要的密钥生成和签名操作。通过 openssl.cnf 配置文件控制 OpenSSL。我将讨论这个文件的某些部分和它们影响的 CA.sh 操作。
正如我在前面说过的,CA -newca
操作为 CA 创建必要的目录结构:
dir = ./demoCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key |
这个操作创建在 openssl.cnf 中的 CA_default 一节中定义的目录,尽管 CA.sh 不直接引用配置文件。如果想要使用不同的结构,需要修改 openssl.cnf 并手工创建所需要的目录。也可以修改 CA.sh 以创建目录。.
下面对 OpenSSL 的调用生成一个根证书:
openssl req -new -x509 -keyout ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem -days 365 |
-days
标志设置根证书的生存期为 365 天 (一年),它覆盖了在 openssl.cnf 中指定的所有值。
openssl.cnf 的req
一节控制新证书请求的生成,如下面的例子所示:
[ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes |
第一行确定生成的密钥对的长度,第二行确定生成的私钥的默认目标文件。后面两行指向同一文件的其他节。
req_distinguished_name
一节定义了要放在证书请求中的 DN 组件,这些组件最终要进入签名的证书中:
[ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (e.g., city) organizationName = Organization Name (e.g., company) organizationalUnitName = Organizational Unit Name (e.g., section) commonName = Common Name (e.g., YOUR name) emailAddress = Email Address |
这一节的每一部分包含最多四个值,如例子中的第二到第五行所示:
_default
)_min
)_max
)还有其他几个选项。它们包括定义自己的对象标识符 (OID) 类型和让惟一名值在配置文件中定义而不是由用户提供,这对于批处理操作会很有用。req_attributes
一节可以定义加密密码的最小和最大长度,以及其他内容。
new-request 操作的 OpenSSL 调用为:
openssl req -new -keyout newreq.pem -out newreq.pem -days 365 |
注意-keyout
选项覆盖了配置文件中的default_keyfile
一行。同样,生成的证书的生存期设置为 365 天。如果拿这个一行与生成根证书的那一行比较,您会看到只有一处不同:-x509
。它告诉 OpenSSL 您需要一个自签名的证书。
可以在 OpenSSL 文档 (请参阅参考资料 ) 的req
一节中找到更多关于使用 OpenSSL 生成签名请求的信息。
签名操作,就像请求生成操作一样,使用对 OpenSSL 的调用对证书签名:
openssl ca -policy policy_anything -out newcert.pem -infiles newreq.pem |
值得注意的是 OpenSSL 命令是ca
而不是sign
,没有指定用来签名的私钥。openssl.cnf 配置文件定义了这些信息。有关的一节是CA_default
,尽管可以使用-name
选项覆盖它。
-policy
参数指定配置文件中的策略一节。用这一节指定哪些字段必须出现在 DN 请求中,哪些是可选的。我通常使用这种配置:
[ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional |
可以看到,这种配置默认情况下要求很低。值得注意的是文档声明没有在这里列出的 DN 字段将会无声无息地从签名的请求中删除。
|
|
本书的创建根证书 和生成一个用户证书 两节展示了如何用 CA.sh shell 脚本创建根证书,然后用根证书签名用户证书。如果只想有一个两证书链,那些这个过程就足够了,但是如果在链中需要三个或者更多的证书呢?回答是直接使用 OpenSSL 命令。既然知道了 CA.sh 脚本是如何工作的,就可以利用这些知识创建一个三证书链。其步骤类似于创建二证书链的步骤。为了简化,将重复使用上一例子中的 CA 证书/私钥和用户请求。
首先重命名现有的用户请求文件为 userRequest1.pem。然后创建一个新的用户证书,将称它为 userCert1。现有的用户证书没有标记为 CA 证书,并且不能用于对其他证书签名。(只有在试图验证一个包含这种证书的证书链时才会看到这一点。)
需要添加以下一节,它使证书可以根据配置文件对证书签名:
[ my_v3_ext ] basicConstraints = CA:true |
使用以下命令来签名证书:
openssl ca -policy policy_anything -extensions my_v3_ext -out userCert1.pem -infiles userRequest1.pem |
下一步,为第三个证书生成一个新的证书请求。可以使用CA -newreq
命令完成这项任务,也可以直接使用OpenSSL
命令。
有了请求文件后,需要对它签名。如前所述,用来对请求签名的私钥默认是在配置文件中而不是openssl ca
命令中指定的。但是openssl ca
命令可以包含一个-keyfile
选项,它让您可以覆盖这个默认值。 下面的命令使用第二个证书签名第三个证书:
openssl ca -policy policy_anything -keyfile userRequest1.pem -cert userCert1.pem -out userCert2.pem -infiles newreq.pem |
注意-cert
参数指定了签名者的证书,覆盖了配置文件中的默认值。不用这个参数调用这个命令将会产生一个错误,因为 OpenSSL 会检查私钥和签名者的证书是否匹配。
假定一切顺利,在当前目录中应当有 userCert1.pem 和 userCert2.pem 文件,在 demoCA/private 目录中有根 CA 证书。这三个文件构成了证书链。如果使用 Windows,那么应当可以通过在文件浏览器中更改文件名使它们具有 .cer 扩展名,并双击它们来安装证书。
可以发现下面 OpenSSL 命令行选项很有用:
说明: 在“签名第三个证书”的过程中,我把openssl.cnf拷贝到当前目录,然后添加[my_v3_ext]可是没有成功。 无奈之下,我将默认openssl.cnf中[usr_cert] 中的
basicConstraints = CA:FALSE
改为:basicConstraints = CA:TRUE
接着向下进行就可以了,我觉得这个设置是配置生成的当前证书是不是可以作为CA再去签发其他的证书,我之前做了很多实验,可惜就是因为这一个小小的设置没有成功。
然后,就可以使用verify来验证了
openssl verify -CAfile-untrusted testCA
freeRADIUS中配置证书链:(和证书的配置过程一样,只是证书链设置不一样)
在eap.conf的tls模块中
修改如下:
ca_cert="cacert.pem"client_cert="secondcert.pem" < 上述过程中的中间CA,也就是user1cert.pem> private_key=<对应私钥> private_key_passwd="hello"
客户端的修改较大:
ca_cert="chainCA.pem" <所信任的CA,这里的chainCA是rootCA和secondCA的合并,但second要在前,可以通过cat 将两个文件合并> client_cert="chain.pem" <这里的chain.pem是thirdCA也就是上面的user2certCA, 和chainCA的合并> private_key="/home/wangdawei/work/CA/client.pem" private_key_passwd="hello"
然后就可以eapol_test了