{"id":2601,"date":"2011-06-30T17:41:53","date_gmt":"2011-06-30T22:41:53","guid":{"rendered":"http:\/\/jianmingli.com\/wp\/?p=2601"},"modified":"2011-06-30T17:41:53","modified_gmt":"2011-06-30T22:41:53","slug":"setup-client-ssl-certificate-authentication-for-apache-2","status":"publish","type":"post","link":"https:\/\/jianmingli.com\/wp\/?p=2601","title":{"rendered":"Setup Client SSL Certificate Authentication for Apache 2"},"content":{"rendered":"<span id=\"Install_Apache_2\"><h2>Install Apache 2<\/h2><\/span>\n<p>* On Windows, follow <a href=\"?p=89\">this post<\/a> to install Apache 2.<br \/>\n* Follow <a href=\"?p=2621\">this post<\/a> to setup Apache 2 to support SSL<br \/>\n* Test to see that <a href=\"https:\/\/www.my.com\">https:\/\/www.my.com<\/a> can be accessed<\/p>\n<span id=\"Setup_Client_Authentication\"><h2>Setup Client Authentication<\/h2><\/span>\n<span id=\"Generate_Client_Key_and_Certificate\"><h3>Generate Client Key and Certificate<\/h3><\/span>\n<p>* Generate client key (client_key.pem) and certificate signing request (CSR) (client_req.pem)<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>set OPENSSL_CONF=C:\\OpenSSL\\exampleca\\openssl.conf\r\n\r\nC:\\OpenSSL\\exampleca>openssl req -newkey rsa:1024 -keyout client_key.pem -keyform PEM -out client_req.pem -outform PEM\r\nLoading 'screen' into random state - done\r\nGenerating a 1024 bit RSA private key\r\n..........................................................................++++++\r\n.........++++++\r\nwriting new private key to 'client_key.pem'\r\nEnter PEM pass phrase:\r\nVerifying - Enter PEM pass phrase:\r\n-----\r\nYou are about to be asked to enter information that will be incorporated\r\ninto your certificate request.\r\nWhat you are about to enter is what is called a Distinguished Name or a DN.\r\nThere are quite a few fields but you can leave some blank\r\nFor some fields there will be a default value,\r\nIf you enter '.', the field will be left blank.\r\n-----\r\ncommonName, e.g. www.exampleca.com [Example CA]:John Doe\r\nstateOrProvinceName, e.g. Virginia [Virginia]:\r\ncountryName, e.g. US [US]:\r\nemailAddress, e.g ca@exampleca.com [ca@exampleca.com]:johndoe@exampleca.com\r\norganizationName, e.g. Example CA [Example CA]:\r\n<\/pre>\n<p>* Sign client CSR (client_req.pem) to obtain signed cert (certs\\03.pem)<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>openssl ca -in client_req.pem\r\nUsing configuration from C:\\OpenSSL\\exampleca\\openssl.conf\r\nLoading 'screen' into random state - done\r\nEnter pass phrase for C:\/OpenSSL\/exampleca\/private\/cakey.pem:\r\nCheck that the request matches the signature\r\nSignature ok\r\nThe Subject's Distinguished Name is as follows\r\ncommonName            :PRINTABLE:'John Doe'\r\nstateOrProvinceName   :PRINTABLE:'Virginia'\r\ncountryName           :PRINTABLE:'US'\r\nemailAddress          :IA5STRING:'johndoe@exampleca.com'\r\norganizationName      :PRINTABLE:'Example CA'\r\nCertificate is to be certified until Jun 26 18:53:31 2012 GMT (365 days)\r\nSign the certificate? [y\/n]:y\r\n\r\n1 out of 1 certificate requests certified, commit? [y\/n]y\r\nWrite out database with 1 new entries\r\nCertificate:\r\n    Data:\r\n        Version: 3 (0x2)\r\n        Serial Number: 3 (0x3)\r\n        Signature Algorithm: md5WithRSAEncryption\r\n        Issuer: CN=Example CA, ST=Virginia, C=US\/emailAddress=ca@exampleca.com, O=Example CA\r\n        Validity\r\n            Not Before: Jun 27 18:53:31 2011 GMT\r\n            Not After : Jun 26 18:53:31 2012 GMT\r\n        Subject: CN=John Doe, ST=Virginia, C=US\/emailAddress=johndoe@exampleca.com, O=Example CA\r\n        Subject Public Key Info:\r\n            Public Key Algorithm: rsaEncryption\r\n                Public-Key: (1024 bit)\r\n                Modulus:\r\n                    00:aa:33:7d:0f:93:51:69:8f:66:02:33:e7:57:b6:\r\n                    85:82:74:e5:cd:b3:56:0c:df:b9:7c:bd:3f:99:17:\r\n                    a4:2e:67:45:a8:09:54:7f:de:bc:88:d8:59:05:47:\r\n                    ef:64:52:7f:e7:36:78:26:2b:03:70:b1:fd:83:12:\r\n                    55:59:d0:47:e9:ff:db:ca:b3:63:28:ba:b9:15:2f:\r\n                    45:f6:6c:ea:d6:fe:e9:15:82:1a:47:eb:63:94:6f:\r\n                    bc:66:18:5e:21:00:c3:88:fc:82:1e:e6:30:e0:c0:\r\n                    0c:cb:e1:70:8d:33:72:84:ab:24:84:90:29:64:00:\r\n                    2f:e8:49:66:88:55:95:ae:21\r\n                Exponent: 65537 (0x10001)\r\n        X509v3 extensions:\r\n            X509v3 Basic Constraints:\r\n                CA:FALSE\r\n    Signature Algorithm: md5WithRSAEncryption\r\n        40:ac:f3:fc:a6:43:96:ab:00:c2:f1:77:fd:24:e6:51:68:fe:\r\n        16:5e:27:8a:1c:31:88:78:85:49:24:35:a4:07:0e:f9:cc:fe:\r\n        23:d6:ff:dc:63:47:4c:91:05:fb:33:b6:fc:f4:98:e2:d9:a5:\r\n        0e:ef:4b:3c:fd:8b:ad:27:54:7b:30:c5:0b:59:46:72:48:d3:\r\n        e7:5e:5e:31:8a:50:f4:98:ed:41:05:c8:e0:9d:a4:32:38:80:\r\n        a5:f1:eb:67:a0:a3:38:08:83:ae:97:56:48:93:c7:7e:20:40:\r\n        39:c7:5e:5d:29:47:48:63:ae:44:c0:4e:07:1f:82:e7:8e:cd:\r\n        f8:3e:6a:8e:ff:af:17:83:2d:f9:34:54:37:f8:b6:3a:b8:3a:\r\n        a2:d2:0e:c3:0b:b7:c2:ed:e6:46:bd:bc:1a:8d:1f:f6:4f:d6:\r\n        99:1c:3a:c9:e9:64:22:6c:7c:18:92:b1:0f:b7:0b:c9:45:d0:\r\n        4a:e7:83:2c:5e:c6:26:62:83:ef:66:e5:6f:1d:de:19:da:3b:\r\n        e0:46:b3:14:d1:91:2a:67:8b:f3:42:12:be:7b:83:33:f7:b8:\r\n        14:45:67:8b:f5:78:5f:bd:42:a5:36:ac:b2:1c:50:31:57:9d:\r\n        fa:4f:d1:c3:e1:95:e0:b6:88:7c:69:43:86:bb:cc:83:0e:97:\r\n        c1:2a:f5:fe\r\n-----BEGIN CERTIFICATE-----\r\nMIIC3TCCAcWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBrMRMwEQYDVQQDEwpFeGFt\r\ncGxlIENBMREwDwYDVQQIEwhWaXJnaW5pYTELMAkGA1UEBhMCVVMxHzAdBgkqhkiG\r\n9w0BCQEWEGNhQGV4YW1wbGVjYS5jb20xEzARBgNVBAoTCkV4YW1wbGUgQ0EwHhcN\r\nMTEwNjI3MTg1MzMxWhcNMTIwNjI2MTg1MzMxWjBuMREwDwYDVQQDEwhKb2huIERv\r\nZTERMA8GA1UECBMIVmlyZ2luaWExCzAJBgNVBAYTAlVTMSQwIgYJKoZIhvcNAQkB\r\nFhVqb2huZG9lQGV4YW1wbGVjYS5jb20xEzARBgNVBAoTCkV4YW1wbGUgQ0EwgZ8w\r\nDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKozfQ+TUWmPZgIz51e2hYJ05c2zVgzf\r\nuXy9P5kXpC5nRagJVH\/evIjYWQVH72RSf+c2eCYrA3Cx\/YMSVVnQR+n\/28qzYyi6\r\nuRUvRfZs6tb+6RWCGkfrY5RvvGYYXiEAw4j8gh7mMODADMvhcI0zcoSrJISQKWQA\r\nL+hJZohVla4hAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEEBQADggEB\r\nAECs8\/ymQ5arAMLxd\/0k5lFo\/hZeJ4ocMYh4hUkkNaQHDvnM\/iPW\/9xjR0yRBfsz\r\ntvz0mOLZpQ7vSzz9i60nVHswxQtZRnJI0+deXjGKUPSY7UEFyOCdpDI4gKXx62eg\r\nozgIg66XVkiTx34gQDnHXl0pR0hjrkTATgcfgueOzfg+ao7\/rxeDLfk0VDf4tjq4\r\nOqLSDsMLt8Lt5ka9vBqNH\/ZP1pkcOsnpZCJsfBiSsQ+3C8lF0ErngyxexiZig+9m\r\n5W8d3hnaO+BGsxTRkSpni\/NCEr57gzP3uBRFZ4v1eF+9QqU2rLIcUDFXnfpP0cPh\r\nleC2iHxpQ4a7zIMOl8Eq9f4=\r\n-----END CERTIFICATE-----\r\nData Base Updated\r\n<\/pre>\n<p>* Rename signed cert from 03.pem to client_cert.pem<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>cd certs\r\n\r\nC:\\OpenSSL\\exampleca\\certs>dir\r\n\r\n Directory of C:\\OpenSSL\\exampleca\\certs\r\n\r\n06\/27\/2011  02:53 PM             3,289 03.pem\r\n\r\nC:\\OpenSSL\\exampleca\\certs>rename 03.pem client_cert.pem\r\n\r\nC:\\OpenSSL\\exampleca\\certs>dir clien*\r\n\r\n Directory of C:\\OpenSSL\\exampleca\\certs\r\n\r\n06\/27\/2011  02:53 PM             3,289 client_cert.pem\r\n\r\nC:\\OpenSSL\\exampleca\\certs>cd ..\r\n<\/pre>\n<p>* Convert from PEM to PKCS#12 format so it can be imported into Firefox:<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>openssl pkcs12 -export -clcerts -in certs\\client_cert.pem -inkey client_key.pem -out client_cert.p12\r\nLoading 'screen' into random state - done\r\nEnter pass phrase for client_key.pem:\r\nEnter Export Password:\r\nVerifying - Enter Export Password:\r\n\r\nC:\\OpenSSL\\exampleca>dir client*\r\n\r\n Directory of C:\\OpenSSL\\exampleca\r\n\r\n06\/27\/2011  03:05 PM             1,757 client_cert.p12\r\n06\/27\/2011  02:53 PM             1,041 client_key.pem\r\n06\/27\/2011  02:53 PM               660 client_req.pem\r\n<\/pre>\n<span id=\"Enable_Client_Authentication\"><h3>Enable Client Authentication<\/h3><\/span>\n<p>* Add to http.conf:<\/p>\n<pre lang=\"xml\">\r\nListen 443\r\n<VirtualHost _default_:443>\r\n  SSLEngine on\r\n  SSLCertificateFile conf\/apache_cert.pem\r\n  SSLCertificateKeyFile conf\/apache_key_nopass.pem\r\n\r\n  #################\r\n  SSLVerifyClient require\r\n  SSLVerifyDepth 10\r\n  #################\r\n<\/VirtualHost>\r\n<\/pre>\n<p>* Restart Apache<br \/>\n* Test to see that <a href=\"https:\/\/www.my.com\">https:\/\/www.my.com<\/a> can NOT be accessed anymore.<\/p>\n<span id=\"Setup_Client_SSL_Authentication\"><h3>Setup Client SSL Authentication<\/h3><\/span>\n<p>* Modify httpd.conf to include CA cert:<br \/>\n&#8211; Copy cacert.pem to Apache 2 conf directory<br \/>\n&#8211; Modify httpd.conf to include cacert.pem with SSLCACertificateFile directive:<\/p>\n<pre lang=\"xml\">\r\nListen 443\r\n<VirtualHost _default_:443>\r\n  SSLEngine on\r\n  SSLCertificateFile conf\/apache_cert.pem\r\n  SSLCertificateKeyFile conf\/apache_key_nopass.pem\r\n\r\n  SSLVerifyClient require\r\n  SSLVerifyDepth 10\r\n  #################\r\n  SSLCACertificateFile conf\/cacert.pem\r\n  #################\r\n<\/VirtualHost>\r\n<\/pre>\n<span id=\"Setup_Firefox_Browser_for_Client_Authentication\"><h3>Setup Firefox Browser for Client Authentication<\/h3><\/span>\n<p>* Import client_cert.p12 into Firefox browser:<br \/>\n&#8211; Tools -> Options -> Advanced -> Encryption -> View Certificates -> Your Certificates -> Import -> client_cert.p12<\/p>\n<p>* Import CA certificate if not already done:<br \/>\n&#8211; Tools -> Options -> Advanced -> Encryption -> View Certificates -> Authorities -> Import -> cacert.pem<\/p>\n<p>* Turn on automatic selection when request for personal certificate:<br \/>\n&#8211; Tools -> Options -> Advanced -> Encryption -> Select one automatically<\/p>\n<span id=\"Test_Client_Authentication\"><h3>Test Client Authentication<\/h3><\/span>\n<p>* Restart Apache<br \/>\n* Important! restart Firefox browser as well.<br \/>\n* Test to see the page can be loaded again now.<\/p>\n<span id=\"Setup_CRL\"><h2>Setup CRL<\/h2><\/span>\n<span id=\"Revoke_Client_Certificate_client_cert.pem\"><h3>Revoke Client Certificate (client_cert.pem)<\/h3><\/span>\n<p>openssl ca -revoke certs\\client_cert.pem<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>openssl ca -revoke certs\\client_cert.pem\r\nUsing configuration from C:\\OpenSSL\\exampleca\\openssl.conf\r\nLoading 'screen' into random state - done\r\nEnter pass phrase for C:\/OpenSSL\/exampleca\/private\/cakey.pem:\r\nRevoking Certificate 03.\r\nData Base Updated\r\n<\/pre>\n<span id=\"Generate_CRL:_exampleca.crl\"><h3>Generate CRL: exampleca.crl<\/h3><\/span>\n<p>openssl ca -gencrl -out exampleca.crl<\/p>\n<pre>\r\nC:\\OpenSSL\\exampleca>openssl ca -gencrl -out exampleca.crl\r\nUsing configuration from C:\\OpenSSL\\exampleca\\openssl.conf\r\nLoading 'screen' into random state - done\r\nEnter pass phrase for C:\/OpenSSL\/exampleca\/private\/cakey.pem:\r\n<\/pre>\n<span id=\"Setup_CRL_1\"><h3>Setup CRL<\/h3><\/span>\n<p>* Create a crl directory, e.g. C:\\prog\\Apache2.2\\conf\\crl<br \/>\n* Copy exampleca.crl to the newly created crl directory<br \/>\n* Modify http.conf to point SSLCARevocationFile to crl file<\/p>\n<pre lang=\"xml\">\r\nListen 443\r\n<VirtualHost _default_:443>\r\n  SSLEngine on\r\n  SSLCertificateFile conf\/apache_cert.pem\r\n  SSLCertificateKeyFile conf\/apache_key_nopass.pem\r\n\r\n  SSLVerifyClient require\r\n  SSLVerifyDepth 10\r\n  SSLCACertificateFile conf\/cacert.pem\r\n  SSLCARevocationFile conf\/crl\/exampleca.crl\r\n<\/VirtualHost>\r\n<\/pre>\n<p>* Restart Apache<br \/>\n* Test to see that the page can not be loaded anymore<br \/>\n* Check to see that Apache 2 logs\\error.log file contains certificate revoked error<\/p>\n<pre>\r\n[error] [client 127.0.0.1] Certificate Verification: Error (23): certificate revoked\r\n<\/pre>\n<span id=\"Unix_only:_Use_SSLCARevocationPath_Instead_of_SSLCARevocationFile\"><h3>Unix only: Use SSLCARevocationPath Instead of SSLCARevocationFile<\/h3><\/span>\n<p>* Create a soft link for every crl file in the crl directory:<\/p>\n<pre>\r\nln -s exampleca.crl `openssl crl -hash -noout -in exampleca.crl`.r0\r\n<\/pre>\n<p>* Point SSLCARevocationPath to the crl directory<\/p>\n<pre>\r\nSSLCARevocationPath \/dir\/to\/crl\r\n<\/pre>\n<p>* Restart Apache<br \/>\n* Test to see that the page can not be loaded anymore<\/p>\n<span id=\"References\"><h2>References<\/h2><\/span>\n<p>* <a href=\"http:\/\/www.garex.net\/apache\/\">Client certificates with apache<\/a><br \/>\n* <a href=\"http:\/\/www.apacheweek.com\/features\/crl\">Feature: Using Certificate Revocation Lists<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Install Apache 2 * On Windows, follow this post to install Apache 2. * Follow this post to setup Apache 2 to support SSL * Test to see that https:\/\/www.my.com can be accessed Setup Client Authentication Generate Client Key and &hellip; <a href=\"https:\/\/jianmingli.com\/wp\/?p=2601\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[21,55],"tags":[],"class_list":["post-2601","post","type-post","status-publish","format-standard","hentry","category-apache","category-ssl"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8cRUO-FX","_links":{"self":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2601"}],"version-history":[{"count":20,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2601\/revisions"}],"predecessor-version":[{"id":2674,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/2601\/revisions\/2674"}],"wp:attachment":[{"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jianmingli.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}