Python のParamiko ライブラリを使用すると、ssh-agent に少しのデータに署名するように要求できます。それは素晴らしいことです!しかし、エージェントではなく公開鍵にしかアクセスできない場合、その署名をどのように検証すればよいでしょうか?
from base64 import b64encode
from paramiko.agent import Agent
agent = Agent()
key = agent.get_keys()[0]
sig = key.sign_ssh_data(None, "Hello World!")
print b64encode(sig)
# AAAAB3NzaC1yc2EAAAEAqZFIGxm1Zz3ALeTa2YiiYX2rbr9Cnb3gj4tJj1Fl19sNsRy6UbbauYnmahYWl6mWqhOHJaj0sAtVqPab8U1RiyeZyQB+Bwp0MUal4ZGCmrJxJ7ykVE+BeJnpOxXyutHHV376TXC5l+tx0PjFsylL1vVbBm6J927Nyc/cq1uk0q2QpcRexg0iJ51i1WGyISVvu1PC+g0LmW1dGh2mXTo/fpt+Cu45/hjWpMlcBUg8O60+nkj2jYxxGVh/z7U6zTYrDSJU4hTEveuKG5I38gsaMRBw/YkSIaMtkGNJX36Ybc+/EVolL4Z/NOOCV+kd7WPHjSTf1hVZ02ulTTrnMN4HfA==
思いつく限りのあらゆる解決策を試しました。OpenSSL は、私が使用しているキー (ssh-keygen によって生成されたもの) を見ることさえできません:
$ ssh-keygen -f ~/.ssh/testssh.pub -e -m pem > test.pub
$ cat test.pub
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA7Zs6ZyrHk3RpDKv7Kzd7NCU2Qk5k5ajVJvntRPiEukWOIe4CkcBo
B76HSDyPvEDI50DUyebj2Qj77NDX/lh5AhDrVTEmX/Lfzx2iCwgpWwQcu8dgAaN5
qhsCMYOc77d2YykcnbDUhgxus/KiieLnruKmviVdSHoLBs6ygnVEa+8nx+DhJwSB
B3+6gClM89QnKrPYOonj9z4zi+UeWPX9TVwJVOAADnXEC6LCmDCgHDb+FrCaiNT9
d4yam3iZJ2RMQ+ajBj6JWvoig2LdUBI7eSgmrREjjEEskBCNRkD4YmjeT8mfZg9d
FhbGz0CQjnF31jiohIvhABTwcUQnDdrPEQIDAQAB
-----END RSA PUBLIC KEY-----
$ openssl rsa -inform PEM -in test.pub -pubin -text
unable to load Public Key
140735078689212:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:696:Expecting: PUBLIC KEY
PyCrypto は、同じデータに対してまったく異なる署名を作成します。
from base64 import b64encode
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
# PyCrypto
key = RSA.importKey(open('.ssh/testssh').read())
signer = PKCS1_v1_5.new(key)
h = SHA.new()
h.update("Hello World!")
sig = signer.sign(h)
print "CRYPTO: %s" % b64encode(sig)
# CRYPTO: qZFIGxm1Zz3ALeTa2YiiYX2rbr9Cnb3gj4tJj1Fl19sNsRy6UbbauYnmahYWl6mWqhOHJaj0sAtVqPab8U1RiyeZyQB+Bwp0MUal4ZGCmrJxJ7ykVE+BeJnpOxXyutHHV376TXC5l+tx0PjFsylL1vVbBm6J927Nyc/cq1uk0q2QpcRexg0iJ51i1WGyISVvu1PC+g0LmW1dGh2mXTo/fpt+Cu45/hjWpMlcBUg8O60+nkj2jYxxGVh/z7U6zTYrDSJU4hTEveuKG5I38gsaMRBw/YkSIaMtkGNJX36Ybc+/EVolL4Z/NOOCV+kd7WPHjSTf1hVZ02ulTTrnMN4HfA==
明らかに、私は暗号学者ではありません。私は過去 12 時間、ssh-agent 署名を検証する方法を見つけようとしてコードを読んでいました。私が見逃している痛々しいほど明らかなものはありますか?これを行う「正しい」方法は何ですか?
アップデート
ここで概説されている M2Crypto 検証プロセスに従って、ssh-agent の署名に対して次のエラーが発生します。
Traceback (most recent call last):
File "test.py", line 36, in <module>
print key.verify(datasha.digest(), agentsig)
File "/Users/shbeta/virtualenvs/dev/lib/python2.7/site-packages/M2Crypto-0.21.1-py2.7-macosx-10.7-intel.egg/M2Crypto/RSA.py", line 259, in verify
M2Crypto.RSA.RSAError: wrong signature length
ただし、Crypto で生成された署名に対するテストは成功します。ssh-agent は非標準の署名アルゴリズムを使用していますか?
更新 2: 編集済み。読み違えました。