sql >> データベース >  >> RDS >> Sqlserver

SQL Server 2016:常に暗号化

    SQL Server 2016には、AlwaysEncryptedと呼ばれるデータベースセキュリティ機能が含まれています。 SQL ServerODBCドライバーにAlwaysEncryptedのサポートを追加したため、お客様はこの機能を利用できるようになります。

    Always Encryptedは、攻撃を受けやすいポイント(データが使用されているとき)でSQLServerデータを保護します。たとえば、トランザクションおよび計算中。これは、既存のSQL Server暗号化機能とは異なり、操作を実行する前にデータを復号化する必要があります。

    Always Encrypted列を保護する暗号化キーは、アプリケーションマシンに保存されます。これは、SQLServerがAlwaysEncryptedデータを復号化できないことを意味します。 SQL Serverマシンが侵害された場合、攻撃者は暗号化された形式のデータにのみアクセスできます。

    ほとんどのユーザーにとって、Always Encrypted機能は透過的です。つまり、Always Encryptedの動作から隔離されており、機能のメリットを享受するために実行していることを変更する必要はありません。

    アプリケーション側では、暗号化はSQLServerのクライアントインターフェイスを提供するソフトウェアドライバーによって行われます。 LinuxおよびUNIXでは、これはODBCドライバーであり、移動方向に応じてデータを透過的に暗号化または復号化します。 Easysoftドライバーの場合、接続文字列パラメーターを設定することで、AlwaysEncryptedが有効になります。

    人々は自分のデータがクラウドで安全であることにますます懸念を抱いているため、AlwaysEncryptedはクラウドベースの従量制SQLServerであるAzureSQLで利用できるようになります。 EasysoftのAzureSQL用ODBCドライバーは、AlwaysEncryptedもサポートします。

    ウォークスルー:Linuxで常に暗号化された列データを操作する

    EasysoftのSQLServerODBCドライバーを使用すると、AlwaysEncrypted列に保持されているデータを更新およびクエリできます。

    テーブルを作成して暗号化キーを生成する

    これらの手順は、SQLServerマシンで実行されます。

    1. SQL Server Management Studio 2016 CTP3以降では、新しいデータベースを作成します。
    2. 新しいデータベースで、内容を暗号化する1つ以上の列を含むテーブルを作成します。例:
      CREATE TABLE dbo.EncryptedTable
      (
        ID INT IDENTITY(1,1) PRIMARY KEY, LastName NVARCHAR(32), Salary INT NOT NULL
      );
      
    3. データベースを右クリックします。ポップアップメニューから、タスク>列の暗号化を選択します。 。

      常に暗号化されたウィザードが起動します。

    4. 列の選択について ページを開き、テーブルを展開して、暗号化する列を選択します。
    5. 各列の暗号化タイプを選択します。

      決定論的 -常に同じ暗号文に暗号化して、同等のルックアップ、結合、およびgroupbyを実行できるようにします。

      ランダム化 同じプレーンテキストに対して異なる暗号文値を生成します。これはより安全ですが、操作をサポートしていません。

    6. CEK_Auto1(新規)を選択します 各列の暗号化キーとして、これは新しい自動生成キーです。 次へを選択します 。
    7. [マスターキーの構成]ページで、デフォルト設定を受け入れます:
      Field
      列マスターキーを選択 列マスターキーの自動生成
      キーストアプロバイダーを選択 Windows証明書ストア
      列マスターキーを選択 現在のユーザー
    8. 次へを使用する ボタンをクリックして概要に進みます ページ。 完了を選択します 。
    9. ウィザードが完了するのを待ってから、閉じるを選択します 。

    証明書のエクスポート

    証明書をLinuxマシンに転送するには、最初に証明書をWindowsにエクスポートする必要があります。

    1. コマンドプロンプトウィンドウで、 certmgrと入力します 、証明書スナップインを起動します。
    2. 新しいAlwaysEncrypted証明書は、証明書-現在のユーザー>個人>証明書で利用できます。 。
    3. 証明書を右クリックします(これは Always Encrypted Auto Certificate1 )。ポップアップメニューから、[すべてのタスク>エクスポート]を選択します 。

      証明書のエクスポートウィザードが起動します。 次へを選択します 。

    4. はい、秘密鍵をエクスポートするを選択します 。
    5. [ファイル形式のエクスポート]ページでデフォルトを受け入れます。 次へを選択します 。
    6. プロンプトが表示されたらパスワードを入力します。 次へを選択します 。
    7. プロンプトが表示されたら、証明書に名前を付けて保存します。例: CMK_Auto1.pfx
    8. 次へを使用する および終了 ウィザードを完了するためのボタン。

    Linuxへの証明書のインストール

    エクスポートされた証明書を、AlwaysEncrypted列にアクセスするLinuxマシンに転送します。

    1. エクスポートした証明書を〜/ ssl / privateにコピーします SQLServerODBCドライバーをインストールしたLinuxまたはUNIXマシン。

      EasysoftODBCドライバーを介してSQLServerに接続するアプリケーションを実行するユーザーのホームディレクトリです。 〜/ ssl / private は、ドライバーに組み込まれているOpenSSLレイヤーが個人証明書の読み込みを試みる場所です。ディレクトリが存在しない場合は作成します。例:

      $ mkdir -p ~/ssl/private
      $ cd ~/ssl/private
      $ mv /tmp/CMK_Auto1.pfx .
      
    2. SQL Server ODBCドライバーで証明書を使用するには、証明書に含まれているパスフレーズを削除する必要があります。これを行うには、OpenSSLをマシンにインストールする必要があります。 (これはパスフレーズを削除するためにのみ必要です。他の操作では、SQL Server ODBCドライバーは組み込みのOpenSSLレイヤーを使用します。)次のコマンドを使用してパスフレーズを削除します。 後にパスフレーズの入力を求められたら コマンドを入力し、何も入力せずにRETURNを押します。これにより、パスフレーズが何も設定されません。
      $ openssl pkcs12 -in CMK_Auto1.pfx -nodes -out temp.pem
      Enter Import Password: *******
      MAC verified OK
      $ openssl pkcs12 -export -in temp.pem  -out nopassphrase.p12
      Enter Export Password:
      Verifying - Enter Export Password:
      $
      
    3. 証明書をロードするために、SQL Server ODBCドライバーは、暗号化された列に関してSQLServerから受信したメタ情報を使用します。ドライバーがSQLServerから受け取る証明書名は、 my / thumbprintの形式です。 。証明書にはこの命名規則を使用する必要があります。 OpenSSLを使用して証明書の拇印を表示し、myという名前のサブディレクトリで証明書の名前を変更します。
      $ openssl x509 -in temp.pem -fingerprint -noout | tr -d ":"
      SHA1 Fingerprint=EFC1940E545941D6C05C763361403F55A5DEF0E8
      $ mkdir my
      $ cp nopassphrase.p12 my/EFC1940E545941D6C05C763361403F55A5DEF0E8
      $ ln -s my My
      

      テスト中に、SQLServerが証明書にMy / thumbprintという名前を付けることがあることに気付きました。 。上記の例のシンボリックリンクは、この不整合を回避します。

    SQLServerODBCドライバーのインストール

    SQL Server ODBCドライバーは、アプリケーションとSQL Server間の接続レイヤーを提供するだけでなく、AlwaysEncrypted列に格納されているデータの暗号化/復号化も処理します。

    SQLServerODBCドライバーをインストールしてライセンスを取得します。これを行う方法については、SQLServerODBCドライバーのドキュメントを参照してください。アプリケーションが64ビットの場合は、64ビットバージョンのODBCドライバーをダウンロードします。それ以外の場合は、オペレーティングシステムのアーキテクチャに関係なく、32ビットバージョンのドライバを使用してください。

    ODBCデータソースには、SQLServerODBCドライバーがターゲットSQLServerインスタンスに接続できるようにする接続文字列情報が含まれています。私たちのマシンでは、ODBCデータソースは /etc/odbc.iniに保存されています 。このデータソースの抜粋は、AlwaysEncrypted列に関連する設定を示しています。

    [SQLSERVER_2016]
    Driver=Easysoft ODBC-SQL Server SSL # Must use SSL version of driver
    Server=machine\sqlserver_instance
    Database=database_with_always_encrypted_data
    User=user # This can be a Windows or SQL Server login.
    Password=password
    Trusted_Connection=Yes # Set this to No for a SQL Server login
    ColumnEncryption=Enabled # To view Always Encrypted data or to
                             # insert into an Always Encrypted column set to Enabled
    

    「SSL接続がsyscallで失敗しました」というエラーで接続が失敗した場合、システムには「ランダムデバイス」がありません。 エントロピーを参照してください これについて何をすべきかについては、SQLServerODBCドライバーマニュアルの属性を参照してください。

    常に暗号化された列へのデータの挿入

    これで、Always Encrypted列を含む空のテーブルが作成され、SQLServerODBCドライバーがAlwaysEncryptedDataを処理できるようにLinuxクライアントマシンがセットアップされました。次に、テーブルにデータを入力する必要があります。

    データをAlwaysEncrypted列に挿入するには、アプリケーションは次のことを行う必要があります。

    1. パラメータ化された挿入を使用します。つまり、INSERT INTO EncryptedTable VALUES(?、?)を使用します。

      これにより、SQL Server ODBCドライバーは、列の値(暗号化する必要があります)とSQLステートメントテキスト(プレーンテキストのままにする必要があります。AlwaysEncryptedでは、SQL Serverは復号化を行いません)を区別できます。

    2. パラメータのデータ型を明示的に記述します。

      SQL Serverは、 SQLDescribeParamを使用してデータ型を検出するためのSQLServerODBCドライバーのAlwaysEncrypted列に関する必要な情報を提供しません。 。

    これを行う方法を示すPerlサンプルを次に示します。

    # Use Perl DBI / DBD:ODBC to insert data into Always Encrypted columns.
    use strict;
    use warnings;
    use DBI;
    
    my $data_source = q/dbi:ODBC:SQLSERVER_2016/;
    
    my $h = DBI->connect($data_source)
        or die "Can't connect to $data_source: $DBI::errstr";
    $h->{RaiseError} = 1;
    
    my $s = $h->prepare(q/insert into EncryptedTable values(?,?)/);
    my $lastname='Smith';
    my $salary=25000;
    
    # Set the data type of the target columns.
    # Cannot use SQLDescribeParam with Always Encrypted columns.
    $s->bind_param(1, $lastname, DBI::SQL_WVARCHAR);
    $s->bind_param(2, $salary, DBI::SQL_INTEGER);
    $s->execute($lastname,$salary);
    $h->disconnect;
    

    これを行う方法を示すCサンプルを次に示します。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sql.h>
    #include <sqlucode.h>
    #include <sqlext.h>
    #include <string.h>
    #include <wchar.h>
    
    #define LASTNAME_LEN 6
    
    SQLHENV   henv  = SQL_NULL_HENV;   // Environment
    SQLHDBC   hdbc  = SQL_NULL_HDBC;   // Connection handle
    SQLHSTMT  hstmt = SQL_NULL_HSTMT;  // Statement handle
    SQLRETURN retcode;
    
    SQLCHAR strLastName[]="Jones";
    SQLINTEGER pSalary=25000;
    
    SQLLEN lenLastName=0;
    
    int main () {
        // Allocate environment
        retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    
        // Set ODBC Version
        retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
                                (SQLPOINTER*)SQL_OV_ODBC3, 0);
    
        // Allocate Connection
        retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    
        // Connect to DSN
        retcode = SQLConnect(hdbc, (SQLCHAR*) "MyDSN", SQL_NTS,
                             (SQLCHAR*) NULL, 0, NULL, 0);
    
        // Allocate Statement Handle
        retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    
        // Bind Parameters to all fields
        retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
                                   SQL_WVARCHAR, LASTNAME_LEN, 0, strLastName, LASTNAME_LEN,
                        &lenLastName);
    
        retcode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG,
                                   SQL_INTEGER, 0, 0, &pSalary, 0, NULL);
    
        retcode = SQLPrepare(hstmt, (SQLCHAR*)"INSERT INTO [dbo].[EncryptedTable] ([LastName],[Salary]) VALUES (?,?)",
                                   SQL_NTS);
    
        lenLastName=strlen((char*)strLastName);
    
        retcode = SQLExecute(hstmt);
    
    exit:
    
        printf ("\nComplete.\n");
    
        // Free handles
        // Statement
    
        if (hstmt != SQL_NULL_HSTMT)
            SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    
        // Connection
        if (hdbc != SQL_NULL_HDBC) {
            SQLDisconnect(hdbc);
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
        }
    
        // Environment
        if (henv != SQL_NULL_HENV)
            SQLFreeHandle(SQL_HANDLE_ENV, henv);
    
        return 0;
    }
    
    	
    

    これで列にデータが入力されたので、isqlを使用してデータを取得できます。

    $ /usr/local/easysoft/unixODBC/bin/isql.sh -v SQLSERVER_2016
    SQL> select * from EncryptedTable
    +----+----------+------------+
    | ID | LastName | Salary     |
    +----+----------+------------+
    | 1  | Smith    | 25000      |
    +----+----------+------------+
    

    データソースでドライバーロギングをオンにしました。ドライバーログからの次の抜粋は、次のことを示しています。

    1. SQL Serverは、列に関するメタ情報として証明書名を提供します。
    2. 列データはSQLServer側で暗号化されるため、転送中も暗号化されたままになります。クライアント上のSQLServerODBCドライバーは、列の値を復号化してから、プレーンテキストでアプリケーションに返します。
    1.
    M.S.S.Q.L._.C.E.
    R.T.I.F.I.C.A.T.
    E._.S.T.O.R.E.7.
    C.u.r.r.e.n.t.U.
    s.e.r./.m.y./.7.
    2.8.8.1.8.C.5.F.
    B.2.C.6.E.B.F.C.
    2.5.3.D.B.C.1.2.
    2.8.5.B.6.A.D.9.
    4.8.9.0.8.3.E..R
    .S.A._.O.A.E.P..
    .....8.I.D......
    ...........@....
    ......L.a.s.t.N.
    a.m.e........Q..
    .....8....S.a.l.
    a.r.y...........
    
    2.
    PKTDUMP:         Encrypted column
    .);...'A..zs..I.
    .N.]r..p.-..$...
    .S;.].km6.....3c
    r.OhR..j*.....fj
    ....ARN{V.F.....
    
    DETAIL:  EVP_DecryptInit returns 1
    DETAIL:  EVP_DecryptUpdate returns 1, 0
    DETAIL:  EVP_DecryptUpdate returns 1, 16
    DETAIL:  EVP_DecryptFinal returns 1, 0
    PKTDUMP:         data
    
    S.m.i.t.h.
    

    関連項目

    • LinuxのAzureKeyVaultで保護されたデータの使用
    • Linuxのカスタムキーストアで保護されたデータの使用

    1. 非常に大規模なデータベースをアンロードする

    2. SQLServerで中央値を計算する関数

    3. Access2016で空のデータベースを作成する方法

    4. Linux用の12MySQL/MariaDBセキュリティのベストプラクティス