0

彼は、私のアプリケーションに暗号化アルゴリズムを実装する方法を調査していました。彼はRC2を見たことがあります。

一方では、c# からの暗号化と復号化に成功しました。

一方で、SQL Server からの暗号化と復号化にも成功しました。

しかし、SQL サーバーから暗号化したものは C# から解読できず、また C# から暗号化すると SQL Server から解読できません。

もちろん、暗号鍵と初期ベクトルは同じです。

SQLサーバーをデータ暗号化として維持しているのは、単なるバイナリ暗号化ではなく、さらに何かを追加していると思います。


編集: C# コード:

public static byte[] Cifrar(string dato, string clave, string vectorInicial)
    {
        byte[] plainText = Encoding.ASCII.GetBytes(dato);
        byte[] keys = Encoding.ASCII.GetBytes(clave);
        byte[] vecI = Encoding.ASCII.GetBytes(vectorInicial);
        MemoryStream memdata = new MemoryStream();


        RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
        ICryptoTransform transform;
        rc2.Mode = CipherMode.CBC;
        transform = rc2.CreateEncryptor(keys, vecI);

        CryptoStream encStream = new CryptoStream(memdata,transform,CryptoStreamMode.Write);


        encStream.Write(plainText, 0, plainText.Length);
        encStream.Close();

        return memdata.ToArray();
    }

    public static string Descrifrar(byte[] dato,string clave, string vectorInicial)
    {
        byte[] keys = Encoding.ASCII.GetBytes(clave);
        byte[] vecI = Encoding.ASCII.GetBytes(vectorInicial);
         MemoryStream memdata = new MemoryStream();

        RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
        ICryptoTransform transform;
        rc2.Mode = CipherMode.CBC;
        transform = rc2.CreateDecryptor(keys, vecI);

        CryptoStream encStream = new CryptoStream(memdata,transform,CryptoStreamMode.Write);


        encStream.Write(dato, 0, dato.Length);
        encStream.Close();

        return Encoding.ASCII.GetString(memdata.ToArray());

    }

暗号化するには、次を使用します。

CifradoRC2.Cifrar("Perico", "sdsdfdsf323", "huihuihuih123");

T-SQL コード:

CREATE SYMMETRIC KEY NuevaClaveDeCifrado WITH IDENTITY_VALUE = 'huihuihuih123',ALGORITHM = RC2,KEY_SOURCE = 'sdsdfdsf323' ENCRYPTION BY Password = 'dsjdkflJ435907NnmM#sX003';

CREATE PROCEDURE OpenSqlKeys
AS
BEGIN    
     SET NOCOUNT ON;
     BEGIN TRY
             OPEN SYMMETRIC KEY NuevaClaveDeCifrado DECRYPTION BY PASSWORD ='dsjdkflJ435907NnmM#sX003';
     END TRY
     BEGIN CATCH
             -- Handle non-existant key here
     END CATCH
END
GO

CREATE FUNCTION Encrypt(@ValueToEncrypt varchar(max))
RETURNS varbinary(256)
AS
BEGIN    
-- Declare the return variable here    
DECLARE @Result varbinary(256)  
SET @Result = EncryptByKey(Key_GUID('NuevaClaveDeCifrado'), @ValueToEncrypt)     
-- Return the result of the function    
RETURN @Result
END
GO

CREATE FUNCTION Decrypt(@ValueToDecrypt varbinary(256))
RETURNS varchar(max)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Result varchar(max)
    SET @Result = DecryptByKey(@ValueToDecrypt)
    -- Return the result of the function
    RETURN @Result
END

暗号化 "Perico" T-SQL のバイナリ結果: 0x009C6828879054489426381EFD2E3FD501000000266B3AF2ED7029C1F567AF8119C5D458FCDE1E984B2262A0

C#:

0x9FC66B77905837F5

ありがとう!

4

1 に答える 1

1

SQL と RC2CryptoServiceProvider の出力が異なるのは、SQL で作成したキーにパスワードを指定しているためだと思います。そのため、2 つの結果の間に長さの違いがあります。CLR dll と C# コードを使用して、必要なことを行うことをお勧めします。

ここに例があります。あなたのコードを使用して関数を作成しました

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Text;
using System.Security.Cryptography;

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlBinary Cifrar(string dato, string clave, string vectorInicial)
    {
        byte[] plainText = Encoding.ASCII.GetBytes(dato);
        byte[] keys = Encoding.ASCII.GetBytes(clave);
        byte[] vecI = Encoding.ASCII.GetBytes(vectorInicial);
        MemoryStream memdata = new MemoryStream();


        RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
        ICryptoTransform transform;
        rc2.Mode = CipherMode.CBC;
        transform = rc2.CreateEncryptor(keys, vecI);

        CryptoStream encStream = new CryptoStream(memdata, transform, CryptoStreamMode.Write);


        encStream.Write(plainText, 0, plainText.Length);
        encStream.Close();
        return new SqlBinary(memdata.ToArray());
    }

    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString Descrifrar(byte[] dato, string clave, string vectorInicial)
    {
        byte[] keys = Encoding.ASCII.GetBytes(clave);
        byte[] vecI = Encoding.ASCII.GetBytes(vectorInicial);
        MemoryStream memdata = new MemoryStream();

        RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
        ICryptoTransform transform;
        rc2.Mode = CipherMode.CBC;
        transform = rc2.CreateDecryptor(keys, vecI);

        CryptoStream encStream = new CryptoStream(memdata, transform, CryptoStreamMode.Write);


        encStream.Write(dato, 0, dato.Length);
        encStream.Close();

        return new SqlString(Encoding.ASCII.GetString(memdata.ToArray()));
    }
};

SQL CLR データベース プロジェクトを作成する必要があります。データベースに接続します。手順に従い、警告を必ずお読みください。今すぐ本番サーバーを停止しないでください。新しいアイテムを追加し、ユーザー定義関数を選択します。そこにコードを貼り付けます。コンパイルして問題がないことを確認したら、プロジェクトを右クリックして [デプロイ] を選択します。次に、それをテストして、それがどのように機能するか、および希望どおりに機能しているかどうかを確認できます。

私は自分のマシンでテストしましたが、うまくいくようです。

于 2012-03-14T10:52:03.723 に答える