Ruby - 使用SSL连接并通过客户端证书进行身份验证 - sslv3 alert bad certificate

时间:2017-08-16 16:18:44

标签: ruby-on-rails ruby ssl certificate faraday

我正在尝试连接通过SSL访问某个网站的网络抓取工具,并在该网站上查询我的数据。本网站的身份验证是通过自签名数字证书进行的。目前我想访问该网站,我将.pfx格式的证书上传到我的api,将其转换为.pem,当我尝试使用此证书访问该网站时,响应带有状态403(禁止)。 但是,当我尝试使用.pfx格式的证书通过浏览器访问该站点时,我通常会得到它。 我已经尝试过使用Mechanize,它已经工作了一段时间(直到几个月前才有效),但之后就开始出错了: SSL_connect returned = 1 errno = 0 state = SSLv3 read finished A: sslv3 alert bad certificate 该网站是旧的,它不经常收到更新。 之后我已经尝试使用net / http lib并且错误仍然存​​在,我尝试使用httprb gem,最后我尝试了Faraday。所有尝试都以上面引用的错误或响应状态== 403结束。 我能做些什么才能连接?我的脚本有问题吗?它缺少我需要通过的任何信息吗?

代码:

# Faraday customs method:

class FaradayHttp
  def with_openssl
    system "openssl pkcs12 -in my-certificate-path -out certificate-output-path -nodes -password pass:certificate-password"

    def cert_object
      OpenSSL::X509::Certificate.new File.read("certificate-output-path")
    end

    # create PKey
    def key_object
      OpenSSL::PKey.read File.read("certificate-output-path")
    end


    faraday = Faraday::Connection.new 'https://example-site.com',
    :ssl => {
      certificate: cert_object,
      private_key: key_object,
      version: :SSLv3,
      verify: false
    }
    faraday
  end
end

# Controller that try to connect with the ssl server:

agent = FaradayHttp.new.with_openssl
page = agent.get '/login_path'

1 个答案:

答案 0 :(得分:0)

module Header (
  PGlobalHeader(..)
, Transaction(..)
, MarketData(..)
, Pcap(..)

, parsePCAP 
) where 

import Data.Int 
import Data.Word 
import Control.Monad
import Data.Maybe 
import Control.Monad.IO.Class

import qualified Data.ByteString as BS 
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8 as Char8
import Data.Binary.Get 
import Data.Text (Text)
import Data.Text.Encoding 

import Lib (source)

data PGlobalHeader = PGHeader { 
  magic_number  :: Word32 
, version_major :: Word16 
, version_minor :: Word16 
, timezone      :: Int32  -- GMT to local correction 
, sigfigs       :: Word32 -- accuracy of timestamps 
, snaplen       :: Word32 -- max length of captured packets 
, network       :: Word32 -- data link type 
} deriving (Show, Eq)

data Transaction = Trans { 
  qty   :: Text
, price :: Text
} deriving (Show, Eq)

data MarketData = B6034 {
  issCode :: Text -- issue code (ISIN code) 
, accTime :: Text -- accepted time 
, bids    :: [Transaction] -- from 1st to 5th
, asks    :: [Transaction]
} deriving (Show, Eq)

data Pcap = Pcap PGlobalHeader [MarketData] 
deriving Show

parseGHeader :: Get PGlobalHeader 
parseGHeader = PGHeader <$> 
           getWord32le <*> 
           getWord16le <*> 
           getWord16le <*>
           getInt32le <*>
           getWord32le <*> 
           getWord32le <*> 
           getWord32le 

parsePPacket :: (BS.ByteString -> Bool) -> -- discard the packet?
            Get a -> -- packet parser 
            Get (Maybe a) 
parsePPacket f p = do 
    skip 12
    plen <- getWord32le -- length of pcap packet 
    skip 42 -- skip the IP/UDP header 
    code <- getByteString 5 
    if f code 
        then do r <- p 
                return (Just r)
        else do skip' (plen - 47)
                return Nothing 
  where 
    skip' = skip . fromIntegral 
    getByteString' = getByteString . fromIntegral

parseB6034 :: Get (Maybe MarketData)
parseB6034 = parsePPacket (BS.isPrefixOf quote) parseB6034' 
 where 
  quote :: BS.ByteString
  quote = Char8.pack "B6034"

  parseB6034' :: Get MarketData 
  parseB6034' = do
      issCode <- mkText 12 
      skip 12 
      bids <- go 5  
      skip 7
      asks <- go 5  
      skip 50 
      accTime <- mkText 8
      skip 1 
      return (B6034 issCode accTime bids asks)
    where 
      go 0 = return [] 
      go n = do price <- mkText 5  
                qty <- mkText 7
                remains <- go (n-1)  
                return $ (Trans qty price) : remains 

mkText :: Int -> Get Text 
mkText = fmap decodeLatin1 . getByteString 

parsePCAP = do 
    gHeader <- parseGHeader 
    packets <- parsePPackets [] 
    let packets' = catMaybes packets 
    return (Pcap gHeader packets')
  where 
    parsePPackets xs = do 
    empty <- isEmpty 
    if empty 
        then return xs 
        else do p <- parseB6034 
                parsePPackets (p:xs)