コンテンツにスキップ

暗号化する

ormarは、データベース内のフィールドのみを暗号化する方法を提供します。提供されている暗号化バックエンドでは、一方向暗号化(HASHバックエンド)と双方向暗号化/復号化(FER NETバックエンド)が可能です。

!!!警告暗号化を機能させるには、オプションの暗号化パッケージをインストールする必要があることに注意してください。

1
あなたはそれを手動で行うことができます `pip install cryptography` またはormar by `pip install ormar[crypto]`

!!!警告暗号化_バックエンドを追加すると、データベースのカラムタイプがTEXTに変更されることに注意してください

フィールド暗号化の定義

フィールドを暗号化するには、少なくともcrypt_secretとcrypt_backendパラメータを渡す必要があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
base_ormar_config=ormar. OrmarConfig(ベースの設定
    メタデータ
    データベース
)

class Filter(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100,
                             crypt_secret="secret 123",
                             crypt_backend=ormar. EncryptBackend.FER NET)

!!!は、第一次_keyカラムとオフシリーズ(ForeignKeyとManyTomany)を除くすべてのフィールドタイプを暗号化できると警告しています。詳細については、バックエンドの詳細を確認してください。

利用可能なバックエンド

ハッシュ

HASHは一方向ハッシュ(パスワードなど)であり、検索時に復号化されることはありません

設定するには、適切なバックエンド値を渡します。

1
2
3
4
。。。 #残りのモデル定義
パスワード: str=ormar.String(max_length=128,
                         crypt_secret="secret 123",
                         crypt_backend=ormar. EncryptBackend.HASH)

このバックエンドは格納された値を復号化することは決してないので、文字列フィールドにのみ適用されることに注意してください。使用されるハッシュはsha 512ハッシュなので、フィールド長は>=128でなければなりません。

警告HASHバックエンドでは、完全な値でフィルタリングできますが、暗号化された値が比較されるため、インクルードなどのフィルターは機能しないことに注意してください

!!!note提供されているcrypt_secretは最初にそれ自体をハッシュしてソルトとして使用するため、保存されている文字列と比較するには、このステップを再作成する必要があることに注意してください。 order_byは、暗号化された文字列を比較しているために機能しないため、確実にソートできません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Hash(ormar. Model):
    or_config=base_or_config. copy(tablename="ハッシュ")

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=128,
                             crypt_secret="udxc 32",
                             crypt_backend=ormar. EncryptBackend.HASH)


await Hash(name='test 1'). save()

#保存された値を再作成する手順に注意してください
#hashlibの代わりに暗号化パッケージも使用できます
secret=hashlib. sha 256("udxc 32".encode()).digest()
secret=base 64. urlsafe_b 64エンコード(secret)
hashed_test 1=hashlib. sha 512(secret+'test 1'.encode()).hexdigest()

#フルバリュー比較機能
hash 1=await Hash. object.get(name='test 1')
asserthash1.name_test 1

#しかし、部分比較はしません(ハッシュされた文字列が比較されます)
pytest.レイズ(NoMatch)を使用して:
    await Filter. object.get(name__icontains='test')

フェネット

FERNETは双方向暗号化/復号化バックエンドです

設定するには、適切なバックエンド値を渡します。

1
2
3
。。。 #残りのモデル定義
year: int=ormar.Integer(crypt_secret="secret 123",
                          crypt_backend=ormar. EncryptBackend.FER NET)

値はデータベース側に到達する途中で暗号化され、外に出るときに復号化されます。返り値は対応するpythonタイプに解析されるため、すべてのタイプに使用できます。

!!!警告FERNETバックエンドでは、暗号化された値の一部がタイムスタンプであるため、フィルタリングの可能性が完全に失われることに注意してください。暗号化された文字列を比較するため、確実にソートできないため、order_byも同様です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Filter(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100,
                             crypt_secret="asd 123",
                             crypt_backend=ormar. EncryptBackend.FER NET)

awaitフィルター(name='test 1'). save()
awaitフィルター(name='test 1'). save()

#値は適切に暗号化され、後で復号化される
filters=await Filter. object.all()
assert filters[0]. name==filters[1]. name=='test 1'

#しかし、fernetハッシュの一部がタイムスタンプであるため、フィルターをかけることはできません。
#同じ文字列を2回暗号化しても異なることを意味します
pytest.レイズ(NoMatch)を使用して:
    await Filter. object.get(name='test 1')

カスタムバックエンド

他の種類の暗号化(AES)をサポートしたい場合は、独自のEncryptionBackendを提供できます。

バックエンドを設定するには、ormar. field.EncryptBackendクラスをサブクラス化し、必要なバックエンドを提供するだけです。

何も実行しない仮想バックエンドの例は次のようになります。

1
2
3
4
5
6
7
8
9
class DummyBackend(ormar. field.EncryptBackend):
    def_initialize_backend(self, secret_key:bytes)->None:
        パス

    def crypt(self, value:Any)->str:
        戻り値

    def decrypt(self, value:Any)->str:
        戻り値

このバックエンドを使用するには、暗号化_backendをCUSTOMに設定し、暗号化_カスタム_backendを使用してバックエンドを引数として指定します。

1
2
3
4
5
6
7
8
9
class Filter(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100,
                             crypt_secret="secret 123",
                             crypt_backend=ormar. EncryptBackends.CUSTOM,
                             暗号化_カスタム_backend=DummyBackend
                             )