[Mac]https化したサイトでXML-RPCを使うために、プライベート認証局でSSLクライアント証明書を発行する
Google+の投稿を自動でWordPressに投稿するスクリプトが動かなくなってしまった。
サイトがSSL化している場合、XML-RPCを使うにはクライアントもSSLに対応していないといけない場合があるらしい。
そのためには、プライベート認証局でSSLクライアント証明書を発行しなければならない。
ここのサイト曰く、クエリを投げるにはクライアントの証明書とクライアントの秘密鍵とそのパスフレーズ、CAの公開鍵証明書が必要らしいので、そいつらを生成する。
ちなみにこの時の環境は以下の通り。
- macOS High Sierra (10.13.3)
- LibreSSL 2.2.7
プライベート認証局(CA)の構築
openssl.cnfの準備
うちの環境では、/private/etc/ssl/openssl.cnfがデフォルトで使用される設定になっていたので、ここを書き換えた。
後述するが、適当なところにopenssl.cnfを作ってそれを使う方法もある。
当時はその方法がわからなかったのでデフォルトのものを書き換えた。
中身は以下のようにしてくれればとりあえず動くと思う。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | # # OpenSSL example configuration file. # This is mostly being used for generation of certificate requests. # # This definition stops the following lines choking if HOME isn't # defined. HOME = . RANDFILE = $ENV::HOME/.rnd # Extra OBJECT IDENTIFIER info: #oid_file = $ENV::HOME/.oid oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: # extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) [ new_oids ] # We can add new OIDs in here for use by 'ca' and 'req'. # Add a simple OID like this: # testoid1=1.2.3.4 # Or use config file substitution like this: # testoid2=${testoid1}.5.6 #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] 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. #unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options # Extension copying option: use with caution. # copy_extensions = copy # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha1 # which md to use. preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 1024 #default_md = sha256 #default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extentions to add to the self signed cert # Passwords for private keys if not present they will be prompted for # input_password = secret # output_password = secret # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString. # utf8only: only UTF8Strings. # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings # so use this option with caution! string_mask = nombstr # req_extensions = v3_req # The extensions to add to a certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = JP countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Internet Widgits Pty Ltd # we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = commonName = Common Name (eg, fully qualified host name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 # SET-ex3 = SET extension number 3 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] # These extensions are added when 'ca' signs a request. # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. # nsCertType = server # For an object signing certificate this would be used. # nsCertType = objsign # For normal client use this is typical # nsCertType = client, email # and for everything including object signing: # nsCertType = client, email, objsign # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment [ v3_ca ] # Extensions for a typical CA # PKIX recommendation. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer:always # This is what PKIX recommends but some broken software chokes on critical # extensions. #basicConstraints = critical,CA:true # So we do this instead. basicConstraints = CA:true # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. # keyUsage = cRLSign, keyCertSign # Some might want this also # nsCertType = sslCA, emailCA # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details # issuerAltName=issuer:copy # DER hex encoding of an extension: beware experts only! # obj=DER:02:03 # Where 'obj' is a standard or added object # You can even override a supported extension: # basicConstraints= critical, DER:30:03:01:01:FF [ crl_ext ] # CRL extensions. # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always [ proxy_cert_ext ] # These extensions should be added when creating a proxy certificate # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. # nsCertType = server # For an object signing certificate this would be used. # nsCertType = objsign # For normal client use this is typical # nsCertType = client, email # and for everything including object signing: # nsCertType = client, email, objsign # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer:always # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo |
構築
まず、/System/Library/OpenSSL/misc/CA.shを適当なところにコピーする。
ホームフォルダとかがいいかな。
そしてそのディレクトリで以下のコマンドを入力する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | $ ./CA.sh -newca CA certificate filename (or enter to create) # ここはエンター Making CA certificate ... Generating a 1024 bit RSA private key ....................++++++ .................................................................................++++++ writing new private key to './demoCA/private/./cakey.pem' Enter PEM pass phrase: # 好きなパスフレーズ(英数字)を入力。あとで使うので覚えておく Verifying - 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. There are quite a few 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) [JP]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Tokyo Organization Name (eg, company) [Internet Widgits Pty Ltd]:ashija Organizational Unit Name (eg, section) []: # エンターキー Common Name (eg, fully qualified host name) []:blog.ashija.net # サブドメイン含むドメイン名 Email Address []:address@gmail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: # エンターキー An optional company name []: # エンターキー Using configuration from /private/etc/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/./cakey.pem: # 同じパスフレーズをもう一度入力 Check that the request matches the signature Signature ok Certificate Details: ~略~ Certificate is to be certified until Jul 31 18:24:45 2021 GMT (1095 days) Write out database with 1 new entries Data Base Updated |
ちなみに、以下のようにコマンドを打つとopenssl.confの場所を指定できる。
1 | $ SSLEAY_CONFIG="-config /System/Library/OpenSSL/openssl-ca.cnf" ./CA.sh -newca |
これで以下の二つのファイルができているはずだ(他にも色々生成されている)。
- ./demoCA/private/cakey.pem
CAの秘密鍵 - ./demoCA/cacert.pem
CAの公開鍵証明書(CAのcakey.pemで署名したもの)
クライアント用の証明書発行
クライアントの証明書作成
以下のようにコマンドを叩く。
もちろんSSLEAY_CONFIGで任意の場所のopenssl.confを使っていい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | $ ./CA.sh -newreq Generating a 1024 bit RSA private key .....................++++++ ...++++++ writing new private key to 'newkey.pem' Enter PEM pass phrase: # 好きなパスフレーズ(英数字)を入力。XML-RPCのクエリを送るときに必要になるので覚えておく Verifying - 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. There are quite a few 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) [JP]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Tokyo Organization Name (eg, company) [Internet Widgits Pty Ltd]:ashija Organizational Unit Name (eg, section) []: # エンターキー Common Name (eg, fully qualified host name) []:blog.ashija.net Email Address []:address@gmail.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: # エンターキー An optional company name []: # エンターキー Request is in newreq.pem, private key is in newkey.pem |
これで以下のファイルが生成されているはずだ。
- newkey.pem
クライアントの秘密鍵 - newreq.pem
クライアントの署名なし公開鍵
(証明書署名要求(CSR)でもある? これを第三者機関であるプライベートCAに審査してもらう感じ?)
署名入りのクライアントの証明書作成
以下のコマンドを入力。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ ./CA.sh -sign Using configuration from /private/etc/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: # cakey.pemのパスフレーズを入力 Check that the request matches the signature Signature ok Certificate Details: ~略~ Certificate is to be certified until Aug 2 18:49:33 2019 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: ~略~ Signed certificate is in newcert.pem |
これで以下のファイルが生成されているはずだ。
- newcert.pem
(CAの署名が入った)クライアントの証明書
クエリを投げる
PHPの場合、以下のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $domain = 'blog.ashija.net'; // ドメイン名(commonNameと同じものを指定。FQDNになる場合も?) $xmlrpc_path = '/hogehoge/xmlrpc.php'; // サーバー上のxmlrpc.phpのパス $pubcert_path = '/Users/hogehoge/demoCA/newcert.pem'; // クライアントの証明書 $privatekey_path = '/Users/hogehoge/demoCA/newkey.pem'; // クライアントの秘密鍵 $sec_pass = 'passphrase'; // newkey.pemのパスフレーズ $cacert_path = '/Users/hogehoge/demoCA/cacert.pem'; // CAの公開鍵証明書 $client = new IXR_ClientSSL($host, $xmlrpc_path); // SSLのための設定 $client->setCertificate($pubcert_path, $privatekey_path, $sec_pass); $client->setCACertificate($cacert_path); $status = $client->query( // クエリの中身 ); |
これで無事また自動投稿できるようになった。
めでたしめでたし。
この記事へのコメントはこちら