【テクニカル・上級編】QueryDefのSQLを「暗号化」して保存する:ソースコード保護の最終防衛ライン – Access VBA解析バイブル

スポンサーリンク

Access VBAを掌握する極限の知見:QueryDefの「SQL難読化」による最終防衛ライン

AccessのQueryDefオブジェクトを覗けば、そこにはビジネスロジックのすべてが記述されたSQLが丸裸で転がっている。開発者が去り、保守担当がコードを追う際、最も脆弱なのは「バックエンドのロジックが誰の目にも明らかである」という事実だ。

コードの難読化(Obsucation)は、単なる気休めではない。これはリバースエンジニアリングに対する「心理的障壁」を築き、安易な改ざんを許さないためのアーキテクトとしての矜持である。今回は、QueryDefに保存されたSQLを暗号化し、実行時にメモリ上で復号・実行する「最終防衛ライン」の構築手法を伝授する。

—

1. なぜQueryDefを暗号化するのか

AccessにおいてQueryDefは、データベースの実行計画を最適化する重要なオブジェクトである。しかし、`.SQL`プロパティはプレーンテキストであり、`CurrentDb.QueryDefs(“q_Sensitive”)`にアクセスするだけで、すべてのロジックが露呈する。

我々が目指すのは、「保存時は無意味な文字列」として保持し、「実行時のみメモリ上でSQLに変換する」というプロセスだ。これには以下の技術的要諦が必要となる。

  • 永続化の分離: DBファイル内には暗号化文字列のみを置く。
  • メモリ・ライフサイクル管理: 復号されたSQLは変数としてメモリに保持し、実行後は即座に消去する。
  • APIによる秘匿: 復号ロジックを標準モジュールに隠蔽し、外部からの直接参照を制限する。

—

2. 実装の核心:SQL難読化エンジン

ここでは、単純なXOR暗号ではなく、BASE64と組み合わせた簡易的な置換アルゴリズムを用いてSQLを保護する。本番環境では、ここにAES等の強力な暗号化APIを組み込むのが定石だ。

難読化・復号モジュール (modSecurity)

Option Explicit

‘ 復号用キー(ハードコードせず、環境変数や別ファイルから読み込むのが理想)
Private Const CRYPTO_KEY As String = “ARCHITECT_SECRET_2024″

”’

”’ QueryDefのSQLを復号して一時的に実行するメソッド
”’

Public Sub ExecuteEncryptedQuery(ByVal queryName As String)
Dim qdf As DAO.QueryDef
Dim db As DAO.Database
Dim encryptedSQL As String
Dim decryptedSQL As String

Set db = CurrentDb
Set qdf = db.QueryDefs(queryName)

‘ 暗号化されたSQLを読み込み
encryptedSQL = qdf.SQL

‘ 復号処理(メモリ上でのみ展開)
decryptedSQL = DecryptSQL(encryptedSQL)

‘ 実行計画の生成と実行
‘ 注:本来はここで動的SQLとしてQueryDefを再定義するか、
‘ RunSQLあるいはDAO.Database.Executeを使用する
db.Execute decryptedSQL, dbFailOnError

‘ オブジェクトの解放とメモリのクリーンアップ
Set qdf = Nothing
Set db = Nothing
decryptedSQL = vbNullString ‘ メモリを確実に解放
End Sub

‘ 簡易的な復号ロジック(実際にはCryptoAPI等を使用すること)
Private Function DecryptSQL(ByVal inputData As String) As String
‘ ここに復号アルゴリズムを実装
‘ 難読化を施した文字列から元のSQLを生成する
‘ 戻り値はクリーンなSQL文字列
End Function

—

3. シニアエンジニアが意識すべき「メモリとパフォーマンス」

この手法を用いる際、最も注意すべきは「復号されたSQLがメモリ上にスタックされる時間」である。

1. 文字列の破棄: VBAの文字列変数は、スコープを抜ければ自動的に解放されるが、巨大なSQLを扱う場合は`str = vbNullString`で明示的にメモリ領域を解放する癖をつけよ。
2. DAOオブジェクトのライフサイクル: `CurrentDb`を安易に使い回すな。DAOのDatabaseオブジェクトをキャッシュし、不要になった瞬間に`Set db = Nothing`を叩く。これがメモリリークを防ぐ唯一の道である。
3. パフォーマンスへの影響: 復号コストは、ミリ秒単位で見れば無視できるが、ループ内で何度も呼び出すのは愚策だ。必要な時に一度だけ復号し、メモリにキャッシュする設計を心がけよ。

—

4. 運用の極意:防衛ラインを突破させないために

この難読化は「完璧なセキュリティ」ではない。しかし、Accessというオープンな環境において、「中身を覗く手間を100倍にする」ことは、ビジネス上のリスクヘッジとして極めて有効だ。

  • プロシージャのコンパイル: MDE/ACCDE形式での配布を前提とする。これにより、ソースコードそのものへのアクセス権を物理的に遮断する。
  • 動的生成の活用: QueryDefそのものをDBに保存せず、VBAコード内に隠蔽した暗号化文字列から、実行時のみメモリ上で`CreateQueryDef`を使用して一時クエリを作成・実行し、終了時に`DeleteQueryDef`する。これが「痕跡を残さない」究極の運用だ。

—

総括:技術を支配せよ

Accessは、しばしば「おもちゃ」と揶揄される。だが、その内部構造を理解し、メモリ管理からセキュリティ設計までを制御下に置く者にとって、これほど強力で高速なプロトタイピング環境は存在しない。

QueryDefのSQLを隠蔽することは、単なるコード保護ではない。それは、君が書いた「ロジック」という名の資産を、泥棒や無理解な改ざん者から守り抜くための、エンジニアとしての最後の砦である。

さあ、今すぐ君のシステムにこの防衛線を構築せよ。アーキテクチャに妥協は許されない。それが、プロフェッショナルというものだ。

タイトルとURLをコピーしました