【極限の知見】AutoCAD VBAにおけるデジタル署名の完全制御:図面改ざんを許さない「Gatekeeper」アーキテクチャの実装
インフラ設計、防衛、あるいは高度な機密を要するプラント設計において、DWGファイルは単なる「図面データ」ではない。それは、設計者の責任と法的整合性を担保する「証跡」である。
多くの自動化エンジニアは、図面の「描画」や「レイアウトの自動化」に終始する。しかし、真のプロフェッショナルが向き合うべきは、そのデータの「完全性(Integrity)」だ。デジタル署名が付与された図面が、意図せぬ改ざんを受けたまま保存され、あるいは署名が失効した状態で運用されることは、システム全体の信頼性を崩壊させる致命的な欠陥となる。
本稿では、AutoCAD VBAを単なるスクリプト言語としてではなく、Windows OSのセキュリティレイヤーと密接に連携する「ゲートキーパー(門番)」として機能させるための、極限の制御手法を解説する。
1. 概念設計:なぜ標準の `SaveAs` では不十分なのか
AutoCADの標準的なオブジェクトモデル(`AcadDocument`)は、図面の幾何学的情報を操作することに特化しており、OSレベルのファイル属性や、暗号学的な署名の有効性検証(Certificate Revocation List: CRL のチェック等)を直接的にハンドリングするプロパティを十分に備えていない。
シニアエンジニアが構築すべきは、以下の3層構造を持つアーキテクチャである。
1. Integrity Check Layer (検証層): Windows ShellまたはWMIを介し、ファイル属性としてのデジタル署名の有無と有効性を判定する。
2. Workflow Control Layer (制御層): 検証結果に基づき、AutoCADの標準的な `Save` メソッドをラップ(包摂)し、不正な状態での保存を物理的に阻止する。
3. Resource Management Layer (管理層): 大規模なDWGを扱う際のメモリリークを防ぐため、COMオブジェクトのライフサイクルを厳格に管理する。
2. 実装:デジタル署名の検証と保存制御
ここでは、Windowsのシェル機能を利用してファイルの署名状態を判定し、署名が無効な場合に保存を拒否する、堅牢なプロトタイプを提示する。
署名検証エンジンとセキュア・セーブの実装
Option Explicit
' --- Windows API 定義 ---
' ファイルの属性確認や高度な操作が必要な場合に備え、宣言しておく
Private Declare PtrSafe Function GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" (ByVal lpFileName As String) As Long
Private Const FILE_ATTRIBUTE_READONLY As Long = &H1
''' <summary>
''' 図面のデジタル署名の有効性を検証する。
''' 本来は、より高度な証明書検証(CRLチェック)を伴う外部DLLとの連携が望ましいが、
''' ここではShell.Applicationを用いたプロパティ検証のロジックを示す。
''' </summary>
''' <param name="filePath">検証対象のDWGフルパス</param>
''' <returns>署名が有効であればTrue</returns>
Private Function IsDigitalSignatureValid(ByVal filePath As String) As Boolean
Dim objShell As Object
Dim objFolder As Object
Dim objFile As Object
Dim strName As String
Dim isSigned As Boolean
On Error GoTo ErrorHandler
' ファイルの存在確認
If Dir(filePath) = "" Then
Err.Raise vbObjectError + 513, "SecurityModule", "Target file not found."
End If
Set objShell = CreateObject("Shell.Application")
' ファイルパスからフォルダとファイル名を分離
Dim lastSlash As Integer
lastSlash = InStrRev(filePath, "\")
strName = Mid(filePath, lastSlash + 1)
' 親フォルダのオブジェクトを取得
Set objFolder = objShell.Namespace(Left(filePath, lastSlash))
' ファイルのオブジェクトを取得
Set objFile = objFolder.ParseName(strName)
' --- 署名検証ロジック ---
' Windowsのプロパティ(Digital Signature)をスキャンする。
' 注意: 環境によりプロパティのインデックスは異なるため、
' 本番環境ではプロパティ名を直接ループで検索する実装が必須。
isSigned = False
Dim i As Integer
For i = 0 To 300 ' プロパティの範囲を走査
Dim propName As String
propName = objFolder.GetDetailsOf(objFolder.Items, i)
' "Digital Signature" プロパティを特定(言語依存に注意)
If InStr(1, propName, "署名", vbTextCompare) > 0 Or _
InStr(1, propName, "Signature", vbTextCompare) > 0 Then
Dim propValue As String
propValue = objFolder.GetDetailsOf(objFile, i)
' 値が存在し、かつ「無効」などのキーワードが含まれていないか検証
If propValue <> "" And InStr(1, propValue, "Invalid", vbTextCompare) = 0 Then
isSigned = True
Exit For
End If
End If
Next i
IsDigitalSignatureValid = isSigned
GoTo CleanUp
ErrorHandler:
Debug.Print "Error in IsDigitalSignatureValid: " & Err.Description
IsDigitalSignatureValid = False
CleanUp:
' メモリ管理の極致:COMオブジェクトの明示的な解放
Set objFile = Nothing
Set objFolder = Nothing
Set objShell = Nothing
End Function
''' <summary>
''' 署名を検証した上で保存を実行する「Gatekeeper」メソッド。
''' </summary>
''' <param name="targetDoc">操作対象のAcadDocument</param>
Public Sub SecureSave(ByRef targetDoc As Object)
Dim filePath As String
filePath = targetDoc.FullName
' 1. 署名検証の実行
If IsDigitalSignatureValid(filePath) Then
' 2. 検証成功時のみ保存を許可
On Error Resume Next
targetDoc.Save
If Err.Number <> 0 Then
MsgBox "保存中にエラーが発生しました: " & Err.Description, vbCritical, "Save Error"
Else
Debug.Print "Secure Save Successful: " & filePath
End If
On Error GoTo 0
Else
' 3. 検証失敗時の強制介入
MsgBox "【警告】図面のデジタル署名が無効、または改ざんの可能性があります。" & vbCrLf & _
"この図面を保存することは、セキュリティポリシーにより禁止されています。", _
vbCritical, "Security Violation"
' 必要に応じて、図面を読み取り専用モードへ強制移行させるロジックをここに挿入
End If
End Sub
3. 伝説的アーキテクトの視点:メモリとライフサイクル
大規模なBIMプロジェクトや、数千枚の図面をバッチ処理するシステムにおいて、VBAの最大の敵は「メモリの断片化」と「COMオブジェクトのゾンビ化」である。
オブジェクトの解放(Explicit Release)
上記のコード内で `Set objFile = Nothing` と記述しているのは、単なる作法ではない。AutoCAD VBAにおいて、`Shell.Application` のような外部COMオブジェクトを適切に解放しない場合、AutoCADのプロセスが終了しても、`dllhost.exe`(COM+ System Application)がメモリ上に残り続け、システム全体のパフォーマンスを段階的に蝕んでいく。
パフォーマンスの最適化
`IsDigitalSignatureValid` 関数内で `For i = 0 To 300` とループを回している点は、一見非効率に見えるかもしれない。しかし、WindowsのプロパティインデックスはOSのバージョンやインストールされているシェル拡張によって動的に変化する。インデックスをハードコーディングすることは、レガシー環境の保守において「死」を意味する。名前による検索(Name-based lookup)こそが、長期運用に耐えうる唯一の解である。
4. システム間連携への展開
このロジックを、単体のAutoCAD内蔵マクロとして完結させてはならない。真に高度なシステム管理者は、これを「外部セキュリティモジュール」として設計する。
1. VB.NET / C# による検証DLLの作成:
Windows APIの `WinVerifyTrust` 関数を直接呼び出し、証明書のチェーン、失効状態(CRL/OCSP)、およびハッシュ値の整合性を極めて精密に検証するコンポーネントを作成する。
2. COM Interop による呼び出し:
作成したDLLをCOM参照可能にし、AutoCAD VBAから `CreateObject` で呼び出す。これにより、VBAの柔軟性と、.NETの堅牢な暗号化ライブラリを融合させることができる。
結論
AutoCAD VBAを用いた自動化において、図面の「描画」は表面的な作業に過ぎない。プロフェッショナルとしての真価は、そのデータが「いつ、誰によって、どのような正当性を持って生成されたか」をシステム的に保証する仕組みを構築できるかどうかにかかっている。
デジタル署名の制御を実装することは、単なるエラーチェックではない。それは、エンジニアリングの成果物に対する「信頼のアーキテクチャ」を構築することと同義である。
