October 23, 2012 at 2:13 am
What I am trying to achieve:
I have a big SQL script, around 20.000 lines, that initializes a new database for our application. This script is automatically generated by pasting together numerous smaller scripts, all the stored procedures and SQL functions files (one per file), etc.
I run this script either from SSMS or with SQLCMD.
Moreover, every time there is an application upgrade, e.g. from dbVersion 748 to dbVersion 749, we generate an upgrade script that can upgrade any dbVersion to 749, plus a new initialization script for a 749 database.
Needless to say all procs/funcs are WITH ENCRYPTION.
Also needless to say, I can't give these scripts to the customer, coz that would beat the purpose of WITH ENCRYPTION.
However I want the customer to be able to initialize/upgrade new databases themselves (following some predefined processes).
Is there any way to make these scripts available to the customer in encrypted form so that they can be executed by the customer with one of the available tools, like SQLCMD?
The only other way I can think of is to provide my own tool, that can read the encrypted files, decrypt them in-memory and execute them directly against the selected database.
Not such a big challenge, but I just wanted to know if there is some other option.
Thanks!
October 23, 2012 at 2:24 am
Not an answer, however...
The WITH ENCRYPTION on procs and functions is not encryption. It's obfuscation at best and it is absolutely trivial to reverse. If you are relying on that to secure code, well....
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
October 23, 2012 at 2:29 am
GilaMonster (10/23/2012)
Not an answer, however...The WITH ENCRYPTION on procs and functions is not encryption. It's obfuscation at best and it is absolutely trivial to reverse. If you are relying on that to secure code, well....
Hi Gail,
I knew it used simple obfuscation in early versions of SQL Server, but I thought they'd replaced it with something more subtantial later. I assume I'm wrong in believing that, or is it better in 2012 and not 2008?
October 23, 2012 at 2:34 am
Oh it's better. Better in the sense that it'll take me 10 seconds to reverse not 5 and require sysadmin access.
It is not encryption, it is not going to protect code unless against someone who knows nothing about SQL and doesn't care
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
October 23, 2012 at 5:01 am
My goal WITH ENCRYPTION is not so much to "secure" our code base.
It's the same as with .NET or Java code.
Just some decent obfuscation.
But, obfuscation is good enough to prevent 99.9% of the clients from snooping around the code and finding "bugs" or proposing "optimizations", or even worse replacing directly some SQL code with their own "optimized" versions.
Additionally, clients who are a bit tech-savvy might be tempted to "study" our SQL code and think of it as a "public" API that they can use to write additional code for their own purposes. Then when our upgraded version arrives, their code might break and we will have endless and totally unneeded support cycles.
Similarly, with upgrades, why should I give the chance to a client to look at what changed *internally* in the DB? What would be the benefit? It can only lead to trouble and unnecessary discussion about this and that.
That's why I would like some sort of obfuscated file that can be executed by a readily available tool, like SQLCMD.
Otherwise, I will write my own 🙂
October 23, 2012 at 5:51 am
here's one way i've seen here on the forums to obfuscate a script that is to be deployed:
-- obfuscate a command to send to the client:
Declare @cmds Nvarchar(MAX)
Declare @obfoo varbinary(MAX)
--build our varbinary
Set @cmds = '
PRINT ''This binary string will execute "SELECT * FROM SYS.OBJECTS":''
SELECT * FROM SYS.OBJECTS
'
--proof of concept: can we get the value back
Set @obfoo = CAST(@cmds as varbinary(MAX))
Select @obfoo
--this is what we would deploy to an end user
declare @_ as varbinary(max)
set @_ =0x0D000A005000520049004E0054002000270054006800690073002000620069006E00610072007900200073007400720069006E0067002000770069006C006C002000650078006500630075007400650020002200530045004C0045004300540020002A002000460052004F004D0020005300590053002E004F0042004A00450043005400530022003A0027000D000A00530045004C0045004300540020002A002000460052004F004D0020005300590053002E004F0042004A0045004300540053000D000A00
exec (@_)
Lowell
October 23, 2012 at 6:53 am
That's so so so cool 🙂
Even though it's trivial to reverse with a PRINT CAST(@_ AS NVARCHAR(MAX))
Still I love it. Moreover I can now play pranks on my dev friends and show them how I can execute SQL byte-code, LOL
Thanks man!
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply