问题
I would like to create a stored procedure that decrypts a column that was encrypted by a .Net library.
This is the C# code the encrypts the data:
public static byte[] Encrypt(string plainText, byte[] salt, byte[] key)
{
using (var aesManaged = new AesManaged())
{
if (key.Length != aesManaged.Key.Length) // I use this to toggle encryption on/off
return Encoding.UTF8.GetBytes(plainText);
if (salt.Length == 0)
throw new ArgumentException("salt.Length must be > 0");
byte[] hash;
using (var sha = SHA256.Create())
hash = sha.ComputeHash(salt);
byte[] iv = new byte[aesManaged.IV.Length];
if (hash.Length < iv.Length)
throw new IndexOutOfRangeException("Hash algorithm returns too few bytes for use as IV for encryption algorithm");
else
Buffer.BlockCopy(hash, 0, iv, 0, iv.Length);
using (var encryptor = aesManaged.CreateEncryptor(key, iv))
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
using (var streamWriter = new StreamWriter(cryptoStream))
streamWriter.Write(plainText);
return Concatenate(iv, memoryStream.ToArray());
}
}
}
This is the C# code that will be loaded in SQL Server to be called by a stored procedure:
[SqlProcedure]
public static string SLWSDecrypt(string protectedData, string key)
{
byte[] keyArray = FromHexString(key);
byte[] cryptogram = Convert.FromBase64String(protectedData.ToString());
using (var aesManaged = new AesManaged())
{
if (key.Length != aesManaged.Key.Length) // I use this to toggle encryption on/off
return Encoding.UTF8.GetString(cryptogram);
byte[] iv;
byte[] encryptedData;
int ivLen = aesManaged.IV.Length;
Split(cryptogram, ivLen, out iv, out encryptedData);
using (var decryptor = aesManaged.CreateDecryptor(keyArray, iv))
using (var memoryStream = new MemoryStream(encryptedData))
{
using (var decryptStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var decryptReader = new StreamReader(decryptStream))
return decryptReader.ReadToEnd();
}
}
}
This is registration of the assembly:
CREATE ASSEMBLY MyEncryptor FROM 'C:\MyAssemblies\MyEncryptor.dll' WITH PERMISSION_SET = SAFE
GO
CREATE PROCEDURE SLWSDecrypt
@dataToDecrypt VARCHAR(MAX),
@key VARCHAR(32),
@decryptedText VARCHAR(MAX) OUTPUT
AS
EXTERNAL NAME MyEncryptor.MyEncryption.SLWSDecrypt
GO
The error I get when trying to run the CREATE PROCEDURE statement:
CREATE PROCEDURE failed because a CLR Procedure may only be defined on CLR methods that return either SqlInt32, System.Int32, System.Nullable, void.
来源:https://stackoverflow.com/questions/57117259/how-to-decrypt-column-in-sql-server-that-was-encrypted-by-net-code