Python SDKでOCI Vaultを操作する② - デジタル署名 -


Vaultは、RSA, ECDSAといった公開鍵を使用したデジタル署名を実行することが可能です。デジタル署名は、ファイルの真正・非改ざん性を証明する技術で、ファイル送受信のアプリケーションなどに組み込まれて使われていることも多いかと思います。デジタル署名に最も重要な役割を持つのがRSAの暗号鍵ですが、VaultのAPIを利用することで暗号鍵をセキュアに管理しつつ、APIによるデジタル署名を実現できます。

ここでは、実際にデジタル署名を実行するPythonコードを紹介します。

ファイルのデジタル署名と検証をする

事前にVaultにデジタル署名で使用するためのRSAのマスター暗号鍵を作成します。Vaultの管理エンドポイント、Vaultの暗号エンドポイント、マスター暗号鍵のOCIDはターゲットのVaultの詳細情報から取得し、コード内に追記します。

#ファイルのメッセージダイジェストを署名/検証するサンプルコード
import oci,os,sys,hashlib
config = oci.config.from_file("~/.oci/config","DEFAULT")

key_crypto_client = oci.key_management.KmsCryptoClient(
    config, "<Vaultの管理エンドポイント>")

key_management_client = oci.key_management.KmsManagementClient(
    config, "<Vaultの暗号エンドポイント>")

#Masiter RSA Key
Master_RSA_Key="<マスター暗号鍵(RSA)のOCID>"

#ファイルのハッシュ値を取得
plaintext = sys.argv[1]
filepath=os.getcwd()

with open(filepath + "\\" + plaintext,"rb") as file:
    data = file.read()

hash_sha256 = hashlib.sha256(data).hexdigest()
print ("*****デジタル署名*****")
print ("検証するファイル:  " + plaintext )
print ("メッセージダイジェスト:  " + hash_sha256)
print ("VaultのRSAキー:  " + Master_RSA_Key)
print ("")

#署名
sing_response = key_crypto_client.sign(
    sign_data_details=oci.key_management.models.SignDataDetails(
        message=hash_sha256,
        key_id=Master_RSA_Key,
        signing_algorithm="SHA_224_RSA_PKCS_PSS",
        message_type="RAW")
)
response_signature=sing_response.data.signature
print("デジタル署名:  " + response_signature)
print ("")

#署名検証
verify_response = key_crypto_client.verify(
    verify_data_details=oci.key_management.models.VerifyDataDetails(
        message=hash_sha256,
        signature=response_signature,
        key_id=Master_RSA_Key,
        signing_algorithm="SHA_224_RSA_PKCS_PSS",
        message_type="RAW")
)

print ("*****デジタル署名の検証*****")
print ("検証するファイル:  " + plaintext )
print ("メッセージダイジェスト:  " + hash_sha256)
print ("VaultのRSAキー:  " + Master_RSA_Key)
print ("デジタル署名:  " + response_signature)
print ("結果:  " + str(verify_response.data.is_signature_valid))
print ("")

サンプルコードはsing.pyとして保存し、デジタル署名をするテキストファイルをカレントディレクトリに一つ用意します。

#実行例
$ python .\sign.py sampledata.txt

*****デジタル署名*****
検証するファイル:  sampledata.txt
メッセージダイジェスト:  9ab0578eaf44cafd1593d9491cf0f53e185d93626b19a8b219354aa12685d1d1
VaultのRSAキー:  ocid1.key.oc1.iad.bbpadvkaaacuu.xxxxxxx
デジタル署名:  vBJXvio33W0jP7B/7cD/ONHzDromOv6OZowh5zqZhTT69+fpRfwgWeElvUxcOUEdHWG0h9uFRr5tjFrm/wok5+gUd4DQB0nFyo3Tw9RPGLfpJxDGpumu6o1GR/xFwMI8l9xFWF52bKeiXSRD29kptPUe7sSMp2L3ROZ/emgl7qCXp7BAY6Yw8D635j66UzwAYWrri+31bcU6iKCtdtRlujDI3ndqD5RbKD7jv+bdGc8eXiUtfOEuyrtp31tYZIml+YJVAfPxvhitK0gJuxCfbOi6X2J40ToRKsA+KCV4C654jfxJUWf6J3QUDywOM2DQNK/lNBnoMr4tKoh3e7fihQ==

*****デジタル署名の検証*****
検証するファイル:  sampledata.txt
メッセージダイジェスト:  9ab0578eaf44cafd1593d9491cf0f53e185d93626b19a8b219354aa12685d1d1
VaultのRSAキー:  ocid1.key.oc1.iad.bbpadvkaaacuu.xxxxxxx
デジタル署名:  vBJXvio33W0jP7B/7cD/ONHzDromOv6OZowh5zqZhTT69+fpRfwgWeElvUxcOUEdHWG0h9uFRr5tjFrm/wok5+gUd4DQB0nFyo3Tw9RPGLfpJxDGpumu6o1GR/xFwMI8l9xFWF52bKeiXSRD29kptPUe7sSMp2L3ROZ/emgl7qCXp7BAY6Yw8D635j66UzwAYWrri+31bcU6iKCtdtRlujDI3ndqD5RbKD7jv+bdGc8eXiUtfOEuyrtp31tYZIml+YJVAfPxvhitK0gJuxCfbOi6X2J40ToRKsA+KCV4C654jfxJUWf6J3QUDywOM2DQNK/lNBnoMr4tKoh3e7fihQ==
結果:  True

ファイルから32バイトのメッセージダイジェストを生成し、その値に対するデジタル署名をVaultのRSAマスター暗号鍵を使用して行い、デジタル署名の値を生成します。
実際には、送信者はファイルとこのデジタル署名を一緒に送ります。受信者は、そのファイルが改ざんされていないか正しいファイルかを検証するには、ファイルからメッセージダイジェストを生成し、受け取ったデジタル署名と一緒にVualtに送信して、検証してもらいます。正しければ、True、何らかの改ざんが検出されれば、Falseとなります。

また、4KB以下であればメッセージダイジェストにせずとも、そのままメッセージとして送信可能です。