想通了。 :)
ca = OpenSSL::X509::Certificate.new(File.read(INTERCEPTOR_CA_CERTIFICATE))
ca_key = OpenSSL::PKey::RSA.new(File.read(INTERCEPTOR_CA_KEY))
keypair = OpenSSL::PKey::RSA.new(4096)
req = OpenSSL::X509::Request.new
req.version = 0
req.subject = OpenSSL::X509::Name.parse(
"CN=www.origin-server.com/O=Arachni/OU=Proxy/L=Athens/ST=Attika/C=GR"
)
req.public_key = keypair.public_key
req.sign(keypair, OpenSSL::Digest::SHA1.new)
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = rand(999999)
cert.not_before = Time.new
cert.not_after = cert.not_before + (60 * 60 * 24 * 365)
cert.public_key = req.public_key
cert.subject = req.subject
cert.issuer = ca.subject
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = ca
cert.extensions = [
ef.create_extension('basicConstraints', 'CA:FALSE', true),
ef.create_extension('extendedKeyUsage', 'serverAuth', false),
ef.create_extension('subjectKeyIdentifier', 'hash'),
ef.create_extension('authorityKeyIdentifier', 'keyid:always,issuer:always'),
ef.create_extension('keyUsage',
%w(nonRepudiation digitalSignature
keyEncipherment dataEncipherment).join(","),
true
)
]
cert.sign(ca_key, OpenSSL::Digest::SHA1.new)
有用的資源:
- http://users.nccs.gov/~fwang2/ruby/ruby_ssl.html
- http://acidx.net/wordpress/2012/09/creating-a-certification-authority-and-a-server-certificate-on-ubuntu/
* 「......每個對應於請求的域名CN的......」 * - 瀏覽器會拒絕這樣的證書。它們需要* Subject Alternate Name *(SAN)中的服務器名稱,而不是* Common Name *(CN)。相關的,請參見[如何使用openssl創建自簽名證書?](http://stackoverflow.com/a/27931596/608639)。它解釋了使大多數用戶代理感到滿意的規則。 – jww