RC2 Crypt SQL Server и C#
Он изучал, как реализовать алгоритм шифрования в моем приложении. Он видел 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
Спасибо!
1 ответ
Я думаю, что причина, по которой выходные данные SQL и RC2CryptoServiceProvider различаются, заключается в том, что вы задаете пароль для ключа, который вы создаете в SQL. Вот почему между вашими двумя результатами есть большая разница. Я предлагаю вам использовать CLR CLR и код 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. Это соединит вас с базой данных. Следуйте инструкциям и обязательно прочитайте предупреждения. Не идите и остановите производственный сервер сейчас. Добавьте новый элемент и выберите User-Defined Function. Вставьте код туда. Скомпилируйте его, чтобы убедиться, что все в порядке, затем щелкните правой кнопкой мыши проект и выберите Deploy. Тогда вы можете проверить его и посмотреть, как он работает, и делает ли он то, что вы хотите.
Я проверил на своей машине, и, кажется, делает работу.