目的
ZMQで認証&通信暗号化をしてみます。言語はPythonを使います。
コード
REQ-REPで試してみます。Public keyとSecret keyを作成するコード、サーバーのコード、クライアントのコードが必要になります。
キー作成
次のgen_keys.pyを作成し、pythonで実行します。
1 2 3 4 5 6 7 8 9 10 11 | import os
import zmq
import zmq.auth
def main():
os.makedirs("cert", exist_ok=True)
server_public_file, server_secret_file = zmq.auth.create_certificates("cert", "server")
client_public_file, client_secret_file = zmq.auth.create_certificates("cert", "client")
if __name__ == '__main__':
main()
|
client.key client.key_secret server.key server.key_secretの4つのファイルが作成されます。
サーバー
サーバーのコードは以下の通り。サーバー側に認証機能をつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
def main():
ctx = zmq.Context.instance()
auth = ThreadAuthenticator(ctx)
auth.start()
auth.configure_curve(location="cert") # Need only public keys
server = ctx.socket(zmq.REP)
server.curve_publickey, server.curve_secretkey = zmq.auth.load_certificate("cert/server.key_secret")
server.curve_server = True
server.bind('tcp://*:9000')
while True:
msg = server.recv_pyobj()
print("server:", msg)
server.send_pyobj("123")
if __name__ == '__main__':
main()
|
クライアント
クライアントのコードは以下の通り。サーバーのpublic keyが必要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import zmq
import zmq.auth
def main():
ctx = zmq.Context.instance()
client = ctx.socket(zmq.REQ)
client.curve_publickey, client.curve_secretkey = zmq.auth.load_certificate("cert/client.key_secret")
client.curve_serverkey, _ = zmq.auth.load_certificate("cert/server.key")
client.connect('tcp://127.0.0.1:9000')
client.send_pyobj("abc")
msg = client.recv_pyobj()
print("client:", msg)
if __name__ == '__main__':
main()
|
server: abcクライアント側に
client: 123と表示されます。 クライアント側で指定するサーバーのPublic keyを間違えるとサーバーには接続できません。 また、Wiresharkで通信内容を見た限りでは、abcや123は平文では通信されていませんでした。 一方、認証関連のコード(authやcurve関連)を削除して実行すると、abcや123を平文で読むことができました。
参考
https://github.com/zeromq/pyzmq/blob/main/examples/security/generate_certificates.py
https://github.com/zeromq/pyzmq/blob/main/examples/security/ironhouse.py
0 件のコメント :
コメントを投稿