web-dev-qa-db-ja.com

TRUSTWORTHYをオンにせずに.NetアセンブリをSQL CLRに追加

Solomon Rutzkyの投稿で提供されているガイダンスを使用して「System.Messaging.dll」を追加しようとしています 権限UNSAFEまたは非対称キーを使用したEXTERNAL_ACCESSを使用したアセンブリの展開 ですが、最初のハードルで失敗します。

スクリプトの最初の部分は、アセンブリから証明書を作成することです。

CREATE CERTIFICATE [MS.NETcer] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll';
GO

ただし、これを実行するとエラーが発生します。

Msg 15208, Level 16, State 1, Line 1
The certificate, asymmetric key, or private key file does not exist or has invalid format.

コマンドの実行に使用しているアカウントには、「sysadmin」サーバーの役割があります。これはSQL Server 2008インスタンス上にあります。

なぜこれが失敗するのかについて誰かが何かアイデアを持っていますか?

---------- Update 1 -----------

私はソロモンのアドバイスを取り入れ、スクリプトを次のように修正しました。

CREATE ASYMMETRIC KEY [Key.System.Messaging] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll';
GO

CREATE LOGIN [CLR.Login.System.Messaging] FROM ASYMMETRIC KEY [Key.System.Messaging];
GO

GRANT UNSAFE Assembly TO [CLR.Login.System.Messaging];
GO

これまでのところすべて良い。次に、CREATE Assemblyコマンドを実行して、アセンブリをSQLCLRに追加します。

CREATE Assembly [System.Messaging]
FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'
WITH PERMISSION_SET = UNSAFE
GO

しかし、これはエラーで失敗します。

アセンブリ 'System.Windows.Forms'がPERMISSION_SET = UNSAFEに対して承認されていないため、アセンブリ 'System.Messaging'のアセンブリの作成に失敗しました。アセンブリは、次のいずれかに該当する場合に承認されます。データベース所有者(DBO)にUNSAFEアセンブリ権限があり、データベースにTRUSTWORTHYデータベースプロパティがオンになっている。または、アセンブリは、UNSAFEアセンブリ権限を持つ対応するログインを持つ証明書または非対称キーで署名されています。

「System.Windows.Forms」の非対称キーを作成してみました

CREATE ASYMMETRIC KEY [Key.System.Windows.Forms] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll';
GO

しかし、これは失敗します。

メッセージ15468、レベル16、状態1、行1非対称キーの生成中にエラーが発生しました。

だから私は試しました。

CREATE CERTIFICATE [Cer.System.Windows.Forms] FROM EXECUTABLE FILE = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll';
GO

そしてこれは失敗します;

メッセージ15208、レベル16、状態1、行1証明書、非対称キー、または秘密キーファイルが存在しないか、形式が無効です。

だから今私は再び立ち往生していて、TRUSTWORTHYデータベースプロパティを有効にする必要なしにSQL CLRでSystem.Messaging.dllを使用することが可能かどうか疑問に思っています(また、なぜ地上でSystem.Messaging.dllを実行するのか) System.Windows.Forms.dllへの依存関係が必要です!)

感謝して受け取った考え

4
user1443986

SQL Server 2017 CU12で同じコマンドを実行すると、同じ15208エラーが発生しました。それから私は以下を試しました:

CREATE ASYMMETRIC KEY [MS.NETsnk] FROM EXECUTABLE FILE =
'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll';

そしてそれは成功しました! (名前の「snk」は技術的には証明書ではないため、「Strong Name Key」用です)。

私が知ることができることから、CLR 2.0の.NET Frameworkライブラリのほとんど(つまり、.NET Frameworkバージョン2.0、3.0、および3.5)はnot証明書で署名されています。 mscor * .dllファイルのほとんどではなく、1つSystem。*。dllSystem.EnterpriseServices.Thunk.dll—証明書で署名されています。残りは厳密な名前のキーのみを使用しています/厳密な名前が付けられています。

CLR 4.0(つまり.NET Frameworkバージョン4. *)以降、all .NET Frameworkライブラリは証明書で署名されているようです。

したがって、より正確なルールは次のとおりです。

  • CLR 4.0(SQL Serverバージョン2012以降)の場合、CREATE CERTIFICATEを使用します
  • CLR 2.0(つまり、SQL Serverバージョン2005、2008、および2008 R2)の場合、CREATE ASYMMETRIC KEYを使用します。ただし、これを実行すると15208エラーが発生する場合( "証明書、非対称鍵、または秘密鍵ファイルが無効であるか、存在しないか、アクセス権がない場合)、次に切り替えます。 CREATE CERTIFICATEへ。

    このグループがASYMMETRIC KEYで始まる理由は、veryCERTIFICATEを使用する必要がある可能性が低いためです。 SQL Server 2019(CLR 4.0を使用)とSQL Server 2005(CLR 2.0を使用)の両方にSystem.EnterpriseServices.Thunk.dllをインポートしようとしましたまた、SQL Server 2005のmsg 6507とSQL Server 2019のmsg 6544の両方で失敗しました。「不正な形式のアセンブリ」(混合モード/非純粋なMSILアセンブリであることを意味します)を報告しています。また、SQL Server 2005でmscor *ライブラリの一部をインポートしようとしましたが、それらは同じ6507エラーで失敗しました(コアライブラリが管理されていないことは当然のことです)それらのコード)。したがって、CLR 2.0の.NET FrameworkライブラリをインポートするときにCREATE CERTIFICATEを使用する可能性さえない可能性が高いです。

System.Messagingにはいくつかの依存関係があるようです:

  • system.configuration.install
  • system.runtime.serialization.formatters.soap
  • system.windows.forms
  • system.drawing
  • アクセシビリティ
  • system.directoryservices

CREATE Assemblyのソースはファイルであり、VARBINARYリテラル/ 16進バイトではないため、これらの依存関係は自動的にインポートされます。この依存関係の自動インポートを実行している間、操作はsystem.windows.formsで失敗し、UNSAFEが許可されていないと主張します。ただし、非対称キーはすでに作成されており、他の依存関係は正しくインポートされています。

さらなる調査の結果、system.windows.formsに使用されている厳密な名前のキーが、他のライブラリに使用されているものと異なることがわかりました。正常にインポートされたライブラリにはb03f5f7f11d50a3aの公開鍵トークンがあり、失敗したライブラリにはb77a5c561934e089の公開鍵トークンがあります。 O.P.が発見したように、system.windows.formsからの非対称キーの作成は機能しません。ライブラリから証明書を作成することもできませんが、説明は簡単です。ライブラリは証明書で署名されていません;-)。ただし、非対称キーの作成に関する問題は、おそらくhowsystem.windows.formsが署名されているためです。 ECMA署名を使用します。これは、公開鍵の代わりに標準のプレースホルダー値をライブラリーに配置しますが、このプレースホルダー値は有効な公開鍵ではありません。詳細については、以下を参照してください。

現在、私はしませんthink公開鍵ファイルを取得して非対称鍵を作成できます。セキュリティ上の問題ではなく、「公開」キーである必要があるため、ファイルシステムのどこかにある可能性がありますが、現時点ではどこにあるのかわかりません。

そのため、当面は、2017年より前のバージョンからSQL Server 2017(またはそれ以降)にアップグレードされたデータベース内の既存の署名されていないアセンブリが機能するのと同じ基本的な手法を使用してこれを回避できるはずです:インプレースで組み立てます。もちろん、SQL Serverにアセンブリを取得するには、一時的にTRUSTWORTHYを有効にする必要がありますが、単一のコマンド。次に、アセンブリがインポートされると、次のことができます。

  1. 証明書を作成する
  2. それで議会に署名する
  3. 証明書(公開キーと秘密キーの両方)をファイルにバックアップします(公開キーのVARBINARYを取得できません [〜#〜] certencoded [〜#〜] としてSQL Server 2012で導入されました)
  4. 秘密鍵を証明書から削除して、他の署名に使用できないようにする
  5. 同じ証明書を[master]に作成しますが、公開鍵のみを使用します(署名には使用できません)
  6. その証明書からログインを作成する
  7. その署名ベースのログインにUNSAFE Assembly権限を付与します

上記の手順に基づいて、次の方法を試してください。以下のサンプルコードは、非対称キー、関連する署名ベースのログイン、およびSystem.MessagingGRANTを作成する手順がすでに完成しています。

--CREATE DATABASE [Test];
--ALTER DATABASE [Test] SET RECOVERY SIMPLE;
GO

USE [Test];
ALTER DATABASE [Test] SET TRUSTWORTHY ON;

CREATE Assembly [System.Messaging]
FROM 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'
WITH PERMISSION_SET = UNSAFE;

ALTER DATABASE [Test] SET TRUSTWORTHY OFF;

SELECT * FROM sys.assemblies;
-- System.Messaging: publickeytoken=b03f5f7f11d50a3a
-- System.Windows.Forms: publickeytoken=b77a5c561934e089

CREATE CERTIFICATE [WinForms]
  ENCRYPTION BY PASSWORD = 'Use Another Password!'
  WITH SUBJECT = 'For ECMA-signed .NET Framework libraries';

ADD SIGNATURE
  TO Assembly::[System.Windows.Forms]
  BY CERTIFICATE [WinForms] WITH PASSWORD = 'Use Another Password!';

BACKUP CERTIFICATE [WinForms]
  TO FILE = 'C:\TEMP\WinFormsCert.crt'
  WITH PRIVATE KEY
  (
    FILE = 'C:\TEMP\WinFormsCert.pvk',
    ENCRYPTION BY PASSWORD = 'Backup Password!',
    DECRYPTION BY PASSWORD = 'Use Another Password!'
  );

ALTER CERTIFICATE [WinForms] REMOVE PRIVATE KEY;
GO

USE [master];
CREATE CERTIFICATE [WinForms] FROM FILE = 'C:\TEMP\WinFormsCert.crt';
CREATE LOGIN [WinForms] FROM CERTIFICATE [WinForms];
GRANT UNSAFE Assembly TO [WinForms];

これらのアセンブリはすべて証明書で署名されているため、CLR 4.0(SQL Server 2012以降)を使用する場合、この回避策は必要ありません。

一般的なSQLCLRの操作の詳細については、次のWebサイトをご覧ください。 SQLCLR Info

3
Solomon Rutzky