June 12, 2008 at 8:49 am
I am having a problem with some code I have in a DLL that is running in SQL Server 2005. I am trying to get some RSA encryption and decryption. The encrypt code runs in SAFE mode without a problem. The decrypt code gets and error:
Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "March_CryptoDecrypt":
System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.KeyContainerPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters parameters)
at System.Security.Cryptography.RSA.FromXmlString(String xmlString)
at Crypto.DoCrypto.Decrypt(String P_text, String P_privateKey)
at SQLServerCrypto.Decrypt(SqlString P_text, SqlString P_privateKey)
Here is the decrypt code:
static public string Decrypt(string P_text, string P_privateKey)
{
string retStr;
string encryptedBlock = "";
string localTextStr = P_text;
int numberOfBlocks;
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
rsaProvider.FromXmlString(P_privateKey);
Queue ();
while (localTextStr.Length != 0)
{
if (rsaProvider.KeySize == 1024)
{
encryptedBlock = localTextStr.Substring(0, localTextStr.IndexOf("=") + 1);
encryptedBlocks.Enqueue(encryptedBlock);
localTextStr = localTextStr.Remove(0, encryptedBlock.Length);
}
else
{
encryptedBlock = localTextStr.Substring(0, localTextStr.IndexOf("==") + 2);
encryptedBlocks.Enqueue(encryptedBlock);
localTextStr = localTextStr.Remove(0, encryptedBlock.Length);
}
}
encryptedBlocks.TrimExcess();
numberOfBlocks = encryptedBlocks.Count;
retStr = "";
for (int cnt = 1; cnt <= numberOfBlocks; cnt++)
{
encryptedBlock = encryptedBlocks.Dequeue();
retStr +=
ASCIIEncoding.ASCII.GetString(rsaProvider.Decrypt(
Convert.FromBase64String(encryptedBlock), false));
}
return (retStr);
}
Here is the encrypt code that works:
static public string Encrypt(string P_text, string P_publicKey)
{
string retStr;
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
rsaProvider.FromXmlString(P_publicKey);
int numberOfBlocks = (P_text.Length / 32) + 1;
char[] charArray = P_text.ToCharArray();
byte[][] byteBlockArray = new byte[numberOfBlocks][];
int incrementer = 0;
for (int cnt = 1; cnt <= numberOfBlocks; cnt++)
{
if (cnt == numberOfBlocks)
{
byteBlockArray[cnt - 1] =
ASCIIEncoding.ASCII.GetBytes(charArray, incrementer, charArray.Length - incrementer);
}
else
{
byteBlockArray[cnt - 1] =
ASCIIEncoding.ASCII.GetBytes(charArray, incrementer, 32);
incrementer += 32;
}
}
retStr = "";
for (int cnt = 0; cnt < byteBlockArray.Length; cnt++)
{
retStr += System.Convert.ToBase64String(
rsaProvider.Encrypt(byteBlockArray[cnt], false));
}
return (retStr);
}
These Methods are wrapped in the following SQL Server Wrapers:
[SqlFunction()]
static public SqlString Encrypt(SqlString P_text, SqlString P_publicKey)
{
string text = P_text.ToString();
string pubKey = P_publicKey.ToString();
string dataStr = DoCrypto.Encrypt(text, pubKey);
SqlString retVal = new SqlString(dataStr);
return (retVal);
}
[SqlFunction()]
static public SqlString Decrypt(SqlString P_text, SqlString P_privateKey)
{
string text = P_text.ToString();
string privKey = P_privateKey.ToString();
string dataStr = DoCrypto.Decrypt(text, privKey);
SqlString retVal = new SqlString(dataStr);
return (retVal);
}
By the error message it seems clear that the access problem is started with the call FromXmlString which takes the RSA key (in XML format) and coverts it to the internal parameters needed by the RSA object. My concern is that both methods have the line:
rsaProvider.FromXmlString(P_privateKey);
Bute since both of these methods have this same line I am at a lost of what the problem might be. I do not see why the encrypt can run is safe mode and the decrypt can not. Does anyone have any ideas?
Thank You,
David Demland
June 15, 2008 at 12:47 pm
This is a CAS (CodeAccessSecurity) permissions error. I think that it means that you are trying to use a DLL that is not approved for your Assembly's safety level.
[font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
Proactive Performance Solutions, Inc. [/font][font="Verdana"] "Performance is our middle name."[/font]
June 18, 2008 at 9:02 am
June 18, 2008 at 9:27 am
I have found out that the .Net call:
rsaProvider.FromXmlString(P_privateKey);
will always access the system when a private key is passed in. This means that the .Net asymmetrical keys can not be used in SAFE mode in SQL Server. This is unfortunate because this design does not take into account hosted environments and privacy issues. These are issue that are going to become more and more real was we seen systems move into a hosted environment.
Viewing 4 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply