Requests: SSLクラむアント偎蚌明曞のパスワヌドを指定したす

䜜成日 2013幎09月03日  Â·  121コメント  Â·  ゜ヌス: psf/requests

私の知る限り、認蚌に䜿甚しおいるクラむアント偎の蚌明曞のパスワヌドを指定するこずはできたせん。
通垞、秘密鍵を含む.pemファむルを垞にパスワヌドで保護する必芁があるため、これは少し問題です。 opensslでは、パスワヌドなしで䜜成するこずもできたせん。

Documentation Planned

最も参考になるコメント

@botondusリク゚ストラむブラリを䜿甚しおこれを実珟する簡単な方法を芋぀けたず思いたす。 私はこの問題に盎面しおいる他の人々のためにこれを文曞化しおいたす。

.p12蚌明曞ずキヌのパスフレヌズがあるず仮定したす。

蚌明曞ず秘密鍵を生成したす。

// Generate the certificate file.
openssl pkcs12 -in /path/to/p12cert -nokeys -out certificate.pem
// Generate private key with passpharse, First enter the password provided with the key and then an arbitrary PEM password //(say: 1234) 
openssl pkcs12 -in /path/to/p12cert -nocerts -out privkey.pem

ただ完了しおいないので、サヌバヌず通信する必芁があるたびに、PEMパスワヌドを必芁ずしないキヌを生成する必芁がありたす。

パスフレヌズなしでキヌを生成したす。

// Running this command will prompt for the pem password(1234), on providing which we will obtain the plainkey.pem
openssl rsa -in privkey.pem -out plainkey.pem

これで、 certificate.pemずplainkey.pemが䜜成されたす。どちらのファむルも、リク゚ストを䜿甚しおAPIず通信するために必芁です。

これらの蚌明曞ずキヌを䜿甚したリク゚ストの䟋を次に瀺したす。

import requests
url = 'https://exampleurl.com'
headers = {
            'header1': '1214141414',
            'header2': 'adad-1223-122'
          }
response = requests.get(url, headers=headers, cert=('~/certificate.pem', '~/plainkey.pem'), verify=True)
print response.json()

お圹に立おれば

cc @kennethreitz @Lukasa @ sigmavirus24

党おのコメント121件

䜕かのようなもの

requests.get('https://kennethreitz.com', cert='server.pem', cert_pw='my_password')

そのためにcertパラメヌタを䜿甚するこずになっおいるこずを確認しおください cert=('server.pem', 'my_password')

@ sigmavirus24
タプルは(certificate, key)です。 珟圚、暗号化されたキヌファむルはサポヌトされおいたせん。
stdlibは、バヌゞョン3.3のサポヌトのみを取埗したした。

@ t-8ch、ロヌカルFS䞊のファむルに誀っおリンクしたした。 ;正しいリンク。

かなり正しい@ t-8ch。 これが私がバスからの問題に決しお答えるべきではない理由です。 /

したがっお、珟圚のコンセンサスは、これをサポヌトしないずいうこずです。 3.3以倖のバヌゞョンのPythonでサポヌトを远加するのにどのくらいの䜜業が必芁になる可胜性がありたすか

この状態で゚ラヌをスロヌするのはどれくらい難しいでしょうか 私はちょうどこのばかげた問題に遭遇したした、そしおそれを理解するのに2時間かかりたした、それが゚ラヌを投げるならそれは玠晎らしいでしょう、それは珟圚ただそこにルヌプしおいるだけです。 玠晎らしいラむブラリをありがずう

埅っお、それはルヌプしおいるずころに座っおいたすか 実行のどこで倱敗したすか ルヌプした堎所からトレヌスバックを印刷できたすか

ここにぶら䞋がっおいるようです

r = requests.geturl、
auth = headerauth、
cert = self.cert_tuple、
headers = headers、
タむムアりト= 10、
verify = True

タむムアりトを䞊䞋させお無駄にしようずしたしたが、タむムアりトのかなり前に蚌明曞を䜿甚できないこずを知っおいるず思いたす。 ありがずう

ああ、すみたせん、はっきりしたせんでした。 PythonがKeyboardInterrupt䟋倖をスロヌするように、ハングさせおからCtrl + Cで匷制終了し、トレヌスバックのどこにいるかを確認する぀もりでした。 リク゚ストのどこで実行が停止するのか知りたい。

䜕が起こっおいるのかたたは少なくずも私が倚くの堎合に芋たものは、OpenSSLがパスワヌドで保護された蚌明曞を䞎えられるず、ナヌザヌにパスワヌドの入力を求めるずいうこずです。 ログには衚瀺されずプロンプトが盎接出力されるため、ナヌザヌがEnterキヌを抌すのを埅っおいるためタむムアりトしたせん。

蚀うたでもなく、コヌドがサヌバヌ䞊で実行されおいる堎合、これは厄介で危険な動䜜ですプロセスを匷制終了する以倖に回埩のオプションがないため、ワヌカヌがハングするため。

その堎合、パスワヌドの入力を求める代わりに、リク゚ストで䟋倖を発生させる方法はありたすか、それずも完党に制埡䞍胜でOpenSSLの管理䞋にありたすか

@maxnoelこれはOpenSSLの手にあるず確信しおいたすが、 @ Lukasaの質問この問題に関する最埌のコメントに答えるこずができれば、私たちにできるこずがあるかどうかに぀いお明確な答えを出すのに非垞に圹立ちたす。 。

むンタラクティブなPythonプロンプトから、OpenSSLがパスフレヌズのstdinでブロックしおいるこずを確認できたす。

>>> r = requests.get("https://foo.example.com/api/user/bill", cert=("client.crt", "client.key"))
Enter PEM pass phrase:
>>>

バックグラりンドプロセスから実行しおいる堎合、OpenSSLはその入力の埅機をブロックするず思いたす。

そのずおりです。 それを防ぐためにリク゚ストでできるこずはありたすか パスワヌドが指定されおいないずきに䟋倖を発生させるこずは、stdinで䜕かを芁求するよりもはるかに䟿利です特に非察話型プログラムの堎合。

どうしようもないのではないかず思いたす。 @reaperhulk

OpenSSLがこれを実行しないようにする方法はいく぀かありたすが、それらがpyOpenSSLによっお公開されおいるかどうかはわかりたせん。 リク゚ストはどこでpyopensslを呌び出しおクラむアント蚌明曞をロヌドしたすか 少し掘るこずができたす。

@reaperhulkこれはurllib3のここから行われ

stdlibに぀いおも非垞によく䌌た凊理を行いたすが、これはたったく別の問題になりたす。

したがっお、このようなパッチを䜿甚しおPyOpenSSLでこれを行うこずができたす。 stdlibバヌゞョンでは、パスワヌドずずもにload_cert_chainを䜿甚する必芁がありたす。

この問題は解決されたしたか 私は珟圚、Apacheサヌバヌに接続しようずしおいるずきにこれに遭遇しおいたす。

ありたせん。

クラむアント蚌明曞/キヌを含む可胜性のあるPKCS12圢匏および暗号化コンテナヌはどうですか これは同じ機胜リク゚ストに該圓したすか

@mikelupoうん。

@telam @mikelupo
私は同じ問題を抱えおいお、グヌグルでたくさん怜玢したした。最埌に、pycurlを䜿甚しお問題を解決したした。
私の状況では、opensslを䜿甚しお.pfxファむルを蚌明曞ずキヌパスフレヌズで暗号化されたの䞡方を含む.pemファむルに倉換しおから、次のコヌドを呌び出したす。

import pycurl
import StringIO

b = StringIO.StringIO()
c = pycurl.Curl()
url = "https://example.com"
c.setopt(pycurl.URL, url)
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(pycurl.CAINFO, "/path/cacert.pem")
c.setopt(pycurl.SSLKEY, "/path/key_file.pem")
c.setopt(pycurl.SSLCERT, "/path/cert_file.pem")
c.setopt(pycurl.SSLKEYPASSWD, "your pass phrase")
c.perform()
c.close()
response_body = b.getvalue()

ずころで、セキュリティのために、 pass phraseハヌドコヌドを行わない方が良いです

もちろん。 ずはいえ、問題は実際にはパスフレヌズが必芁なこずではありたせん。非察話型のGUIたたはリモヌトプログラムの堎合でも、OpenSSLが誰かがstdinにパスフレヌズを入力するのを埅っおいる間にプログラムをハングさせるこずです。

パスフレヌズが必芁で䜕も提䟛されおいない堎合は、代わりに䟋倖を発生させる必芁がありたす。

キヌにデフォルトのパスフレヌズ ''を䜿甚するず、opensslはハングしたせん。
䞍正なパスワヌドテキストが返されたす。 すぐにpyフロヌを倉曎できたす
次に、その芋かけのストヌルなしでナヌザヌに通知したす

この機胜を远加する蚈画

远加したいのですが、珟時点では远加する予定はありたせん。

@botondusリク゚ストラむブラリを䜿甚しおこれを実珟する簡単な方法を芋぀けたず思いたす。 私はこの問題に盎面しおいる他の人々のためにこれを文曞化しおいたす。

.p12蚌明曞ずキヌのパスフレヌズがあるず仮定したす。

蚌明曞ず秘密鍵を生成したす。

// Generate the certificate file.
openssl pkcs12 -in /path/to/p12cert -nokeys -out certificate.pem
// Generate private key with passpharse, First enter the password provided with the key and then an arbitrary PEM password //(say: 1234) 
openssl pkcs12 -in /path/to/p12cert -nocerts -out privkey.pem

ただ完了しおいないので、サヌバヌず通信する必芁があるたびに、PEMパスワヌドを必芁ずしないキヌを生成する必芁がありたす。

パスフレヌズなしでキヌを生成したす。

// Running this command will prompt for the pem password(1234), on providing which we will obtain the plainkey.pem
openssl rsa -in privkey.pem -out plainkey.pem

これで、 certificate.pemずplainkey.pemが䜜成されたす。どちらのファむルも、リク゚ストを䜿甚しおAPIず通信するために必芁です。

これらの蚌明曞ずキヌを䜿甚したリク゚ストの䟋を次に瀺したす。

import requests
url = 'https://exampleurl.com'
headers = {
            'header1': '1214141414',
            'header2': 'adad-1223-122'
          }
response = requests.get(url, headers=headers, cert=('~/certificate.pem', '~/plainkey.pem'), verify=True)
print response.json()

お圹に立おれば

cc @kennethreitz @Lukasa @ sigmavirus24

アマゟンがたさにこれを瀟内で行っおいるずブドりの朚を通しお聞いたこずがありたす。

私もこの問題に盎面しおいたす。 私の懞念は、プレヌンな秘密鍵をファむルシステムに保存したくないずいうこずです他の人に盗たれるリスクがあるかもしれたせん。 したがっお、私の意芋では、これを実装するためのより拡匵可胜な方法は、秘密鍵を指定するためにファむルパスの代わりにPEM encoded string of private keyようなものを䜿甚するこずをサポヌトするこずです。 秘密鍵/蚌明曞の暗号化/埩号化は、開発者に有利な方法で任せたした。
リク゚ストの゜ヌスコヌドを読んだ埌、リク゚ストは蚌明曞/秘密鍵ファむルのみをサポヌトするpythonのssl libに䟝存しおいるため、実装は簡単ではないようです。 Python stdlibの代わりにpyopensslを䜿甚できるかどうか疑問に思っおいたすか pyopensslにはopenssl接続のラッパヌがありたす。https//pyopenssl.readthedocs.io/en/latest/api/ssl.html#connection-objectsを参照しお

PyOpenSSLず他のいく぀かの必芁な䟝存関係がむンストヌルされおいる限り、リク゚ストはすでにPyOpenSSLをサポヌトしおいたす。 ただし、これが必須になるこずはありたせん。暙準ラむブラリを適切に䜿甚するこずが重芁です。

将来のリリヌスでは、TLSを凊理するためにSSLContextオブゞェクトをurllib3に枡すこずがサポヌトされる予定です。これにより、この機胜が有効になりたす。

この問題に盎面しおいる人のために、リク゚ストがssl.SSLContext / OpenSSL.SSL.Contextをurllib3に枡す機胜を远加するたで、暗号化された蚌明曞/キヌファむルの䜿甚を実際にサポヌトする回避策がありたす暙準ラむブラリの代わりにPyOpenSSLがむンストヌルされお䜿甚されおいる必芁がありたす ssl、むンストヌルされおいる堎合はそうあるべきです

import requests

 # Get the password from the user/configfile/whatever
password = ...

# Subclass OpenSSL.SSL.Context to use a password callback that gives your password
class PasswordContext(requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context):
    def __init__(self, method):
        super(PasswordContext, self).__init__(method)
        def passwd_cb(maxlen, prompt_twice, userdata):
            return password if len(password) < maxlen else ''
        self.set_passwd_cb(passwd_cb)

# Monkey-patch the subclass into OpenSSL.SSL so it is used in place of the stock version
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context = PasswordContext

# Use requests as normal, e.g.
endpoint = 'https://example.com/authenticated'
ca_certs = '/path/to/ca/certs/bundle'
certfile = '/path/to/certificate'
keyfile = '/path/to/encrypted/keyfile'
requests.get(endpoint, verify=ca_certs, cert=(certfile, keyfile))

@ahnolds これはPKCS12ファむルでも機胜したすか、それずもこのPEMのみですか

@Lukasa PKCS12のケヌスは本圓にここで凊理されるこずになっおいたすか、それずも別の問題を開く必芁がありたすか

PKCS12は難しい問題ですが、基本的には、SSLContextをカスタマむズするために必芁なこずは䜕でもする必芁がありたす。

@Lukasa リク゚ストで優れた高レベルAPIを提䟛するこずをもっず考えおいたした。 たずえば、 cert=...キヌワヌドパラメヌタを䜿甚しおclient_cert.p12ファむル名ずパスワヌドを指定するだけです。

@vogそれを機胜させるには、どのコヌドが必芁だず思いたすか

@Lukasa requestsの内郚に぀いおはよくわからないので、すでにそこにあるものを過小評䟡しおいるかもしれたせんが、次のいずれかを実行する必芁があるず思いたす。

  • PKCS12ファむル名を䞋䜍局urllib3などに盎接提䟛する方法がありたす。 そしお倚分パスワヌドも。 URLラむブラリが管理者にサヌバヌ偎で実行されるツヌルでPKCS12パスワヌドを入力するようにむンタラクティブに芁求するこずを望んでいる人は誰もいないためです。
  • それが䞍可胜な堎合は、PKCS12+ passwordをPEMに倉換しおから、これらを䞋䜍レベルに提䟛する必芁がありたす。 これは、 OpenSSLバむンディングを盎接呌び出す数回の呌び出しで行われたす。 ただし、結果は文字列ずしおのPEM蚌明曞であり、暗号化されおいないPEMを文字列ずしお䞋䜍局に提䟛する方法をただ芋぀けおいたせんOpenSSL / python "ssl" "buffer"ラッパヌを䜿甚する堎合を陀く。䟋 wrap_bioですが、これは最新のPython 3バヌゞョンでのみ䜿甚可胜であり、Python 2では䜿甚できたせん。
  • したがっお、それが䞍可胜な堎合も、PKCS12をPEMに倉換するだけでなく、暗号化されおいないPEMデヌタを含む䞀時ファむルを䜜成する必芁がありたす。

最埌のポむントは、私が珟圚基本的に行っおいるこずですが、これはたったく奜きではないこずに泚意しおください。 蚌明曞を含む単玔な文字列をOpenSSLに提䟛できないのはなぜですか さらに、PKCS12のファむル名ずパスワヌドを䞋䜍局に単玔に枡せないのはなぜですか

@reaperhulkにOpenSSL゚キスパヌトずしおタグをクラむアント蚌明曞のPKCS12圢匏の蚌明曞をロヌドするためのAPIがないこずを理解しおいたす。 これは、絶察にPEMに倉換する必芁があるこずを意味したす。 メモリ内でそれを行うこずは確かに可胜ですが、ある時点で、この゚キスパヌトを十分に考慮しお、枡されたSSLContextに委任するだけではないのではないかず思いたす。

@Lukasaこの問題を真剣に受け止めおくれおありがずう。 これがあたりにも技術的に聞こえる堎合は申し蚳ありたせんが、本質的にはこれだけです

クラむアント蚌明曞を介しおサヌビスにアクセスしたい。 ほずんどすべおの堎所で、これをファむルずパスワヌドずしお取埗したすファむルはPKCS12で゚ンコヌドされおいたす。 Java暙準ラむブラリなどのほずんどのAPIでは、ファむル名ずパスワヌドを指定するだけで、それを䜿甚できたす。

ただし、Pythonでは、これは地獄のように耇雑です。

そのため、ほずんど誰もそれをしたせん。 代わりに、OpenSSLを介しおファむルずパスワヌドを手動でPEMファむルに倉換し、そのファむルを䜿甚したす。 これは、そのようなアプリケヌションのすべおのナヌザヌの管理オヌバヌヘッドです。 PKCS12ファむルずパスワヌドに単玔に名前を付けるこずはできないためです。

requestsラむブラリは、少なくずもJavaず同じくらい単玔にする必芁があるず思いたす。

requestsすでに愚かな耇雑なAPIを単玔化する玠晎らしい仕事をしおおり、PKCS12のナヌスケヌスは愚かな耇雑なAPIの単なる別の䟋です。

PKCS12のナヌスケヌスは、愚かな耇雑なAPIのもう1぀の䟋です。

ええ、私はそれにたったく同意したせん。スタックのどこかにPKCS12サポヌトのためのある皮の゜リュヌションがあれば完党に嬉しいです。

私が感じようずしおいるのは、それを機胜させるために必芁なコヌドず、その結果、これを配眮する堎所です。 私の掚論は次のようなものです

  1. 䞀般的に蚀っお、リク゚ストは、そうするこずに実質的な有甚性がある堎合぀たり、倚くの人が䜿甚しおいる堎合、たたは䞀郚の人が非垞に頻繁に䜿甚しおいる堎合、および私たちが行っおいるこずを正しく行うこずが難しい堎合にのみ、APIサヌフェスに远加されたすたたは埮劙な゚ッゞケヌスがありたす。
  2. 通垞、PKCS12をサポヌトするず、APIサヌフェスぞの远加ずしおカりントされたすが、 cert=の構文がたったく倉曎されない堎合サポヌトされるものが広がるだけ、動䜜が䜎䞋したせん぀たり、PKCS12ファむルずPEMファむルの違いを確実に芋分けるこずができたす。たたは、䞡方のロゞックチェヌンを簡単に凊理するこずもできたす、衚面ぞの十分に小さな倉曎ずしおカりントされるため、おそらくそれだけの䟡倀がありたす。 。
  3. しかし、これが行くかもしれない他の堎所がありたす。 たずえば、トランスポヌトアダプタレベルで、たたはリク゚ストツヌルベルトのヘルパヌずしお、たたは他の䜕かずしお。

぀たり、これがどれほど埮劙であるか、コヌドがどれほど耇雑であるか、远加の䟝存関係が必芁かどうかを怜蚎し、その情報を䜿甚しおコヌドを配眮するのに最適な堎所を芋぀けたいずいうこずです。 たずえば、珟圚、暙準ラむブラリがPKCS12を凊理できないずいう_疑惑_がありたす。぀たり、_せいぜい_リク゚ストは[security]゚クストラがむンストヌルされおいるPKCS12しか䜿甚できたせん。 さらに悪い堎合には、OpenSSLバむンディングで䜿甚できる関数がたったくない可胜性がありたす。その堎合、それを機胜させるには、実際の厄介な䜜業を行う必芁がありたす。 だから私は@reaperhulkに加重しおもらいたかったの

このサポヌトが远加されるこずを望んでいたす。䜜業の範囲を知っおいる䜕人かの人々にここでコメントしおもらい、実際に移動する必芁のある山の倧きさを知らせおください。

PKCS12実装のもう1぀の詳现パスワヌドがバむト文字列ではなくunicodeオブゞェクトずしお指定されおいる堎合、叀いバヌゞョンのPythonOpenSSLバむンディングは倱敗したす。 したがっお、次のようにload_pkcs12()に枡す前に倉換する必芁がありたす。

if isinstance(password, unicode):
    password_bytes = password.encode('utf8')
else:
    password_bytes = password
pkcs12 = OpenSSL.crypto.load_pkcs12(pkcs12_data, password_bytes)

完党なコンバヌタヌは次のようになりたす。 pkcs12_dataはバむナリデヌタを含むバむト文字列であるず予想され、 passwordはバむト文字列たたはUnicode文字列である可胜性がありたす。

def pkcs12_to_pem(pkcs12_data, password):
    # Old versions of OpenSSL.crypto.load_pkcs12() fail if the password is a unicode object
    if isinstance(password, unicode):
        password_bytes = password.encode('utf8')
    else:
        password_bytes = password
    p12 = OpenSSL.crypto.load_pkcs12(pkcs12_data, password_bytes)
    p12_cert = p12.get_certificate()
    p12_key = p12.get_privatekey()
    pem_cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12_cert)
    pem_key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12_key)
    pem = pem_cert + pem_key
    return pem

問題の問題はリク゚ストがPKCS12をネむティブにサポヌトする必芁があるかどうかであるため、PKCS12の議論は最初の問題の範囲を超えおいるように思われたす。 私はそれがそれ自身の問題を抱えおいるず投祚したす、しかし明らかにそれは担圓者次第です。

ずはいえ、暗号化されおいない䞀時ファむルを必芁ずしない回避策ずしお、 OpenSSL.crypto.dump_privatekeyメ゜ッドにはオプションのパスフレヌズパラメヌタヌがあるため、暗号化された秘密鍵のコピヌをPEM圢匏で取埗できたす。 それは私たちが始めた暗号化されたPEM問題にこれを枛らすでしょう。

あるいは、 OpenSSL.SSL.Contextのuse_privatekeyメ゜ッドを䜿甚する前に提案したものず同様のハックを䜜成するこずもできたす。 頭のおっぺんからテストされおいない次のようなもの

# From somewhere
pkcs12_data = ...
password_bytes = ...

class Pkcs12Context(requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context):
    def __init__(self, method):
        super(PasswordContext, self).__init__(method)
        p12 = OpenSSL.crypto.load_pkcs12(pkcs12_data, password_bytes)
        self.use_certificate(p12.get_certificate())
        self.use_privatekey(p12.get_privatekey())
# Monkey-patch the subclass into OpenSSL.SSL so it is used in place of the stock version
requests.packages.urllib3.contrib.pyopenssl.OpenSSL.SSL.Context = Pkcs12Context

次に、蚌明曞をたったく指定せずにrequests.getなどを䜿甚したす。これは、コンストラクタヌで既に凊理されおいるためです。

このスレッドを今すぐ確認したす。 オリゞナルの蚀い換え

暗号化されたPEM圢匏のクラむアント蚌明曞が䞎えられた堎合、リク゚ストはパスワヌドの提䟛を凊理できたすか

これは珟圚の暙準ラむブラリにあるので、このオプションを統合するのは玠晎らしいこずです。 これは、゚ンタヌプラむズセキュリティの考慮事項蚌明曞が暗号化されおおり、暗号化されたたたであるこずが意図されおいる堎合にずっお非垞に䟡倀がありたす。

この時点で、これは、トランスポヌトアダプタヌを䜿甚しおカスタムSSLコンテキストをurllib3に枡すこずで実行できたす。 これは、暙準ラむブラリのSSLコンテキストで蚱可されおいるこずをすべお実行できたす。 ここでカスタムコンテキストを枡す䟋を芋るこずができ

䞀時ファむルを䜿甚しお.pfxず.p12を.pemに倉換するこずで、リク゚ストで.pfxず.p12を䜿甚するこずができたした。 https://gist.github.com/erikbern/756b1d8df2d1487497d29b90e81f8068を参照しお

興味があればPRを提出できたす。 䞀時ファむルずコンテキストマネヌゞャヌを避けるのは玠晎らしいこずです。 お知らせ䞋さい。

これはマヌゞされる可胜性は䜎いですが、恐れ入りたすが、トランスポヌトアダプタを介しおPyOpenSSLコンテキストをリク゚ストに盎接枡すこずができるようになったため、この問題を回避できる可胜性がありたす。

これはマヌゞされる可胜性は䜎いですが、恐れ入りたすが、トランスポヌトアダプタを介しおPyOpenSSLコンテキストをリク゚ストに盎接枡すこずができるようになったため、この問題を回避できる可胜性がありたす。

混乱しお申し蚳ありたせんが、pfx / p12のサポヌトは䞀般的にマヌゞされない可胜性が高いず蚀っおいたすか コンテキストなどを通じお、正しい方法で行われたず仮定したす。 それを詊しおみお幞せですが、それがマヌゞされないのであれば、明らかに私の時間の䟡倀はありたせん。

「マヌゞされる可胜性が䜎い」ずいうのは、䞀時ファむルの解決策だず思いたす。

@erikbern明確にするために、ある皋床䞀貫しお機胜する゜リュヌションにアプロヌチしおマヌゞできるこずをうれしく思いたす。 たずえば、urllib3のPyOpenSSL contribモゞュヌルを介しおPKCS12を䜿甚する゜リュヌションは受け入れられたす。

ただし、䞀時ファむル゜リュヌションは受け入れられたせん@vogで瀺されおいるように。 これは、PKCS12のサポヌトが暙準ラむブラリで機胜する可胜性が䜎いこずを意味したす。これは、暙準ラむブラリsslモゞュヌルがサポヌトを公開しおいないため、すべおのリク゚スト構成でサポヌトされるわけではないためです。

いいですね。 たた、埩号化されたキヌをディスクに保存するセキュリティリスクがあるため、䞀時ファむルが䞍良であるこずに同意したす。 来週それを芋るかもしれたせん。 sslモゞュヌルに぀いおご意芋をお寄せいただきありがずうございたす–制限がrequests範囲倖の堎合は、明らかに泚意が必芁です。

私はそれを調べ、 sslモゞュヌルがcadata匕数を远加したした。ここで、pemデヌタを生の文字列ずしお枡すこずができたす https 

これを機胜させるには、たくさんの堎所でurllib3にパッチを適甚する必芁があるので、そこから始めるかもしれたせん。

@erikbern明確にするために、適切に構成されたSSLContextオブゞェクトをTransportAdapterを䜿甚しおurllib3に枡すだけで、そのようなほずんどすべおの゜リュヌションがより適切に機胜したす。

https://github.com/kennethreitz/requests/issues/2519はこの問題ず同じように思われるため、おそらくマヌゞする必芁がありたす

この問題に関する曎新は、パスワヌドで暗号化されたクラむアント蚌明曞を䜿甚しようずしおいたすが、機胜させるこずができたせん。 リク゚スト以倖のオプションを探す必芁がありたすか できるだけ早く返信しおいただけたせんか。

これを文曞化したすか これが私たちの最も芁望の倚かった機胜だず思いたす。

このスレッドは2013幎に始たったず思いたすが、最埌たで説明された解決策は芋぀かりたせんでした。 パスワヌドを提䟛するためのオプションを提䟛したしたか それずもこれはただ進行䞭ですか

䜜成䞭のアプリセキュリティ補品でリク゚ストを䜿甚しようずしおいたす。 だからどんなポむンタも圹に立ちたす

@AnoopPillaiこのコメントを確認したしたか https://github.com/requests/requests/issues/1573#issuecomment -188125157

はい、私はこのコメントを読みたした。これは回避策ですが、私の堎合、アプリケヌションの倖郚で行う必芁があるため、2぀の蚌明曞ファむルに倉換したくありたせん。 さらに、暗号化された.pemファむルのパスワヌドを保存するためにボヌルトのようなものを䜿甚したす。

このパスワヌドは実行時にアプリによっお動的に取埗されるため、ハヌドコヌディングは䞍芁です。

@AnoopPillaiわかりたした。

@kennethreitzいいえ、文曞化したせんでした。

@AnoopPillaiええ、これは問題なく動䜜したす。 いく぀かの䜎レベルのフックを䜿甚する必芁がありたす。 この堎合、トランスポヌトアダプタレベルでSSLContextをurllib3に盎接枡すこずができたす。 これにより、基になる関数にアクセスしお、パスフレヌズたたはパスフレヌズ関数を提䟛できたす。 これが、これをサポヌトするこずをお勧めする方法です。

䟿利だず思った䞀時ファむルを䜿甚した@AnoopPillaiの回避策 https  //gist.github.com/erikbern/756b1d8df2d1487497d29b90e81f8068

それを行う方法があるこずを私に知らせおくれたLukasaに感謝したす。
私はPythonを初めお䜿甚し、3.6バヌゞョンを䜿甚しおいたす。 クラむアント蚌明曞のパスワヌドを枡すための暗号などのオプションを芋぀けるこずができる堎所を教えおください。
@Erikbern私は䞀時ファむルの解決策をただ経隓しおいたせんが、今日も同じこずを芋おいきたす。 返信ありがずうございたす。

@AnoopPillai load_cert_chainが必芁になりたす。

@Lukasaそれを文曞化しお

申し蚳ありたせんが、Pythonの経隓が䞍足しおいるこずが原因である可胜性がありたすが、Lukasaが䞊蚘で説明したコヌドを倉曎するこずはできたせん。 私のコヌドは次のずおりです。

class DESAdapter(HTTPAdapter):
    """
    A TransportAdapter that re-enables 3DES support in Requests.
    """
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(load_cert_chain='rtmqa-clientid.pem',password='weblogic')
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(load_cert_chain='rtmqa-clientid.pem', password='weblogic')
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
s = requests.Session()
s.mount(url, DESAdapter())
r = s.get(url, headers=request_header).json()

゚ラヌが発生したす
TypeErrorcreate_urllib3_contextが予期しないキヌワヌド匕数 'load_cert_chain'を取埗したした

はい、それは間違いです。 あなたは、呌び出したいcreate_urllib3_contextずその戻り倀を取埗した埌、呌び出しload_cert_chain返されたオブゞェクトの䞊に。 むンタラクティブむンタプリタでこれらの関数を詊しおみお、それらがどのように機胜するかを確認しおください。

Macにむンストヌルされおいるurllib3..util.ssl_.pyには、パスワヌドの最新のオプションがありたせん。
これはコヌドです

    if certfile:
        context.load_cert_chain(certfile, keyfile)
    if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
        return context.wrap_socket(sock, server_hostname=server_hostname)

パスワヌドオプションがありたせん。 ssl_.pyを曎新しお最新バヌゞョンを取埗するにはどうすればよいですか

@AnoopPillaiあなたはしたせん。 匕数なしで関数を呌び出しおから、返されたオブゞェクトに察しおload_cert_chainを呌び出したす。 urllib3を倉曎する必芁はありたせん。

明確にするために、このように

ctx = create_urllib3_context()
ctx.load_cert_chain(your_arguments_here)

これを文曞化したしょう:)

@ erikbern tempfile゜リュヌションを詊したしたが、次の゚ラヌが発生したした

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 441, in wrap_socket
    cnx.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1716, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1456, in _raise_ssl_error
    _raise_current_error()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 595, in urlopen
    self._prepare_proxy(conn)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 816, in _prepare_proxy
    conn.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connection.py", line 326, in connect
    ssl_context=context)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 448, in wrap_socket
    raise ssl.SSLError('bad handshake: %r' % e)
ssl.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='credit-cards-accounts-qa.kdc.capitalone.com', port=443): Max retries exceeded with url: /credit-cards-accounts/credit-cards/accounts/XqLuxBTABbIDvpw56ba34p2WV9JoWUSkPJ09hrBlWD8= (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/tsu892/Desktop/Office/Pythone-work/ASR-pythone/ASR-python3.6/test-request.py", line 48, in <module>
    r = requests.get(url, headers=request_header, cert=cert).json()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 506, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='credit-cards-accounts-qa.kdc.capitalone.com', port=443): Max retries exceeded with url: /credit-cards-accounts/credit-cards/accounts/XqLuxBTABbIDvpw56ba34p2WV9JoWUSkPJ09hrBlWD8= (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

以䞋は私のコヌドです

import requests
import json
import OpenSSL.crypto
import tempfile
import os
import contextlib
import ssl

json_file='apiInput.json'
hdr_key=[]
hdr_value=[]
json_data=open(json_file)
data = json.load(json_data)
request_body={}
#pprint(data)
json_data.close()
request_data = data['request1']
request_header=request_data['header-data']
url=request_header['url']

@contextlib.contextmanager
def pfx_to_pem():
    print('inside pfx tp pem')
    with tempfile.NamedTemporaryFile(suffix='.pem') as t_pem:
        f_pem = open(t_pem.name, 'wb')
        fr_pfx = open('rtmqa-clientid.pfx', 'rb').read()
        p12 = OpenSSL.crypto.load_pkcs12(fr_pfx,'xxxxxxxxx')
        f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
        f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
        ca = p12.get_ca_certificates()
        if ca is not None:
            for cert in ca:
                f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
        f_pem.close()
        yield t_pem.name

with pfx_to_pem() as cert:
    print(cert)
    r = requests.get(url, headers=request_header, cert=cert).json()
print(r.status_code)
print(r.json())

申し蚳ありたせんが、あなたのコメントから芋お、なぜそれが壊れおいるのかわかりたせん。 私はそれをたくさんのアプリケヌションに䜿甚したしたが、問題はありたせんでした

@Lukasaそのコヌド倉曎以䞋に貌り付けたコヌドを詊しおみたずころ、tempfileメ゜ッドで埗たのず同じ゚ラヌが発生したした。

import requests
import json
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

json_file='apiInput.json'
hdr_key=[]
hdr_value=[]
json_data=open(json_file)
data = json.load(json_data)
request_body={}
#pprint(data)
json_data.close()
request_data = data['request1']
request_header=request_data['header-data']
url=request_header['url']

class DESAdapter(HTTPAdapter):
    """
    A TransportAdapter that re-enables 3DES support in Requests.
    """
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context()
        context.load_cert_chain('rtmqa-clientid.pem',password='weblogic')
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context()
        context.load_cert_chain('rtmqa-clientid.pem',password='weblogic')
        kwargs['ssl_context'] = context
        return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)

s = requests.Session()
s.headers=request_header
s.mount(url, DESAdapter())
r = s.get(url)
/Users/tsu892/Python3.6/bin/python /Users/tsu892/Desktop/Office/Pythone-work/ASR-pythone/ASR-python3.6/Test-ASRreq.py
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 441, in wrap_socket
    cnx.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1716, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/SSL.py", line 1456, in _raise_ssl_error
    _raise_current_error()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 595, in urlopen
    self._prepare_proxy(conn)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 816, in _prepare_proxy
    conn.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connection.py", line 326, in connect
    ssl_context=context)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/ssl_.py", line 329, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py", line 448, in wrap_socket
    raise ssl.SSLError('bad handshake: %r' % e)
ssl.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='credit-cards-accounts-qa.kdc.capitalone.com', port=443): Max retries exceeded with url: /credit-cards-accounts/credit-cards/accounts/XqLuxBTABbIDvpw56ba34p2WV9JoWUSkPJ09hrBlWD8= (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/tsu892/Desktop/Office/Pythone-work/ASR-pythone/ASR-python3.6/Test-ASRreq.py", line 37, in <module>
    r = s.get(url)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 521, in get
    return self.request('GET', url, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 506, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='credit-cards-accounts-qa.kdc.capitalone.com', port=443): Max retries exceeded with url: /credit-cards-accounts/credit-cards/accounts/XqLuxBTABbIDvpw56ba34p2WV9JoWUSkPJ09hrBlWD8= (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

@erikbernは、私のラップトップのセットアップの問題である可胜性がありたす。 私はMac、Pythone3.6を䜿甚しおいたす

6c40089ea258:~ tsu892$ pip3 show requests
Name: requests
Version: 2.18.4
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: [email protected]
License: Apache 2.0
Location: /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Requires: idna, certifi, chardet, urllib3
6c40089ea258:~ tsu892$ pip3 show certifi
Name: certifi
Version: 2017.7.27.1
Summary: Python package for providing Mozilla's CA Bundle.
Home-page: http://certifi.io/
Author: Kenneth Reitz
Author-email: [email protected]
License: MPL-2.0
Location: /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Requires: 

蚌明曞に䜕か問題があるず思いたすか

python -m requests.helpの出力は䜕ですか

@Lukasa出力は次のずおりです。

6c40089ea258:~ tsu892$ python3 -m requests.help?
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3: No module named requests.help?

コマンドラむンから疑問笊を削陀しおください。

6c40089ea258:~ tsu892$ python3 -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.0.3"
  },
  "idna": {
    "version": "2.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.2"
  },
  "platform": {
    "release": "16.7.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "1010006f",
    "version": "17.2.0"
  },
  "requests": {
    "version": "2.18.4"
  },
  "system_ssl": {
    "version": "100020bf"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": true
}

したがっお、発生する゚ラヌは、サヌバヌのTLS蚌明曞を怜蚌できないこずが原因で発生したす。 certifiずOpenSSLは正しいように芋えるので、サヌバヌが誀動䜜しおいるず思いたす。 どのサヌバヌに到達しようずしおいたすか

アプリケヌションはクラりドAWSにデプロむされたす。 ただし、APIを呌び出すず、最初にOSBに送られ、蚌明曞が認蚌されおから、リク゚ストがAWSにルヌティングされたす。
同じ蚌明曞を䜿甚し、postmanたたはrubyコヌドを䜿甚するずAPIは正垞に機胜したす

特定のルヌト蚌明曞が必芁ですか 到達したホスト名を教えおいただけたすか

パスのないホストURLはhttps://credit-cards-accounts-qa.kdc.capitalone.comです
これは内郚゚ンドポむントです

ええ、そこで䜕が起こっおいるのかわかりたせん。 openssl s_client -showcerts -connect credit-cards-accounts-qa.kdc.capitalone.com:443を実行しお、完党な出力を提䟛できたすか

削陀されたした

これは、グロヌバルに信頌されおいるルヌト蚌明曞を䜿甚しおいないように芋えたす。 そのサヌビスのルヌト蚌明曞はどこにありたすか

他の蚌明曞は䜿甚しおいたせん。 舞台裏でルヌト蚌明曞が䜿甚されおいるかどうかわからないので、それを芋぀ける方法はありたすか

ええ、Chromeの開発者ツヌルはそれが䜿甚しおいる完党な蚌明曞チェヌンを教えおくれたす。

おそらく、誰かが芋るこずができるように内郚蚌明曞をオンラむンで投皿したくないでしょう...

@erikbernこれは公開情報です。 同じコマンドを実行するこずで、同じ結果を埗るこずができたす。

@ SethMichaelLarson @ erikbernのGitHubプロファむル「

@erikbern @ sigmavirus24ああ 誰ず話しおいるのかわからなかった。 続行 🙇

郵䟿配達員から実行するず、sha-1蚌明曞以倖は䜕も衚瀺されたせん
どういうわけかこれをPycharmに远加する必芁があるかもしれたせん

あなたが文字通りChromeでりェブサむトを閲芧するなら、それで十分なはずです。

@SethMichaelLarsonはどのコマンドを実行しおいたすか 参考たでに、コメントは削陀されたしたが、以前にここにBEGINCERTIFICATEブロブ党䜓がありたした...オンラむンで共有したくないず思いたす

@erikbernそれは蚌明曞の公開鍵にすぎたせんでした...

蚌明曞は公開デヌタです。 これらは、接続が詊行されるたびに、ネットワヌクを介しおプレヌンテキストで送信されたす。

蚌明曞チェヌンにアクセスしたしたが、APIをヒットするために䜿甚しおいるSha-1蚌明曞ず.Pem蚌明曞のみが芋぀かりたした

@AnoopPillaiパスワヌド付きのクラむアント偎pemファむルを䜿甚しお、9月1日のサンプルコヌドが問題なく機胜するようになりたした。 ホストは通垞​​の蚌明曞を䜿甚しおいるようです。 @Lukasaに感謝したす

残念ながら、Temp Fileメ゜ッドを䜿甚しおも、ただ問題が発生しおいたす。 Google Postmanで.pfxを䜿甚でき、認蚌に問題はありたせんしたがっお、クレデンシャルが機胜するこずはわかっおいたすが、Pythonで401を取埗しおいたす。 残念ながら、私が扱っおいる䌚瀟のサポヌト担圓者はあたり助けになりたせんでした-トラブルシュヌティングの提案はありたすか

この段階では、他の人が䞀時ファむル方匏で成功したず報告しおいお、蚌明曞管理チヌムから䜕も返事がないため、どこで問題を探すべきか本圓にわかりたせん。

アドバむスをいただければ幞いです。これを簡単にするための远加情報を提䟛できるかどうかお知らせください。

ありがずう 

単なる提案ですが、PFXをPEMに倉換しおみたしたか たた、サヌバヌがナヌザヌ名/パスワヌドも䜿甚しおいる堎合は、auth =を䜿甚しおget / postリク゚ストを远加する必芁がありたす。 パスワヌドで保護されたPEMファむルを䜿甚しお、䞊蚘のclass DESAdapter(HTTPAdapter)アプロヌチを数週間問題なく䜿甚しおいたす。

@ideaseanただ無効なクレデンシャルを取埗しおいたす。 䞀時ファむルメ゜ッド甚に蚘述されたpfx_to_pem関数によっお生成された.pemファむルをload_cert_chainに向ける必芁がありたすか 秘密鍵ず蚌明曞が含たれおいたす。

.pfxはPostmanで動䜜したすが、ここでは認蚌されないため、倉換プロセスで問題が発生しおいる可胜性がありたすか

䞀時ファむルメ゜ッドは䜿甚したせんでした。 䞊蚘の9月1日のAnoopPillaiの投皿に曞かれおいるように、DESAdapterアプロヌチをほが䜿甚したした。

私はそのコヌド倉曎以䞋に貌り付けられたコヌドを詊しおみたしたが、tempfileメ゜ッドで埗たのず同じ゚ラヌが発生したした。

倉換プロセスに぀いお話すこずはできたせんが、おそらく良いテストは、倉換されたpemファむルをPostmanで䜿甚しおみるこずです。

たた、私のpemファむルは暗号化/パスワヌドで保護されおおり、Pythonリク゚ストは珟圚それをサポヌトしおいないため、䞊蚘のアプロヌチを䜿甚したこずにも泚意しおください。 pemがパスワヌドで保護されおいない堎合は、リンクごずにネむティブリク゚ストを䜿甚できるはずですただし、ファむルシステムに保護されおいない蚌明曞がありたす。

@ideaseanこのメ゜ッドに埓っお.pfxを分解し、バッグ属性ず蚌明曞を含む.pemファむルず、バッグ属性ず暗号化された秘密鍵を含む.pemファむルを取埗したした。

ただ無効なクレデンシャルを取埗しおいるので、Postmanに蚌明曞を入れお、それらが機胜するかどうかを確認しようず思いたすが、この.pfxを正しく解凍できない理由がわかりたせん。

たた、opensslコマンドopenssl pkcs12 -in <my_pfx>.pfx -out certificate.cer -nodesを詊したしたが、次のように倉曎しおも401゚ラヌが発生したす context.load_cert_chain('certificate.cer')

䞊蚘の.cerをむンストヌルしたしたが、PostmanはAPI呌び出しを行うずきにそれを䜿甚するように芁求したせん.pfxを䜿甚するように芁求するポップアップずは異なりたす、他にどのようにその特定の蚌明曞を䜿甚させるこずができるかわかりたせんドキュメントに蚘茉されおいるような蚭定には「蚌明曞」パネルがないためです。

蚌明曞パネル、SSL怜蚌の無効化などが含たれおいないブラりザバヌゞョンのPostmanを䜿甚しおいる可胜性がありたす。クラむアント党䜓を詊しお蚌明曞の蚭定を倉曎しおください。 トピックから少し倖れおいるので、別のスレッドでこのディスカッションを続けるこずをお勧めしたす。

@ mkane848は、 ValueError: String expected受け取っおいた元のコメントを芋たした。 https://github.com/pyca/pyopenssl/issues/701およびhttps://github.com/shazow/urllib3/issues/1275を確認するこずをお勧めし

私はこれを䜿甚しおパスワヌドでプラむベヌトペムを䜿甚したす

from requests.adapters import HTTPAdapter

from urllib3.util.ssl_ import create_urllib3_context

class SSLAdapter(HTTPAdapter):
    def __init__(self, certfile, keyfile, password=None, *args, **kwargs):
        self._certfile = certfile
        self._keyfile = keyfile
        self._password = password
        return super(self.__class__, self).__init__(*args, **kwargs)

    def init_poolmanager(self, *args, **kwargs):
        self._add_ssl_context(kwargs)
        return super(self.__class__, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        self._add_ssl_context(kwargs)
        return super(self.__class__, self).proxy_manager_for(*args, **kwargs)

    def _add_ssl_context(self, kwargs):
        context = create_urllib3_context()
        context.load_cert_chain(certfile=self._certfile,
                                keyfile=self._keyfile,
                                password=str(self._password))
        kwargs['ssl_context'] = context

参考たでに、 requests PKCS12サポヌトを別のラむブラリずしお実装したした。

コヌドはクリヌンな実装です。モンキヌパッチも䞀時ファむルも䜿甚したせん。 代わりに、カスタムSSLContextを提䟛するカスタムTransportAdapterが䜿甚されたす。

フィヌドバックや改善は倧歓迎です

もちろん、 requestsがこの機胜を盎接提䟛するこずを望みたすが、そこに到達するたで、このラむブラリは苊痛を軜枛したす。

これを簡単に実行できれば非垞に䟿利です。

~~~
cert = "cert.pem"、 "key.pem"、 "somepassphrase"個別の蚌明曞/キヌ

cert=("keycert.pem", None, "somepassphrase")    # combined cert/key

~~~

... Python3.3以降でのみ機胜したずしおも。 これは、APIサヌフェスぞのマむナヌな远加にすぎたせん。

AFAICS、これは、HTTPSConnectionがオプションのpassword匕数を受け入れるように、urllib3に小さな倉曎を加えるこずを意味したす。 これはssl_wrap_socketを介しお枡され、最終的に次のようになりたす。

〜certfileの堎合パスワヌドがNoneでない堎合context.load_cert_chaincertfile、keyfile、passwordそうしないずcontext.load_cert_chaincertfile、keyfile〜

その堎合、䞋䜍互換性があり、サポヌトされおいない叀いプラットフォヌムで秘密鍵パスフレヌズを䜿甚しようずした堎合にのみ䟋倖が発生したす。

こずを泚意contrib/pyopenssl.pyアダプタは、すでにサポヌトに、この䜙分な匕数をload_cert_chain 、およびそうのpython 2.7 。


䜙談ですが、私はAWS KMSを䜿甚しお「シヌクレット」デヌタを管理しおいるため、アプリケヌションにハヌドコヌディングするのではなく、実行時にKMSからキヌパスワヌドをロヌドしたす。

個人的には、この倉曎に反察する぀もりはありたせん。これにより、党䜓的に倚くのナヌザヌのナヌザヌむンタヌフェむスが倧幅に改善されるず思いたす。

@ sigmavirus24䜕か考えはありたすか

@candlerb @kennethreitz PKCS12ケヌスをそのAPIに含めるこずもできたすか

cert=('keycert.p12', None, 'somepassphrase')

区別は、ファむル拡匵子 *.p12ず*.pem 、たたはそのファむルの最初のバむトを調べるこずによっお行うこずができたす。

安党に実行できる限り、リク゚ストがpkcs12を取埗できるようにするこずに問題はありたせん。私の意芋では、抜出された秘密鍵を䞀時ファむルに曞き蟌むこずはできたせん。

Python pkcs12をグヌグルで怜玢するず、次のこずがわかりたす。

  • 秘密鍵を曞き出す誰かのコヌド
  • 私が思う他のいく぀かのコヌドは、pkcs12で読み取るためにpyOpenSSLに䟝存しおいたす。 蚌明曞ずキヌをデヌタ項目ずしお返したす。

そのため、これらを含むファむル名ではなく、キヌ/蚌明曞自䜓がOpenSSLに枡されるように接続する必芁があるず思いたす。 それははるかに倧きな倉化のように聞こえたす。

それが難しすぎる堎合は、ナヌザヌがpkcs12をオフラむンでPEMに倉換する必芁があるこずを意味したす。これは非垞に簡単です文曞化できたす。

@candlerb以前のコメントhttps://github.com/requests/requests/issues/1573#issuecomment-348968658で曞いたように、 requestsずうたく統合するクリヌンな実装をすでに䜜成したした。

したがっお、あなたが説明しおいる問題はすでに解決されおいたす。

珟圚、私の実装では、新しいpkcs12_*キヌワヌド匕数を远加しお、できるだけ邪魔にならないようにしおいたす。

しかし、代わりにcertキヌワヌド匕数に統合する必芁があるず思いたす。私の質問は次のずおりです。

  • それは䞀般的に受け入れられたすか
  • 私の具䜓的な提案cert=('keycert.p12', None, 'somepassphrase')は受け入れられたすか
  • PKCS12ずPEMをどのように区別する必芁がありたすか ファむル名のサフィックス、たたはファむルの内容によっお

さらに、それを別のrequests_pkcs12ラむブラリではなく、 requests入れたいず思いたす。しかし、この問題の時代を考えるず、これがすぐに䞊流に行くこずはほずんど期埅できたせん。しかし、どの皮類の実装が正確に必芁かに぀いお具䜓的なステヌトメントがあれば、それに応じお実装を調敎し、プルリク゚ストを提案するこずができたす。

だから、いく぀かのこず

  1. certキヌワヌドをこのように拡匵するべきではないず思いたす。 これは暗黙的に構造化されたデヌタであり、人々はすでにfilesキヌワヌドのタプルによっお混乱しおいたす。 既知の悪いパタヌンを続けるのはばかげおいるず思いたす。

  2. どちらかずいえば、pkcs12アダプタヌを倉曎しお、requests-toolbeltにアップストリヌムする必芁があるず思いたす。 pkcs12パスワヌドをそのオブゞェクトのメモリに保存するのではなく、䞀床倉曎しおssl_contextを䜜成する方がよいず思いたす。

より䞀般的なケヌスでこれを凊理する前に、他にも実行する必芁のある䜜業があるず思いたす。これには、Requests3.0に適切なAPIを決定するこずも含たれたす。

@ sigmavirus24フィヌドバックをありがずう。

  1. では、個別のpkcs12_*キヌワヌドを保持したしょう。
  2. はい、それは間違いなく改善する䟡倀がありたす。 そのための課題远跡゚ントリを䜜成したした https 

PKCS12 TransportAdapterクラスはどのようにrequests含たれたすか そのクラスは単にrequestsに远加されるのでしょうか、それずも「より深い」レベルに含める別の方法があるので、 request()/get()/...ラッパヌなしで、明瀺的にロヌドするこずなく䜿甚できたす。アダプタ

私の組織はPKCS12蚌明曞を䜿甚する必芁があり、そのためにラむブラリに必芁な拡匵を行う甚意がありたす。 .p12ファむルを.pemファむルに埩号化するこずは、リスクが倧きすぎるず芋なされ、察凊するための远加の手順が远加されたす。 特定のセッションに適切なssl_contextを生成しお提䟛する機胜を远加したいず思いたす。 これは、適切に実装されおいるず仮定しお、チヌムが受け入れおも構わないず思っおいる機胜ですか

簡単なリマむンダヌクリヌンな実装はすでに圓瀟から提䟛されおいたすが、個別のアダプタヌずしお https 

リク゚スト自䜓のプルリク゚ストに自由に再フォヌマットしおください。

途䞭で、マむナヌな問題を修正するこずをお勧めしたす。ssl_contextは、セッション党䜓でメモリに保持するのではなく、特定の1぀の接続に察しおできるだけ短く保持する必芁がありたす。 参照

途䞭で修正する堎合は、リク゚スト自䜓に加えお、 https//github.com/m-click/requests_pkcs12ぞの小さなプルリク゚ストずしお提䟛できるず䟿利です。

そうすれば、珟圚requests_pkcs12ラむブラリを䜿甚しおいるすべおの人が、リク゚スト自䜓のためにその埌改善された新しいAPIに切り替えるこずなく、その改善から自動的に恩恵を受けるこずになりたす。

ええ、 https//github.com/m-click/requests_pkcs12は私のために働き、私が望んでいたこずを正確に実行したした。 どうもありがずう

たた、 @ vogの実装に感謝し、期埅どおりに機胜し、私の堎合はS3のような安党でないストレヌゞに蚌明曞/キヌを保持する問題を解決したす。 うたくいけば、これはrequests到達する可胜性がありたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡