Используйте python для доступа к сайту с безопасностью PKI

У меня есть сайт с включенной защитой PKI. Каждый клиент использовал либо кард-ридер для загрузки своего сертификата, либо сертификат был установлен в хранилище сертификатов IE на их компьютере.

Итак, мой вопрос:

  1. Как я могу использовать сертификат устройства чтения карт или сертификат, хранящийся в системе, для проверки системы?
  2. Как мне передать учетные данные на сайт, чтобы сказать «Привет, я — это я, и я могу получить доступ к сервису»? Например, можно использовать мягкие сертификаты. Я могу выяснить часть кард-ридера позже.

Я искал вокруг, и я не придумал ничего, что могло бы помочь мне в этой ситуации. В Django есть куча модулей, но это не вариант, потому что меня интересует только клиентская часть. Я не создаю сайт для размещения службы. Мне нужно просто получить доступ к этим сервисам.

У меня этот код работает вроде. Я просто не знаю, как справиться с перенаправлением, которое я получаю:

import httplib
KEYFILE = r"C:\cert\my.key"
CERTFILE = r"c:\cert\my.pem"
HOSTNAME = 'machine.com'

conn = httplib.HTTPSConnection(
    HOSTNAME,
    key_file = KEYFILE,
    cert_file = CERTFILE
)

conn.putrequest('GET', '/arcgis/sharing/rest?f=json')
conn.endheaders()
response = conn.getresponse()
print response.read()

Результат всего этого:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://machine.com/pki?https://machine.com/arcgis/sharing/rest%3f&amp;f=json">here</a>.</p>
</body></html>

Любая оказанная помощь будет здорово!

Спецификации программного обеспечения: Python 2.7.8, Windows 2012 R2


person code base 5000    schedule 05.06.2015    source источник
comment
Можете ли вы немного рассказать о том, что вы уже пробовали? На данный момент остановимся на № 1 (получение сертификата), предполагая, что аутентификация PKI означает аутентификацию клиентского сертификата, я полагаю, что № 2 встроен в библиотеки, которые обертывают https/ssl/tls. Например, в запросах используйте: requests.get(url, cert=('path/to/cert', 'path/to/key')) (извините - не хотел публиковать как ответ)   -  person bimsapi    schedule 09.06.2015
comment
Похоже, что то, что вы называете PKI, на самом деле является аутентификацией клиентского сертификата (PKI — это более широкое поле, чем это, и обычно включает проверку сертификатов сервера). Знаете ли вы, предоставляет ли ваш кард-ридер драйверы PKCS#11 или это только Windows API?   -  person Bruno    schedule 09.06.2015
comment
Кстати, вы планируете использовать какие-то конкретные библиотеки в Python?   -  person Bruno    schedule 09.06.2015
comment
@Bruno - я не имею в виду никаких библиотек Python. Я не женат на каком-то одном решении.   -  person code base 5000    schedule 09.06.2015
comment
@bimsapi - я пробовал варианты следующего решения: code.activestate.com/recipes/ безуспешно.   -  person code base 5000    schedule 09.06.2015
comment
Попробуйте stackoverflow.com/questions/2195179/ для аутентификации на основе смарт-карт. В зависимости от вашей среды/ситуации это может быть лучшим, что вы сможете сделать. Будет проще, если вы сможете получить подписанный сертификат с локальным ключом в файле для использования (мягкие сертификаты).   -  person Sean Baker    schedule 10.06.2015
comment
Возможно, вам придется следовать стандарту PC/SC, есть библиотека PyCSC, например. здесь github.com/imrehg/pcsc-lite-clone, но это не для слабонервных сердца!   -  person Dima Tisnek    schedule 12.06.2015


Ответы (2)


Я создал обработчик PKI для обработки запросов, поэтому я могу использовать его рабочую библиотеку urllib2.

import httplib, urllib2

class HTTPSClientAuthHandler(urllib2.HTTPSHandler):

    def __init__(self, key, cert):
        urllib2.HTTPSHandler.__init__(self)
        self.key = key
        self.cert = cert
    def https_open(self, req):
        #Rather than pass in a reference to a connection class, we pass in
        # a reference to a function which, for all intents and purposes,
        # will behave as a constructor
        return self.do_open(self.getConnection, req)
    def getConnection(self, host, timeout=300):
        return  httplib.HTTPSConnection(host,
                                             key_file=self.key,
                                             cert_file=self.cert,
                                             timeout=timeout)

Чтобы использовать это, вам нужно будет использовать cookiejar с обработчиком.

from cookielib import CookieJar
cookiejar = CookieJay()
handlers = []
handlers.append(HTTPSClientAuthHandler(somekey, somecert))
handlers.append(urllib2.HTTPCookieProcessor(cookiejar))
opener = urllib2.build_opener(*handlers)
... do other urllib2 calls ....

Надеюсь, это поможет всем!

person code base 5000    schedule 19.06.2015

Попробуйте этот код

#!/usr/bin/env python

import httplib

CERTFILE = '/home/robr/mycert'
HOSTNAME = 'localhost'

conn = httplib.HTTPSConnection(
    HOSTNAME,
    key_file = CERTFILE,
    cert_file = CERTFILE
)
conn.putrequest('GET', '/ssltest/')
conn.endheaders()
response = conn.getresponse()
print response.read()
person Jaffer Wilson    schedule 15.06.2015
comment
спасибо за этот ответ. Может ли httplib обрабатывать перенаправления? - person code base 5000; 19.06.2015