2015-06-13 44 views
0

我在導航混淆Ruby OpenSSL庫的世界時遇到了一些問題。動態創建具有常見CA的SSL證書/密鑰

期望的最終結果是動態創建SSL服務器證書和密鑰,以便與WEBrick::HTTPProxyServer一起使用,每個密鑰對應CN對應於請求的域,並且全部共享相同的CA.

其原因是允許HTTP代理攔截並監控啓用了HSTS標頭的網站的HTTPS流量,方法是首先將CACert加載到瀏覽器中,從而使我的自簽名證書看起來合法給定的網站。

如果有人有這種事情的經驗,代碼示例將不勝感激。

在此先感謝。

PS。這裏沒有什麼邪惡的,只是improving a featurepenetration testing software

+0

* 「......每個對應於請求的域名CN的......」 * - 瀏覽器會拒絕這樣的證書。它們需要* Subject Alternate Name *(SAN)中的服務器名稱,而不是* Common Name *(CN)。相關的,請參見[如何使用openssl創建自簽名證書?](http://stackoverflow.com/a/27931596/608639)。它解釋了使大多數用戶代理感到滿意的規則。 – jww

回答

1

想通了。 :)

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) 

有用的資源:

  1. http://users.nccs.gov/~fwang2/ruby/ruby_ssl.html
  2. http://acidx.net/wordpress/2012/09/creating-a-certification-authority-and-a-server-certificate-on-ubuntu/
+0

如果您將服務器名稱放在*主題備用名稱(SAN)*(而不是*常用名稱(CN)*)中,那麼我會對此答案滿意。因爲上面的代碼依賴於IETF和CA/Browser論壇的棄用行爲。它在現代瀏覽器中不起作用,但我不確定您的攔截代理是針對目標還是適應瀏覽器。 – jww

+0

@jww那麼「CN =#{host}/subjectAltName =#{host}」應該讓大多數UA高興? –