Always Encrypted による暗号

適用対象:SQL ServerAzure SQL データベースAzure SQL Managed Instance

この記事では、SQL ServerおよびAzure SQL Databaseの Always Encrypted 機能で使用される暗号化マテリアルを派生させる暗号化アルゴリズムとメカニズムについて説明します。 これらのアルゴリズムは、Always Encrypted のすべてのエディションとバージョンに適用されます。セキュリティで保護されたエンクレーブの有無にかかわらず、Always Encrypted では同じ暗号化アルゴリズムが使用されます。

キー、キー ストア、およびキー暗号化アルゴリズム

Always Encrypted では、列マスター キーと列暗号化キーという 2 種類のキーを使用します。

列マスター キー (CMK) は、常にクライアントによって制御され、外部キー ストアに格納されているキー暗号化キー (たとえば、他のキーの暗号化に使用されるキー) です。 Always Encrypted が有効なクライアント ドライバーは CMK ストア プロバイダーを介してキー ストアと対話します。このプロバイダーはドライバー ライブラリの一部 (Microsoft/system プロバイダー) またはクライアント アプリケーションの一部 (カスタム プロバイダー) である場合があります。 現在、クライアント ドライバー ライブラリには、Windows 証明書ストアおよびハードウェア セキュリティ モジュール (HSM) の Microsoft キー ストア プロバイダーが含まれています。 プロバイダーの現在の一覧については、「 CREATE COLUMN MASTER KEY (Transact-SQL)」を参照してください。 アプリケーション開発者は、任意のストアのカスタム プロバイダーを提供できます。

列暗号化キー (CEK) は、CMK によって保護されているコンテンツ暗号化キー (たとえば、データを保護するために使用されるキー) です。

すべての Microsoft CMK ストア プロバイダーでは、RSA-OAEP (RSA with Optimal Asymmetric Encryption Padding) を使用して CEK が暗号化されます。 Microsoft Cryptography API をサポートするキー ストア プロバイダー: .NET Framework の Next Generation (CNG) (SqlColumnEncryptionCngProvider クラス) では、RFC 8017 のセクション A.2.1 で指定されている既定のパラメーターが使用されます。 これらの既定パラメーターでは、SHA-1 のハッシュ関数と、SHA-1 による MGF1 のマスク生成関数が使用されます。 他のすべてのキー ストア プロバイダーでは、SHA-256 が使用されます。

Always Encrypted では内部的に、FIPS 140-2 検証済み暗号化モジュールが使用されます。

データ暗号化アルゴリズム

Always Encrypted では AEAD_AES_256_CBC_HMAC_SHA_256 アルゴリズムを使用して、データベース内のデータを暗号化します。 AEAD は、関連するデータを使用した認証された暗号化の略です。 HMAC は、ハッシュ ベースのメッセージ認証コードを表します。 MAC は、メッセージ認証コードの略です。

AEAD_AES_256_CBC_HMAC_SHA_256IETF 仕様のドラフトから派生しています。 このアルゴリズムでは、Encrypt-then-MAC 手法に従って、関連データで認証済み暗号化スキームを使用します。 つまり、プレーンテキストが最初に暗号化され、その結果として生成される暗号化テキストに基づいて MAC が生成されます。

パターンを非表示にするために、 AEAD_AES_256_CBC_HMAC_SHA_256 では暗号化ブロック チェーン (CBC) という操作モードを使用します。この場合、初期値は初期化ベクター (IV) という名前のシステムに渡されます。 CBC モードの詳細については、 米国国立標準技術研究所 (NIST) を参照してください。

AEAD_AES_256_CBC_HMAC_SHA_256 は、以下の手順を使用して指定されたプレーンテキストの暗号化テキストの値を計算します。

手順 1: 初期化ベクター (IV) の生成

Always Encrypted では、以下の 2 種類の AEAD_AES_256_CBC_HMAC_SHA_256がサポートされています。

  • ランダム化

  • 決定論的

ランダムな暗号化の場合、IV はランダムに生成されます。 その結果、同じプレーンテキストが暗号化されるたびに、別の暗号化テキストが生成され、情報の漏えいを防ぐことができます。

When using randomized encryption: IV = Generate cryptographically random 128bits  

確定的な暗号化の場合、IV はランダムに生成されるのではなく、次のアルゴリズムを使用してプレーンテキスト値から派生します。

When using deterministic encryption: IV = HMAC-SHA-256( iv_key, cell_data ) truncated to 128 bits.  

iv_key は以下の方法で CEK から派生します。

iv_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell IV key" + algorithm + CEK_length)  

IV で必要な場合、1 つのデータ ブロックに収まるように HMAC 値の切り捨てが行われます。 その結果、決定的な暗号化では常に指定されたプレーンテキスト値に対して同じ暗号化テキストが生成されます。これにより、2 つのプレーンテキスト値のそれぞれ対応する暗号化テキスト値を比較して、プレーンテキスト値が同じであるかどうかを推定できます。 この制限された情報の公開により、データベース システムは暗号化された列値の等価比較をサポートできます。

決定的な暗号化は、定義済みの IV 値を使用するなどして、パターンを非表示にする場合や代替との比較を行う場合により効果的です。

手順 2: AES_256_CBC暗号テキストを計算する

Always Encrypted の AEAD_AES_256_CBC_HMAC_SHA_256 アルゴリズムでは、手順 1 で IV を計算した後、 AES_256_CBC 暗号テキストが生成されます。

aes_256_cbc_ciphertext = AES-CBC-256(enc_key, IV, cell_data) with PKCS7 padding.  

暗号化キー (enc_key) は、次のように列暗号化キー (CEK) から派生します。

enc_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell encryption key" + algorithm + CEK_length )  

手順 3: MAC の計算

Always Encrypted の AEAD_AES_256_CBC_HMAC_SHA_256 アルゴリズムの場合、MAC (メッセージ認証コード) は、バージョン バイト、IV (手順 1) とAES_256_CBC暗号テキスト (手順 2 から) から、列暗号化キー (CEK) から派生した mac_key を使用して計算されます。

MAC = HMAC-SHA-256(mac_key, versionbyte + IV + Ciphertext + versionbyte_length)  

場所:

versionbyte = 0x01 and versionbyte_length = 1
mac_key = HMAC-SHA-256(CEK, "Microsoft SQL Server cell MAC key" + algorithm + CEK_length)  

手順 4: 連結

Always Encrypted の AEAD_AES_256_CBC_HMAC_SHA_256 アルゴリズムの場合、最終的な暗号化値は、アルゴリズム のバージョン バイト、MAC (手順 3 から)、IV (手順 1 から)、およびAES_256_CBC暗号テキスト (手順 2 から) を連結することによって生成されます。

aead_aes_256_cbc_hmac_sha_256 = versionbyte + MAC + IV + aes_256_cbc_ciphertext  

暗号文の長さ

AEAD_AES_256_CBC_HMAC_SHA_256 暗号化テキストの各コンポーネントの長さ (バイト単位) は次のとおりです。

コンポーネント サイズ (バイト)
versionbyte 1
MAC 32
IV 16
aes_256_cbc_ciphertext (FLOOR(DATALENGTH(cell_data) / block_size) + 1) * block_sizeでは、 block_size は 16 バイト、 cell_data はプレーンテキスト値です。 aes_256_cbc_ciphertextの最小サイズは 1 ブロック (16 バイト) です。

指定されたプレーンテキスト値を暗号化した場合の暗号化テキストの長さは、以下の式を使用して計算できます。

1 + 32 + 16 + (FLOOR(DATALENGTH(cell_data)/16) + 1) * 16  

次に例を示します。

  • 4 バイト長の int プレーンテキスト値は、暗号化後に 65 バイト長のバイナリ値になります。

  • 2,000 バイトの長い nchar(1000) プレーンテキスト値は、暗号化後に 2,065 バイトの長いバイナリ値になります。

暗号テキストの長さは、ソース データ型によって異なります。 固定長型の場合、結果は定数になります。可変長型 (charncharvarcharnvarcharbinaryvarbinary) の場合は、上記の数式を使用します。 N/A とマークされた型は、Always Encrypted では暗号化できません。 次の表には、データ型と各型の暗号化テキストの長さの完全な一覧が含まれています。

データの種類 暗号テキストの長さ [バイト]
bigint 65
[バイナリ] 異なります。 上の式を使用します。
bit 65
char 異なります。 上の式を使用します。
date 65
datetime 65
datetime2 65
datetimeoffset 65
10進数 81
float 65
geography 該当なし (サポートされていません)
geometry 該当なし (サポートされていません)
hierarchyid 該当なし (サポートされていません)
image 該当なし (サポートされていません)
int 65
money 65
nchar 異なります。 上の式を使用します。
ntext 該当なし (サポートされていません)
numeric 81
nvarchar 異なります。 上の式を使用します。
実数 65
smalldatetime 65
smallint 65
smallmoney 65
sql_variant 該当なし (サポートされていません)
sysname 該当なし (サポートされていません)
text 該当なし (サポートされていません)
time 65
timestamp

(rowversion)
該当なし (サポートされていません)
tinyint 65
uniqueidentifier 81
varbinary 異なります。 上の式を使用します。
varchar 異なります。 上の式を使用します。
xml 該当なし (サポートされていません)

.NET リファレンス

この記事で説明するアルゴリズムの詳細については、「.NET リファレンス」のSqlAeadAes256CbcHmac256Algorithm.csSqlColumnEncryptionCertificateStoreProvider.cs、およびSqlColumnEncryptionCngProvider.csファイルを参照してください