5

SQLCMDスクリプトを介して作成された後、SQL Server 2008データベースの既存のすべてのストアドプロシージャを暗号化する可能性はありますか?

これを実行する理由は次のとおりです
。SQLServerManagementStudioで[変更]をクリックして内容を簡単に確認できるように、暗号化せずにストアドプロシージャを開発したいと思います。
ただし、展開の場合は暗号化したいので、作成後に暗号化するスクリプトを書けるのではないかと思いました。開発システムの場合はスクリプトを実行しませんが、エンドユーザーシステムの場合はスクリプトを実行します。

4

8 に答える 8

5

データベースのすべてのストアド プロシージャの暗号化を確認することをお勧めします。

SQL ストアド プロシージャを保護する必要があると判断し、暗号化は良い考えだと思った場合は、十分に注意してください!!! データベース ストアド プロシージャの暗号化は、バックアップ ファイルまたはストアド プロシージャの何らかのソース管理なしで行うべきではありません。私がこれを言う理由は、一度暗号化されると後戻りできないからです。(はい、コードを解読するサードパーティのツールがありますが、なぜそのようなトラブルを経験するのでしょうか。)

このトリックは、会社が別のサーバーでアプリケーションをホストする必要があり、コードが危険にさらされることを懸念していたため、私が開発したものです。そのため、データベースを提供するために、すべてのストアド プロシージャを暗号化することにしました。100 以上のプロシージャを作成したので、各プロシージャを開いて、すべてのストアド プロシージャに「WITH ENCRYPTION」を貼り付けたくありませんでした。(暗号化の方法がわからない場合は、ストアド プロシージャ コードを保護する方法[^]を参照してください)。そこで、同じことを行う独自の小さな C# アプリケーションを作成することにしました。

このアプリケーションは、Visual Studio 2005 と SQL Server 2005 を使用して作成されたコンソール アプリケーションです。入力パラメーターは、データベース名、サーバー アドレス、データベース ユーザー名、およびパスワードです。これらの詳細を提供できるようになると、すべてのストアド プロシージャを暗号化する準備が整います。

アプリケーションのコードをそのままここに置きます。このコードを機能させるには、「Microsft.SQlserver.SMO」参照をアプリケーションに追加して、「Database」や「StoredProcedure」などのクラスにアクセスできるようにする必要があります。

BEFORE YOU DO THIS, TAKE A BACKUP!!!!!!!
//Connect to the local, default instance of SQL Server. 
string DB = "";
ServerConnection objServerCOnnection = new ServerConnection();
objServerCOnnection.LoginSecure = false;
Console.WriteLine("Enter name or IP Address of the Database Server.");
objServerCOnnection.ServerInstance = Console.ReadLine();
Console.WriteLine("Enter name of the Database");
DB = Console.ReadLine();
Console.WriteLine("Enter user id");
objServerCOnnection.Login = Console.ReadLine();
Console.WriteLine("Enter Password");
objServerCOnnection.Password = Console.ReadLine();
Console.WriteLine(" ");
Server srv = new Server();
try // Check to see if server connection details are ok.
{
   srv = new Server(objServerCOnnection);
   if (srv == null)
   {
      Console.WriteLine("Server details entered are wrong,"
         + " Please restart the application");
      Console.ReadLine();
      System.Environment.Exit(System.Environment.ExitCode);
   }
}
catch
{
   Console.WriteLine("Server details entered are wrong,"
      + " Please restart the application");
   Console.ReadLine();
   System.Environment.Exit(System.Environment.ExitCode);
}
Database db = new Database();
try // Check to see if database exists.
{
   db = srv.Databases[DB];
   if (db == null)
   {
      Console.WriteLine("Database does not exist on the current server,"
         + " Please restart the application");
      Console.ReadLine();
      System.Environment.Exit(System.Environment.ExitCode);
   }
}
catch
{
   Console.WriteLine("Database does not exist on the current server,"
      + " Please restart the application");
   Console.ReadLine();
   System.Environment.Exit(System.Environment.ExitCode);
}
string allSP = "";
                
for (int i = 0; i < db.StoredProcedures.Count; i++)
{
   //Define a StoredProcedure object variable by supplying the parent database 
   //and name arguments in the constructor. 
   StoredProcedure sp;
   sp = new StoredProcedure();
   sp = db.StoredProcedures[i];
   if (!sp.IsSystemObject)// Exclude System stored procedures
   {
      if (!sp.IsEncrypted) // Exclude already encrypted stored procedures
      {
         string text = "";// = sp.TextBody;
         sp.TextMode = false;
         sp.IsEncrypted = true;
         sp.TextMode = true;
         sp.Alter();
 
         Console.WriteLine(sp.Name); // display name of the encrypted SP.
         sp = null;
         text = null;
      }
   }
}
于 2011-12-12T17:11:45.607 に答える
4

私も同じ問題を抱えてる。

私の解決策は、すべてのストアド プロシージャに "-- WITH ENCRYPTION" を入れることです。このバージョンは開発者によって使用され、ソース管理に保存されます。

次に、ビルドでツール (sed など) を使用して、ファイルを送信してインストールする前に、ファイルの "-- WITH ENCRYPTION" を "WITH ENCRYPTION" に置き換えます。

純粋な SQL ソリューションの場合、REPLACE を使用できます。

于 2009-11-25T15:55:23.993 に答える
2

WITH ENCRYPTIONこれは、proc の背後にあるコードが SysComments テーブルに格納されていないことを意味します。

exec sp_helptext 'MyProcName'実行して内容をVarChar (MAX)に取得するスクリプトを記述して、複数行/大規模なプロシージャを簡単に保持し、元の状態からプロシージャを変更することができます。

CREATE MyProcName AS

SELECT SecretColumns From TopSecretTable

に変更CREATEALTERASスペース、タブ、または改行で囲みます (正規表現を使用するのに適した場所)。WITH ENCRYPTION AS

ALTER MyProcName WITH ENCRYPTION AS

SELECT SecretColumns From TopSecretTable

これにより、運用サーバー上のストアド プロシージャのすべてのコードが非表示になります。

暗号化する特定のタイプおよび/または命名規則のすべてのオブジェクトに対して、これをLOOPまたはCURSOR(実際にはセットベースの操作IMHOではない)に配置し、展開するたびに実行できます。

于 2009-11-25T15:50:33.893 に答える
1

私はカーソルを書き、ステップスルーし、ほとんどのオブジェクトを暗号化しました。

                            DECLARE cur_ENCRYPT_ANTHING CURSOR READ_ONLY
                            FOR
                                    SELECT  STUFF(src.definition,
                                                  CASE WHEN CHARINDEX('AS' + CHAR(13),src.definition,1) = 0
                                                       THEN CASE WHEN CHARINDEX('AS ' + CHAR(13),src.definition,1) = 0 THEN CHARINDEX('AS ',src.definition,1)
                                                                 ELSE CHARINDEX('AS ' + CHAR(13),src.definition,1)
                                                            END
                                                       ELSE CHARINDEX('AS' + CHAR(13),src.definition,1)
                                                  END,3,'WITH ENCRYPTION AS' + CHAR(13))
                                    FROM    (SELECT o.name
                                             ,      STUFF(RIGHT(sm.definition,LEN(sm.definition) - CHARINDEX('CREATE ',sm.definition,1) + 1),1,6,'ALTER') AS definition
                                             FROM   sys.sql_modules AS sm
                                                    JOIN sys.objects AS o ON sm.object_id = o.object_id
                                             WHERE  CAST(CASE WHEN sm.definition IS NULL THEN 1
                                                              ELSE 0
                                                         END AS BIT) = 0
                                                    AND type <> 'TR'
                                            ) AS src








                            DECLARE @VLS NVARCHAR(MAX)
                            OPEN cur_ENCRYPT_ANTHING

                            FETCH NEXT FROM cur_ENCRYPT_ANTHING INTO @VLS
                            WHILE (@@fetch_status <> -1)
                                  BEGIN
                                        IF (@@fetch_status <> -2)
                                           BEGIN
                                                 BEGIN TRY
                                                       EXEC (@VLS)

                                                 END TRY
                                                 BEGIN CATCH
                                                       PRINT ERROR_MESSAGE()
                                                       PRINT ''

                                                       PRINT @VLS
                                                 END CATCH
                                           END
                                        FETCH NEXT FROM cur_ENCRYPT_ANTHING INTO @VLS
                                  END

                            CLOSE cur_ENCRYPT_ANTHING
                            DEALLOCATE cur_ENCRYPT_ANTHING
于 2016-03-18T05:35:24.513 に答える
1

複数行の文字列変数で sproc を作成し、 を使用して挿入または変更することをお勧めしsp_executesqlます。このアプローチの唯一の厄介な欠点は、文字列の単一引用符が二重になっていることです。

DECLARE @action varchar(max);
SET @action = 'CREATE'; /* or "ALTER" */

DECLARE @withEncryption varchar(max);
SET @withEncryption = ''; /* or "WITH ENCRYPTION" */

DECLARE @sql varchar(max);
SET @sql = @action + ' PROCEDURE dbo.Something'
    (
        ....
    ) ' + @withEncryption +
    ' AS
    BEGIN
        DECLARE @bob varchar(10);
        SET @bob = ''Bob'';
        ....
    END;
    ';

EXEC sp_executesql @statement = @sql;

[変数の周りの空白に注意してください。]

私のスクリプトはすべてこの方法を使用しています。これは、引用符を 2 倍にすることに慣れればうまく機能します。

また、バッチ ファイルを使用してスクリプトを呼び出し、SQLCMD モードのコマンド ライン変数を使用してさまざまな動作を選択します。これにより、反復可能でテストが容易になります。

于 2009-11-25T16:18:56.783 に答える
0

1) SP と関数の Create コードをエクスポートします。バックアップしておきましょう。たとえば、D:\SP2.sql"

2) このトランザクション SQL コードは、既存の SP および関数を削除するスクリプトを生成します。

SELECT 'DROP PROCEDURE  [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + ']'  as A
FROM sys.procedures p
union
SELECT  'DROP FUNCTION ' + [name]  
FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0
order by a

3) この Poweshell コードは次のように置き換えられます

AS
BEGIN

WITH ENCRYPTION 
AS
BEGIN

コード

$File = "D:\SP2.sql"
$File2 = $File.Replace("SP2.sql","SP-WithEncrypt.sql")
$sortie=""
$SP = get-content -path $file
echo $SP.Count
For ($i = 0 ; $i -le $SP.Count)
{ if ($sp[$i] -eq "AS" -and $sp[$i+1] -eq "BEGIN")
   { $AEcrire = "`nWITH ENCRYPTION `n AS `n BEGIN"
   $i+=1 
          }
   else
   {$AEcrire =$sp[$i]
   }
   $sortie += "`n$AEcrire"

 $i+=1 
 $SP.Count-$i
}

$sortie| out-file $File2

.replace( ,) を使用すると高速になりますが、行末に問題があります...

4) SSMS で SP-WithEncrypt.sql を実行します。

于 2018-07-16T21:34:56.403 に答える