表 12.18 「暗号化関数」
名前 | 説明 |
---|---|
AES_DECRYPT() |
AES を使用して復号化します |
AES_ENCRYPT() |
AES を使用して暗号化します |
COMPRESS() |
バイナリ文字列として結果を返します |
MD5() |
MD5 チェックサムを計算します |
RANDOM_BYTES() |
ランダムなバイトベクトルを返します |
SHA1() , SHA() |
SHA-1 160 ビットチェックサムを計算します |
SHA2() |
SHA-2 チェックサムを計算します |
STATEMENT_DIGEST() |
ステートメントダイジェストハッシュ値の計算 |
STATEMENT_DIGEST_TEXT() |
正規化されたステートメントダイジェストの計算 |
UNCOMPRESS() |
圧縮された文字列を圧縮解除します |
UNCOMPRESSED_LENGTH() |
圧縮前の文字列長を返します |
VALIDATE_PASSWORD_STRENGTH() |
パスワードの強度を判断します |
多くの暗号化関数および圧縮関数では、結果に任意のバイト値が含まれている可能性のある文字列が返されます。 これらの結果を格納する場合は、VARBINARY
または BLOB
バイナリ文字列データ型のカラムを使用します。 これにより、バイナリ以外の文字列データ型 (CHAR
, VARCHAR
, TEXT
) を使用している場合など、データ値を変更する可能性がある後続の領域削除または文字セット変換の潜在的な問題を回避できます。
一部の暗号化関数は ASCII 文字の文字列を返します: MD5()
, SHA()
, SHA1()
, SHA2()
, STATEMENT_DIGEST()
, STATEMENT_DIGEST_TEXT()
。 戻り値は、character_set_connection
および collation_connection
システム変数によって決定される文字セットと照合順序を持つ文字列です。 これは、文字セットが binary
でないかぎり、非バイナリ文字列です。
アプリケーションで 16 進数の文字列を返す関数 (MD5()
や SHA1()
など) からの値を格納する場合は、UNHEX()
を使用して 16 進表現をバイナリに変換し、その結果を BINARY(
カラムに格納すれば、より効率的な格納および比較を実現できます。 16 進数の各ペアにはバイナリ形式で 1 バイトが必要であるため、N
)N
の値は 16 進数文字列の長さに依存します。 N
は、MD5()
値の場合は 16、SHA1()
の場合は 20 です。 SHA2()
の場合、N
の範囲は、結果の目的のビット長を指定する引数に応じて 28 から 32 までです。
utf8
文字セット (文字ごとに 4 バイト使用されます) が使用されるカラムに値が格納される場合に、16 進文字列を CHAR
カラムに格納する際のサイズのペナルティーは最小で 2 回、最大で 8 回です。 また、文字列を格納すると、値が大きくなり、文字セットの照合順序ルールを考慮に入れる必要があるため、比較が遅くなります。
アプリケーションで MD5()
文字列値が CHAR(32)
カラムに格納されると仮定します。
CREATE TABLE md5_tbl (md5_val CHAR(32), ...);
INSERT INTO md5_tbl (md5_val, ...) VALUES(MD5('abcdef'), ...);
16 進文字列をよりコンパクトな形式に変換するには、次のように、代わりに UNHEX()
および BINARY(16)
が使用されるようにアプリケーションを変更します。
CREATE TABLE md5_tbl (md5_val BINARY(16), ...);
INSERT INTO md5_tbl (md5_val, ...) VALUES(UNHEX(MD5('abcdef')), ...);
ハッシュ関数が 2 つの異なる入力値に同じ値を生成するという非常にまれなケースに対応できるように、アプリケーションが準備されるはずです。 競合を検出可能にする方法の 1 つは、ハッシュカラムを主キーにすることです。
MD5 および SHA-1 アルゴリズムの悪用が知られています。 かわりに、このセクションで説明されている別の一方向暗号化機能 (SHA2()
など) の使用を検討してください。
暗号化機能の引数として指定されたパスワードまたはその他の機密値は、SSL 接続が使用されないかぎり、クリアテキストとして MySQL サーバーに送信されます。 また、このような値は、書き込まれるすべての MySQL ログに表示されます。 このようなタイプの露出を回避するために、アプリケーションはクライアント側で機密の値を暗号化してから、サーバーに送信できます。 同じ考慮事項が暗号化鍵にも適用されます。 これらの露出を回避するために、アプリケーションはストアドプロシージャーを使用して、サーバー側で値を暗号化および復号化できます。
-
AES_DECRYPT(
crypt_str
,key_str
[,init_vector
])この関数は、公式の AES (Advanced Encryption Standard) アルゴリズムを使用してデータを復号化します。 詳細は、
AES_ENCRYPT()
の説明を参照してください。AES_DECRYPT()
を使用するステートメントは、ステートメントベースのレプリケーションでは安全ではありません。 -
AES_ENCRYPT(
str
,key_str
[,init_vector
])AES_ENCRYPT()
およびAES_DECRYPT()
では、AES (Advanced Encryption Standard) アルゴリズム (以前は 「Rijndael」 と呼ばれていました) を使用したデータの暗号化および復号化が実装されます。 AES の標準では、さまざまな鍵の長さが許可されます。 デフォルトでは、これらの関数で鍵の長さが 128 ビットの AES が実装されます。 あとで説明するように、196 または 256 ビットの鍵の長さを使用できます。 鍵の長さは、パフォーマンスとセキュリティーの間でのトレードオフです。AES_ENCRYPT()
は、鍵文字列key_str
を使用して文字列str
を暗号化し、暗号化された出力を含むバイナリ文字列を返します。AES_DECRYPT()
は、鍵文字列key_str
を使用して暗号化された文字列crypt_str
を復号化し、元のプレーンテキスト文字列を返します。 関数引数のいずれかがNULL
の場合は、関数でNULL
が返されます。str
およびcrypt_str
引数は任意の長さにすることができ、AES などのブロックベースのアルゴリズムによって、必要に応じてブロックの倍数になるように、自動的にパディングがstr
に追加されます。 このパディングは、AES_DECRYPT()
関数によって自動的に削除されます。crypt_str
の長さは、次の公式を使用して計算できます。16 * (trunc(string_length / 16) + 1)
鍵の長さが 128 ビットの場合、
key_str
引数に鍵を渡すもっともセキュアな方法は、完全にランダムな 128 ビット値を作成し、それをバイナリ値として渡すことです。 例:INSERT INTO t VALUES (1,AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
パスフレーズを使用すると、パスフレーズをハッシュ化することで AES 鍵を生成できます。 例:
INSERT INTO t VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));
パスワードまたはパスフレーズは直接
crypt_str
に渡さず、最初にハッシュ化してください。 このドキュメントの以前のバージョンでは、従来のアプローチが提案されていましたが、ここで示す例の方がセキュアであるため、推奨されなくなりました。AES_DECRYPT()
で無効な日付または不正なパディングが検出された場合は、NULL
が返されます。 ただし、入力データまたは鍵が無効になっている場合は、AES_DECRYPT()
でNULL
以外の値 (ごみの可能性もあります) が返される可能性があります。AES_ENCRYPT()
およびAES_DECRYPT()
は、ブロック暗号化モードの制御を許可し、オプションのinit_vector
初期化ベクトル引数を取ります:block_encryption_mode
システム変数は、ブロックベースの暗号化アルゴリズムのモードを制御します。 そのデフォルト値は、128 ビットの鍵の長さと ECB モードを使用した暗号化を表すaes-128-ecb
です。 この変数で許可されている値については、セクション5.1.8「サーバーシステム変数」を参照してください。オプションの
init_vector
引数では、必要とするブロック暗号化モードに対応する初期化ベクトルが提供されます。
オプションの
init_vector
引数が必要なモードでは、16 バイト以上の長さにする必要があります (16 を超えるバイトは無視されます)。init_vector
が欠落している場合は、エラーが発生します。init_vector
が必要ないモードでは、これが無視され、指定されている場合は警告が生成されます。RANDOM_BYTES(16)
を呼び出すと、初期化ベクトルに使用されるバイトのランダム文字列を生成できます。 初期化ベクトルが必要な暗号化モードでは、暗号化および復号化でも同じベクトルを使用する必要があります。mysql> SET block_encryption_mode = 'aes-256-cbc'; mysql> SET @key_str = SHA2('My secret passphrase',512); mysql> SET @init_vector = RANDOM_BYTES(16); mysql> SET @crypt_str = AES_ENCRYPT('text',@key_str,@init_vector); mysql> SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector); +-----------------------------------------------+ | AES_DECRYPT(@crypt_str,@key_str,@init_vector) | +-----------------------------------------------+ | text | +-----------------------------------------------+
次のテーブルに、許可される各ブロック暗号化モードと、初期化ベクトル引数が必要かどうかを示します。
ブロック暗号化モード 初期化ベクトルが必要 ECB いいえ CBC はい CFB1 はい CFB8 はい CFB128 はい OFB はい AES_ENCRYPT()
またはAES_DECRYPT()
を使用するステートメントは、ステートメントベースのレプリケーションでは安全ではありません。 -
COMPRESS(
string_to_compress
)文字列を圧縮し、その結果をバイナリ文字列として返します。 この関数を使用するには、MySQL が
zlib
などの圧縮ライブラリを使用してコンパイルされている必要があります。 そうでない場合、戻り値は常にNULL
になります。 圧縮された文字列は、UNCOMPRESS()
を使用して圧縮解除できます。mysql> SELECT LENGTH(COMPRESS(REPEAT('a',1000))); -> 21 mysql> SELECT LENGTH(COMPRESS('')); -> 0 mysql> SELECT LENGTH(COMPRESS('a')); -> 13 mysql> SELECT LENGTH(COMPRESS(REPEAT('a',16))); -> 15
圧縮された文字列の内容は、次の方法で格納されます。
空の文字列は、空の文字列として格納されます。
空以外の文字列は、4 バイトの長さの圧縮されていない文字列として格納され (低いバイトが 1 番目)、そのあとに圧縮された文字列が続きます。 文字列が空白文字で終わる場合は、結果が
CHAR
またはVARCHAR
カラムに格納されていても、末尾の空白文字が削除されるという問題が回避されるように、.
文字が追加されます。 (ただし、CHAR
やVARCHAR
などの非バイナリ文字列のデータ型を使用して圧縮された文字列を格納すると、文字セットの変換が発生する可能性があるため、いずれにしても推奨されません。 代わりに、VARBINARY
またはBLOB
バイナリ文字列のカラムを使用してください。)
-
MD5(
str
)文字列の MD5 128 ビットチェックサムを計算します。 値は 32 桁の 16 進数の文字列、または引数が
NULL
の場合はNULL
として返されます。 たとえば、戻り値をハッシュ鍵として使用できます。 効率的なハッシュ値の格納については、このセクションの冒頭で示した注記を参照してください。戻り値は、接続文字セットの文字列です。
FIPS モードが有効な場合、
MD5()
はNULL
を返します。 セクション6.8「FIPS のサポート」を参照してください。mysql> SELECT MD5('testing'); -> 'ae2b1fca515949e5d54fb22b8ed95575'
これは、「RSA Data Security, Inc. MD5 Message-Digest Algorithm」 です。
このセクションの冒頭で示した MD5 アルゴリズムに関する注記を参照してください。
-
RANDOM_BYTES(
len
)この関数は、SSL ライブラリの乱数ジェネレータを使用して生成された
len
ランダムバイトのバイナリ文字列を戻します。len
で許可されている値は、1 から 1024 までの範囲内です。 その範囲外の値の場合は、エラーが発生します。RANDOM_BYTES()
を使用すると、AES_DECRYPT()
およびAES_ENCRYPT()
関数に初期化ベクトルを提供できます。 このコンテキストで使用するには、len
を 16 以上にする必要があります。 さらに大きい値も許可されますが、16 を超えるバイトは無視されます。RANDOM_BYTES()
は、その結果を非決定的にするランダムな値を生成します。 したがって、この関数を使用するステートメントは、ステートメントベースレプリケーションでは安全ではありません。 -
SHA1(
,str
)SHA(
str
)RFC 3174 (Secure Hash Algorithm) で説明されているように、文字列の SHA-1 160 ビットチェックサムを計算します。 値は 40 桁の 16 進数の文字列、または引数が
NULL
の場合はNULL
として返されます。 この関数を使用する一例として、ハッシュ鍵が考えられます。 効率的なハッシュ値の格納については、このセクションの冒頭で示した注記を参照してください。SHA()
はSHA1()
のシノニムです。戻り値は、接続文字セットの文字列です。
mysql> SELECT SHA1('abc'); -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
SHA1()
はMD5()
と同等ですが、暗号化に関してはよりセキュアであると考えられます。 ただし、このセクションの冒頭で示した MD5 と SHA-1 アルゴリズムに関する注記を参照してください。 -
SHA2(
str
,hash_length
)SHA-2 ファミリのハッシュ関数 (SHA-224、SHA-256、SHA-384、および SHA-512) を計算します。 最初の引数は、ハッシュされるプレーンテキスト文字列です。 2 番目の引数には、結果の目的のビット長が指定されます。値は、224、256、384、512、または 0 (256 と同等です) にする必要があります。 引数のいずれかが
NULL
の場合や、ハッシュの長さが許可される値のいずれでもない場合は、戻り値がNULL
になります。 それ以外の場合は、関数の結果が目的のビット数が含まれるハッシュ値になります。 効率的なハッシュ値の格納については、このセクションの冒頭で示した注記を参照してください。戻り値は、接続文字セットの文字列です。
mysql> SELECT SHA2('abc', 224); -> '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'
この関数は、MySQL が SSL サポートで構成されている場合のみ機能します。 セクション6.3「暗号化された接続の使用」を参照してください。
SHA2()
はMD5()
やSHA1()
よりも、暗号化に関してはよりセキュアであると考えられます。 -
STATEMENT_DIGEST(
statement
)SQL ステートメントを文字列として指定すると、ステートメントダイジェストハッシュ値を接続文字セットの文字列として、または引数が
NULL
の場合はNULL
として戻します。 関連するSTATEMENT_DIGEST_TEXT()
関数は、正規化されたステートメントダイジェストを返します。 ステートメントダイジェストの詳細は、セクション27.10「パフォーマンススキーマのステートメントダイジェストとサンプリング」 を参照してください。どちらの関数も、MySQL パーサーを使用してステートメントを解析します。 解析に失敗すると、エラーが発生します。 エラーメッセージに解析エラーが含まれるのは、ステートメントがリテラル文字列として指定されている場合のみです。
max_digest_length
システム変数は、正規化されたステートメントダイジェストを計算するためにこれらの関数で使用できる最大バイト数を決定します。mysql> SET @stmt = 'SELECT * FROM mytable WHERE cola = 10 AND colb = 20'; mysql> SELECT STATEMENT_DIGEST(@stmt); +------------------------------------------------------------------+ | STATEMENT_DIGEST(@stmt) | +------------------------------------------------------------------+ | 3bb95eeade896657c4526e74ff2a2862039d0a0fe8a9e7155b5fe492cbd78387 | +------------------------------------------------------------------+ mysql> SELECT STATEMENT_DIGEST_TEXT(@stmt); +----------------------------------------------------------+ | STATEMENT_DIGEST_TEXT(@stmt) | +----------------------------------------------------------+ | SELECT * FROM `mytable` WHERE `cola` = ? AND `colb` = ? | +----------------------------------------------------------+
-
STATEMENT_DIGEST_TEXT(
statement
)SQL ステートメントを文字列として指定すると、正規化されたステートメントダイジェストを接続文字セットの文字列として、または引数が
NULL
の場合はNULL
として返します。 その他の説明と例については、関連するSTATEMENT_DIGEST()
関数の説明を参照してください。 -
UNCOMPRESS(
string_to_uncompress
)COMPRESS()
関数で圧縮された文字列を圧縮解除します。 引数が圧縮された値でない場合は、結果がNULL
になります。 この関数を使用するには、MySQL がzlib
などの圧縮ライブラリを使用してコンパイルされている必要があります。 そうでない場合、戻り値は常にNULL
になります。mysql> SELECT UNCOMPRESS(COMPRESS('any string')); -> 'any string' mysql> SELECT UNCOMPRESS('any string'); -> NULL
-
UNCOMPRESSED_LENGTH(
compressed_string
)圧縮された文字列が圧縮される前の長さを返します。
mysql> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30))); -> 30
-
VALIDATE_PASSWORD_STRENGTH(
str
)プレーンテキストパスワードを表す引数を指定すると、この関数はパスワードの強さを示す整数を戻します。 戻り値は、0 (弱) から 100 (強) までの範囲内です。
VALIDATE_PASSWORD_STRENGTH()
によるパスワード評価は、validate_password
コンポーネントによって実行されます。 そのコンポーネントがインストールされていない場合、この関数は常に 0 を返します。validate_password
のインストールの詳細は、セクション6.4.3「パスワード検証コンポーネント」 を参照してください。 パスワードテストに影響するパラメータを調査または構成するには、validate_password
によって実装されるシステム変数を確認または設定します。 セクション6.4.3.2「パスワード検証オプションおよび変数」を参照してください。パスワードは、一段と厳密になったテストの対象であり、戻り値は、次の表に示すように、どのテストに合格したのかを示します。 また、
validate_password.check_user_name
システム変数が有効で、パスワードがユーザー名と一致する場合、他のvalidate_password
システム変数の設定方法に関係なく、VALIDATE_PASSWORD_STRENGTH()
は 0 を返します。パスワードテスト 戻り値 長さ <= 4 0 長さ ≥4 および < validate_password.length
25 ポリシー 1 を満たす ( LOW
)50 ポリシー 2 を満たす ( MEDIUM
)75 ポリシー 3 を満たす ( STRONG
)100