From 2bf24f0c94373abb1c26c65bb013ff250d8addbd Mon Sep 17 00:00:00 2001 From: Apress Date: Thu, 13 Oct 2016 05:16:58 +0100 Subject: [PATCH] First commit --- LICENSE.txt | 27 + README.md | 15 + Source-Code/Chapter02/Listing02-01.sql | 5 + Source-Code/Chapter02/Listing02-02.sql | 5 + Source-Code/Chapter02/Listing02-03.sql | 7 + Source-Code/Chapter02/Listing02-04.sql | 5 + Source-Code/Chapter02/Listing02-05.sql | 5 + Source-Code/Chapter02/Listing02-06.sql | 6 + Source-Code/Chapter02/Listing02-07.sql | 12 + Source-Code/Chapter02/Listing02-08.sql | 6 + Source-Code/Chapter02/Listing02-09.sql | 5 + Source-Code/Chapter02/Listing02-10.sql | 7 + Source-Code/Chapter02/Listing02-11.sql | 5 + Source-Code/Chapter02/Listing02-12.sql | 6 + Source-Code/Chapter02/Listing02-13.sql | 5 + Source-Code/Chapter02/Listing02-14.sql | 14 + Source-Code/Chapter02/Listing02-15.sql | 15 + Source-Code/Chapter02/Listing02-16.sql | 14 + Source-Code/Chapter02/Listing02-17.sql | 14 + Source-Code/Chapter02/Listing02-18.sql | 13 + Source-Code/Chapter02/Listing02-19.sql | 16 + Source-Code/Chapter02/Listing02-20.sql | 10 + Source-Code/Chapter02/Listing02-21.sql | 12 + Source-Code/Chapter02/Listing02-22.sql | 13 + Source-Code/Chapter02/Listing02-23.sql | 9 + Source-Code/Chapter02/Listing02-24.sql | 13 + Source-Code/Chapter03/Listing03-01.sql | 15 + Source-Code/Chapter03/Listing03-02.sql | 8 + Source-Code/Chapter03/Listing03-03.sql | 10 + Source-Code/Chapter03/Listing03-04.sql | 39 ++ Source-Code/Chapter03/Listing03-05.sql | 9 + Source-Code/Chapter03/Listing03-06.sql | 20 + Source-Code/Chapter03/Listing03-07.sql | 42 ++ Source-Code/Chapter03/Listing03-08.sql | 22 + Source-Code/Chapter03/Listing03-09.sql | 5 + Source-Code/Chapter03/Listing03-10.sql | 28 + Source-Code/Chapter03/Listing03-11.sql | 29 + Source-Code/Chapter03/Listing03-12.sql | 19 + Source-Code/Chapter03/Listing03-13.sql | 9 + Source-Code/Chapter03/Listing03-14.sql | 10 + Source-Code/Chapter03/Listing03-15.sql | 17 + Source-Code/Chapter03/Listing03-16.sql | 39 ++ Source-Code/Chapter03/Listing03-17.sql | 45 ++ Source-Code/Chapter03/Listing03-18.sql | 29 + Source-Code/Chapter03/Listing03-19.sql | 18 + Source-Code/Chapter04/AsymKey1_Sales.snk | Bin 0 -> 596 bytes Source-Code/Chapter04/Cert2_Sales.cer | Bin 0 -> 828 bytes Source-Code/Chapter04/Cert2_Sales.pvk | Bin 0 -> 1212 bytes Source-Code/Chapter04/CommandLine1.txt | 2 + Source-Code/Chapter04/CommandLine2.txt | 2 + Source-Code/Chapter04/Listing04-01.sql | 5 + Source-Code/Chapter04/Listing04-02.sql | 7 + Source-Code/Chapter04/Listing04-03.sql | 22 + Source-Code/Chapter04/Listing04-04.sql | 51 ++ Source-Code/Chapter04/Listing04-05.sql | 9 + Source-Code/Chapter04/Listing04-06.sql | 36 ++ Source-Code/Chapter04/Listing04-07.sql | 26 + Source-Code/Chapter04/Listing04-08.sql | 5 + Source-Code/Chapter04/Listing04-09.sql | 17 + Source-Code/Chapter04/Listing04-10.sql | 7 + Source-Code/Chapter04/Listing04-11.sql | 29 + Source-Code/Chapter04/Listing04-12.sql | 28 + Source-Code/Chapter04/Listing04-13.sql | 5 + Source-Code/Chapter04/Listing04-14.sql | 16 + Source-Code/Chapter04/Listing04-15.sql | 11 + Source-Code/Chapter04/Listing04-16.sql | 7 + Source-Code/Chapter04/Listing04-17.sql | 6 + Source-Code/Chapter04/Listing04-18.sql | 38 ++ Source-Code/Chapter04/Listing04-19.sql | 14 + Source-Code/Chapter04/Listing04-20.sql | 23 + Source-Code/Chapter04/Listing04-21.sql | 31 + Source-Code/Chapter04/Listing04-22.sql | 32 + Source-Code/Chapter04/Listing04-23.sql | 10 + Source-Code/Chapter04/Listing04-24.sql | 13 + Source-Code/Chapter04/Listing04-25.sql | 21 + Source-Code/Chapter04/Listing04-26.sql | 10 + Source-Code/Chapter04/Listing04-27.sql | 15 + Source-Code/Chapter04/Listing04-28.sql | 45 ++ Source-Code/Chapter04/Listing04-29.sql | 50 ++ Source-Code/Chapter04/Listing04-30.sql | 12 + Source-Code/Chapter04/Listing04-31.sql | 10 + Source-Code/Chapter04/Listing04-32.sql | 10 + Source-Code/Chapter04/Listing04-33.sql | 13 + Source-Code/Chapter04/Listing04-34.sql | 6 + Source-Code/Chapter04/Listing04-35.sql | 7 + Source-Code/Chapter04/Listing04-36.sql | 9 + Source-Code/Chapter04/Listing04-37.sql | 20 + Source-Code/Chapter04/Listing04-38.txt | 16 + Source-Code/Chapter04/Listing04-39.sql | 34 ++ Source-Code/Chapter04/Listing04-40.sql | 18 + Source-Code/Chapter04/Listing04-41.sql | 50 ++ Source-Code/Chapter04/Listing04-42.sql | 14 + Source-Code/Chapter04/Listing04-43.sql | 12 + Source-Code/Chapter04/Listing04-44.sql | 14 + Source-Code/Chapter04/Sidebar04-01.sql | 5 + Source-Code/Chapter04/State-List.xml | 554 ++++++++++++++++++ Source-Code/Chapter05/Listing05-01.sql | 14 + Source-Code/Chapter05/Listing05-02.sql | 5 + Source-Code/Chapter05/Listing05-03.sql | 12 + Source-Code/Chapter05/Listing05-04.sql | 30 + Source-Code/Chapter05/Listing05-05.sql | 8 + Source-Code/Chapter05/Listing05-06.sql | 12 + Source-Code/Chapter05/Listing05-07.sql | 7 + Source-Code/Chapter05/Listing05-08.sql | 19 + Source-Code/Chapter05/Listing05-09.sql | 14 + Source-Code/Chapter05/Listing05-10.sql | 37 ++ Source-Code/Chapter05/Listing05-11.sql | 11 + Source-Code/Chapter05/Listing05-12.sql | 27 + Source-Code/Chapter05/Listing05-13.sql | 8 + Source-Code/Chapter05/Listing05-14.sql | 12 + Source-Code/Chapter05/Listing05-15.sql | 12 + Source-Code/Chapter05/Listing05-16.sql | 34 ++ Source-Code/Chapter05/Listing05-17.sql | 9 + Source-Code/Chapter05/Listing05-18.sql | 9 + Source-Code/Chapter06/Listing06-01.sql | 9 + Source-Code/Chapter06/Listing06-02.sql | 9 + Source-Code/Chapter06/Listing06-03.sql | 14 + Source-Code/Chapter06/Listing06-04.sql | 11 + Source-Code/Chapter06/Listing06-05.sql | 10 + Source-Code/Chapter06/Listing06-06.sql | 14 + Source-Code/Chapter06/Listing06-07.sql | 17 + Source-Code/Chapter06/Listing06-08.sql | 13 + Source-Code/Chapter06/Listing06-09.sql | 18 + Source-Code/Chapter07/Listing07-01.sql | 4 + Source-Code/Chapter07/Listing07-02.sql | 5 + Source-Code/Chapter07/Listing07-03.sql | 12 + Source-Code/Chapter07/Listing07-04.sql | 14 + Source-Code/Chapter07/Listing07-05.sql | 26 + Source-Code/Chapter07/Listing07-06.sql | 22 + Source-Code/Chapter07/Listing07-07.sql | 36 ++ Source-Code/Chapter07/Listing07-08.sql | 15 + Source-Code/Chapter07/Listing07-09.sql | 12 + Source-Code/Chapter07/Listing07-10.sql | 12 + Source-Code/Chapter07/Listing07-11.sql | 24 + .../DecryptAesByPassPhrase.sln | 22 + .../DecryptAesByPassPhrase.suo | Bin 0 -> 9728 bytes .../DecryptAesByPassPhrase.cs | 96 +++ .../DecryptAesByPassPhrase.csproj | 56 ++ .../DecryptAesByPassPhrase.csproj.user | 9 + .../Properties/AssemblyInfo.cs | 31 + .../Test Scripts/Test.sql | 35 ++ .../EncryptAesByPassPhrase.sln | 22 + .../EncryptAesByPassPhrase.suo | Bin 0 -> 9728 bytes .../EncryptAesByPassPhrase.cs | 98 ++++ .../EncryptAesByPassPhrase.csproj | 56 ++ .../EncryptAesByPassPhrase.csproj.user | 9 + .../Properties/AssemblyInfo.cs | 31 + .../Test Scripts/Test.sql | 35 ++ Source-Code/Chapter08/GetHash/GetHash.sln | 22 + Source-Code/Chapter08/GetHash/GetHash.suo | Bin 0 -> 9216 bytes .../Chapter08/GetHash/GetHash/GetHash.cs | 58 ++ .../Chapter08/GetHash/GetHash/GetHash.csproj | 56 ++ .../GetHash/GetHash/GetHash.csproj.user | 9 + .../GetHash/Properties/AssemblyInfo.cs | 31 + .../GetHash/GetHash/Test Scripts/Test.sql | 35 ++ Source-Code/Chapter08/Listing08-03.sql | 38 ++ Source-Code/Chapter08/Listing08-05.sql | 34 ++ Source-Code/Chapter08/Listing08-07.sql | 36 ++ .../Chapter08/SaltedHash/SaltedHash.sln | 22 + .../Chapter08/SaltedHash/SaltedHash.suo | Bin 0 -> 9216 bytes .../SaltedHash/Properties/AssemblyInfo.cs | 31 + .../SaltedHash/SaltedHash/SaltedHash.cs | 66 +++ .../SaltedHash/SaltedHash/SaltedHash.csproj | 56 ++ .../SaltedHash/SaltedHash.csproj.user | 9 + .../SaltedHash/Test Scripts/Test.sql | 35 ++ Source-Code/Chapter09/GetHmac/GetHmac.sln | 22 + Source-Code/Chapter09/GetHmac/GetHmac.suo | Bin 0 -> 9216 bytes .../Chapter09/GetHmac/GetHmac/GetHmac.cs | 60 ++ .../Chapter09/GetHmac/GetHmac/GetHmac.csproj | 56 ++ .../GetHmac/GetHmac/GetHmac.csproj.user | 9 + .../GetHmac/Properties/AssemblyInfo.cs | 31 + .../GetHmac/GetHmac/Test Scripts/Test.sql | 35 ++ Source-Code/Chapter09/Listing09-01.sql | 121 ++++ Source-Code/Chapter09/Listing09-02.sql | 23 + Source-Code/Chapter09/Listing09-03.sql | 8 + Source-Code/Chapter09/Listing09-04.sql | 21 + Source-Code/Chapter09/Listing09-05.sql | 10 + Source-Code/Chapter09/Listing09-06.sql | 10 + Source-Code/Chapter09/Listing09-07.sql | 24 + Source-Code/Chapter09/Listing09-08.sql | 39 ++ Source-Code/Chapter09/Listing09-09.sql | 10 + Source-Code/Chapter09/Listing09-10.sql | 24 + Source-Code/Chapter09/Listing09-11.sql | 17 + Source-Code/Chapter09/Listing09-12.sql | 29 + Source-Code/Chapter09/Listing09-14.sql | 17 + Source-Code/Chapter09/Listing09-15.sql | 28 + Source-Code/Chapter10/CommandLine1.txt | 2 + Source-Code/Chapter10/ListingA.sql | 17 + Source-Code/Notes.txt | 5 + contributing.md | 14 + 190 files changed, 4321 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 Source-Code/Chapter02/Listing02-01.sql create mode 100644 Source-Code/Chapter02/Listing02-02.sql create mode 100644 Source-Code/Chapter02/Listing02-03.sql create mode 100644 Source-Code/Chapter02/Listing02-04.sql create mode 100644 Source-Code/Chapter02/Listing02-05.sql create mode 100644 Source-Code/Chapter02/Listing02-06.sql create mode 100644 Source-Code/Chapter02/Listing02-07.sql create mode 100644 Source-Code/Chapter02/Listing02-08.sql create mode 100644 Source-Code/Chapter02/Listing02-09.sql create mode 100644 Source-Code/Chapter02/Listing02-10.sql create mode 100644 Source-Code/Chapter02/Listing02-11.sql create mode 100644 Source-Code/Chapter02/Listing02-12.sql create mode 100644 Source-Code/Chapter02/Listing02-13.sql create mode 100644 Source-Code/Chapter02/Listing02-14.sql create mode 100644 Source-Code/Chapter02/Listing02-15.sql create mode 100644 Source-Code/Chapter02/Listing02-16.sql create mode 100644 Source-Code/Chapter02/Listing02-17.sql create mode 100644 Source-Code/Chapter02/Listing02-18.sql create mode 100644 Source-Code/Chapter02/Listing02-19.sql create mode 100644 Source-Code/Chapter02/Listing02-20.sql create mode 100644 Source-Code/Chapter02/Listing02-21.sql create mode 100644 Source-Code/Chapter02/Listing02-22.sql create mode 100644 Source-Code/Chapter02/Listing02-23.sql create mode 100644 Source-Code/Chapter02/Listing02-24.sql create mode 100644 Source-Code/Chapter03/Listing03-01.sql create mode 100644 Source-Code/Chapter03/Listing03-02.sql create mode 100644 Source-Code/Chapter03/Listing03-03.sql create mode 100644 Source-Code/Chapter03/Listing03-04.sql create mode 100644 Source-Code/Chapter03/Listing03-05.sql create mode 100644 Source-Code/Chapter03/Listing03-06.sql create mode 100644 Source-Code/Chapter03/Listing03-07.sql create mode 100644 Source-Code/Chapter03/Listing03-08.sql create mode 100644 Source-Code/Chapter03/Listing03-09.sql create mode 100644 Source-Code/Chapter03/Listing03-10.sql create mode 100644 Source-Code/Chapter03/Listing03-11.sql create mode 100644 Source-Code/Chapter03/Listing03-12.sql create mode 100644 Source-Code/Chapter03/Listing03-13.sql create mode 100644 Source-Code/Chapter03/Listing03-14.sql create mode 100644 Source-Code/Chapter03/Listing03-15.sql create mode 100644 Source-Code/Chapter03/Listing03-16.sql create mode 100644 Source-Code/Chapter03/Listing03-17.sql create mode 100644 Source-Code/Chapter03/Listing03-18.sql create mode 100644 Source-Code/Chapter03/Listing03-19.sql create mode 100644 Source-Code/Chapter04/AsymKey1_Sales.snk create mode 100644 Source-Code/Chapter04/Cert2_Sales.cer create mode 100644 Source-Code/Chapter04/Cert2_Sales.pvk create mode 100644 Source-Code/Chapter04/CommandLine1.txt create mode 100644 Source-Code/Chapter04/CommandLine2.txt create mode 100644 Source-Code/Chapter04/Listing04-01.sql create mode 100644 Source-Code/Chapter04/Listing04-02.sql create mode 100644 Source-Code/Chapter04/Listing04-03.sql create mode 100644 Source-Code/Chapter04/Listing04-04.sql create mode 100644 Source-Code/Chapter04/Listing04-05.sql create mode 100644 Source-Code/Chapter04/Listing04-06.sql create mode 100644 Source-Code/Chapter04/Listing04-07.sql create mode 100644 Source-Code/Chapter04/Listing04-08.sql create mode 100644 Source-Code/Chapter04/Listing04-09.sql create mode 100644 Source-Code/Chapter04/Listing04-10.sql create mode 100644 Source-Code/Chapter04/Listing04-11.sql create mode 100644 Source-Code/Chapter04/Listing04-12.sql create mode 100644 Source-Code/Chapter04/Listing04-13.sql create mode 100644 Source-Code/Chapter04/Listing04-14.sql create mode 100644 Source-Code/Chapter04/Listing04-15.sql create mode 100644 Source-Code/Chapter04/Listing04-16.sql create mode 100644 Source-Code/Chapter04/Listing04-17.sql create mode 100644 Source-Code/Chapter04/Listing04-18.sql create mode 100644 Source-Code/Chapter04/Listing04-19.sql create mode 100644 Source-Code/Chapter04/Listing04-20.sql create mode 100644 Source-Code/Chapter04/Listing04-21.sql create mode 100644 Source-Code/Chapter04/Listing04-22.sql create mode 100644 Source-Code/Chapter04/Listing04-23.sql create mode 100644 Source-Code/Chapter04/Listing04-24.sql create mode 100644 Source-Code/Chapter04/Listing04-25.sql create mode 100644 Source-Code/Chapter04/Listing04-26.sql create mode 100644 Source-Code/Chapter04/Listing04-27.sql create mode 100644 Source-Code/Chapter04/Listing04-28.sql create mode 100644 Source-Code/Chapter04/Listing04-29.sql create mode 100644 Source-Code/Chapter04/Listing04-30.sql create mode 100644 Source-Code/Chapter04/Listing04-31.sql create mode 100644 Source-Code/Chapter04/Listing04-32.sql create mode 100644 Source-Code/Chapter04/Listing04-33.sql create mode 100644 Source-Code/Chapter04/Listing04-34.sql create mode 100644 Source-Code/Chapter04/Listing04-35.sql create mode 100644 Source-Code/Chapter04/Listing04-36.sql create mode 100644 Source-Code/Chapter04/Listing04-37.sql create mode 100644 Source-Code/Chapter04/Listing04-38.txt create mode 100644 Source-Code/Chapter04/Listing04-39.sql create mode 100644 Source-Code/Chapter04/Listing04-40.sql create mode 100644 Source-Code/Chapter04/Listing04-41.sql create mode 100644 Source-Code/Chapter04/Listing04-42.sql create mode 100644 Source-Code/Chapter04/Listing04-43.sql create mode 100644 Source-Code/Chapter04/Listing04-44.sql create mode 100644 Source-Code/Chapter04/Sidebar04-01.sql create mode 100644 Source-Code/Chapter04/State-List.xml create mode 100644 Source-Code/Chapter05/Listing05-01.sql create mode 100644 Source-Code/Chapter05/Listing05-02.sql create mode 100644 Source-Code/Chapter05/Listing05-03.sql create mode 100644 Source-Code/Chapter05/Listing05-04.sql create mode 100644 Source-Code/Chapter05/Listing05-05.sql create mode 100644 Source-Code/Chapter05/Listing05-06.sql create mode 100644 Source-Code/Chapter05/Listing05-07.sql create mode 100644 Source-Code/Chapter05/Listing05-08.sql create mode 100644 Source-Code/Chapter05/Listing05-09.sql create mode 100644 Source-Code/Chapter05/Listing05-10.sql create mode 100644 Source-Code/Chapter05/Listing05-11.sql create mode 100644 Source-Code/Chapter05/Listing05-12.sql create mode 100644 Source-Code/Chapter05/Listing05-13.sql create mode 100644 Source-Code/Chapter05/Listing05-14.sql create mode 100644 Source-Code/Chapter05/Listing05-15.sql create mode 100644 Source-Code/Chapter05/Listing05-16.sql create mode 100644 Source-Code/Chapter05/Listing05-17.sql create mode 100644 Source-Code/Chapter05/Listing05-18.sql create mode 100644 Source-Code/Chapter06/Listing06-01.sql create mode 100644 Source-Code/Chapter06/Listing06-02.sql create mode 100644 Source-Code/Chapter06/Listing06-03.sql create mode 100644 Source-Code/Chapter06/Listing06-04.sql create mode 100644 Source-Code/Chapter06/Listing06-05.sql create mode 100644 Source-Code/Chapter06/Listing06-06.sql create mode 100644 Source-Code/Chapter06/Listing06-07.sql create mode 100644 Source-Code/Chapter06/Listing06-08.sql create mode 100644 Source-Code/Chapter06/Listing06-09.sql create mode 100644 Source-Code/Chapter07/Listing07-01.sql create mode 100644 Source-Code/Chapter07/Listing07-02.sql create mode 100644 Source-Code/Chapter07/Listing07-03.sql create mode 100644 Source-Code/Chapter07/Listing07-04.sql create mode 100644 Source-Code/Chapter07/Listing07-05.sql create mode 100644 Source-Code/Chapter07/Listing07-06.sql create mode 100644 Source-Code/Chapter07/Listing07-07.sql create mode 100644 Source-Code/Chapter07/Listing07-08.sql create mode 100644 Source-Code/Chapter07/Listing07-09.sql create mode 100644 Source-Code/Chapter07/Listing07-10.sql create mode 100644 Source-Code/Chapter07/Listing07-11.sql create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.sln create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.suo create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.cs create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj.user create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Properties/AssemblyInfo.cs create mode 100644 Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Test Scripts/Test.sql create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.sln create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.suo create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.cs create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj.user create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Properties/AssemblyInfo.cs create mode 100644 Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Test Scripts/Test.sql create mode 100644 Source-Code/Chapter08/GetHash/GetHash.sln create mode 100644 Source-Code/Chapter08/GetHash/GetHash.suo create mode 100644 Source-Code/Chapter08/GetHash/GetHash/GetHash.cs create mode 100644 Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj create mode 100644 Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj.user create mode 100644 Source-Code/Chapter08/GetHash/GetHash/Properties/AssemblyInfo.cs create mode 100644 Source-Code/Chapter08/GetHash/GetHash/Test Scripts/Test.sql create mode 100644 Source-Code/Chapter08/Listing08-03.sql create mode 100644 Source-Code/Chapter08/Listing08-05.sql create mode 100644 Source-Code/Chapter08/Listing08-07.sql create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash.sln create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash.suo create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash/Properties/AssemblyInfo.cs create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.cs create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.csproj create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.csproj.user create mode 100644 Source-Code/Chapter08/SaltedHash/SaltedHash/Test Scripts/Test.sql create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac.sln create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac.suo create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.cs create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj.user create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac/Properties/AssemblyInfo.cs create mode 100644 Source-Code/Chapter09/GetHmac/GetHmac/Test Scripts/Test.sql create mode 100644 Source-Code/Chapter09/Listing09-01.sql create mode 100644 Source-Code/Chapter09/Listing09-02.sql create mode 100644 Source-Code/Chapter09/Listing09-03.sql create mode 100644 Source-Code/Chapter09/Listing09-04.sql create mode 100644 Source-Code/Chapter09/Listing09-05.sql create mode 100644 Source-Code/Chapter09/Listing09-06.sql create mode 100644 Source-Code/Chapter09/Listing09-07.sql create mode 100644 Source-Code/Chapter09/Listing09-08.sql create mode 100644 Source-Code/Chapter09/Listing09-09.sql create mode 100644 Source-Code/Chapter09/Listing09-10.sql create mode 100644 Source-Code/Chapter09/Listing09-11.sql create mode 100644 Source-Code/Chapter09/Listing09-12.sql create mode 100644 Source-Code/Chapter09/Listing09-14.sql create mode 100644 Source-Code/Chapter09/Listing09-15.sql create mode 100644 Source-Code/Chapter10/CommandLine1.txt create mode 100644 Source-Code/Chapter10/ListingA.sql create mode 100644 Source-Code/Notes.txt create mode 100644 contributing.md diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d477c54 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2009 Michael Coles and Rodney Landrum + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce3cb43 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Expert SQL Server 2008 Encryption*](http://www.apress.com/9781430224648) by Michael Coles and Rodney Landrum (Apress, 2009). + +![Cover image](9781430224648.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/Source-Code/Chapter02/Listing02-01.sql b/Source-Code/Chapter02/Listing02-01.sql new file mode 100644 index 0000000..2980110 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-01.sql @@ -0,0 +1,5 @@ +-- Listing 2-1 +-- Encryption key backup + +BACKUP SERVICE MASTER KEY TO FILE = N'C:\MyServiceMasterKey.key' +ENCRYPTION BY PASSWORD = N'$45^ZeF&u'; diff --git a/Source-Code/Chapter02/Listing02-02.sql b/Source-Code/Chapter02/Listing02-02.sql new file mode 100644 index 0000000..ed1b834 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-02.sql @@ -0,0 +1,5 @@ +-- Listing 2-2 +-- Encryption key restore + +RESTORE SERVICE MASTER KEY FROM FILE = N'C:\MyServiceMasterKey.key' +DECRYPTION BY PASSWORD = N'$45^ZeF&u'; diff --git a/Source-Code/Chapter02/Listing02-03.sql b/Source-Code/Chapter02/Listing02-03.sql new file mode 100644 index 0000000..ebc9368 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-03.sql @@ -0,0 +1,7 @@ +-- Listing 2-3 +-- Change SMK account + +ALTER SERVICE MASTER KEY +WITH NEW_ACCOUNT = N'SQL2008Server\Michael', -- Replace account name with your service account name + NEW_PASSWORD = N'^&3h4l1xPr'; + diff --git a/Source-Code/Chapter02/Listing02-04.sql b/Source-Code/Chapter02/Listing02-04.sql new file mode 100644 index 0000000..1def203 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-04.sql @@ -0,0 +1,5 @@ +-- Listing 2-4 +-- Regenerate SMK + +ALTER SERVICE MASTER KEY REGENERATE; + diff --git a/Source-Code/Chapter02/Listing02-05.sql b/Source-Code/Chapter02/Listing02-05.sql new file mode 100644 index 0000000..a55c6f4 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-05.sql @@ -0,0 +1,5 @@ +-- Listing 2-5 +-- Create DMK + +CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'a0*Ui)4x-f'; + diff --git a/Source-Code/Chapter02/Listing02-06.sql b/Source-Code/Chapter02/Listing02-06.sql new file mode 100644 index 0000000..61f452e --- /dev/null +++ b/Source-Code/Chapter02/Listing02-06.sql @@ -0,0 +1,6 @@ +-- Listing 2-6 +-- Drop DMK encryption by SMK + +ALTER MASTER KEY +DROP ENCRYPTION BY SERVICE MASTER KEY; + diff --git a/Source-Code/Chapter02/Listing02-07.sql b/Source-Code/Chapter02/Listing02-07.sql new file mode 100644 index 0000000..46dfbde --- /dev/null +++ b/Source-Code/Chapter02/Listing02-07.sql @@ -0,0 +1,12 @@ +-- Listing 2-7 +-- Add and remove DMK encryption by password + +-- Add encryption by password +ALTER MASTER KEY ADD ENCRYPTION BY PASSWORD = N'9(%^jQ!@#d'; +GO + +-- Remove encryption by password +ALTER MASTER KEY DROP ENCRYPTION BY PASSWORD = N'9(%^jQ!@#d'; +GO + + diff --git a/Source-Code/Chapter02/Listing02-08.sql b/Source-Code/Chapter02/Listing02-08.sql new file mode 100644 index 0000000..1195851 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-08.sql @@ -0,0 +1,6 @@ +-- Listing 2-8 +-- Regenerate a DMK + +ALTER MASTER KEY REGENERATE WITH ENCRYPTION BY PASSWORD = N'$4yAxU%t7'; + + diff --git a/Source-Code/Chapter02/Listing02-09.sql b/Source-Code/Chapter02/Listing02-09.sql new file mode 100644 index 0000000..d6ae5d0 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-09.sql @@ -0,0 +1,5 @@ +-- Listing 2-9 +-- Backup a DMK + +BACKUP MASTER KEY TO FILE = N'C:\MyDatabaseMasterKey.key' +ENCRYPTION BY PASSWORD = N'0-!t4=Rtr=,'; diff --git a/Source-Code/Chapter02/Listing02-10.sql b/Source-Code/Chapter02/Listing02-10.sql new file mode 100644 index 0000000..7af43c4 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-10.sql @@ -0,0 +1,7 @@ +-- Listing 2-10 +-- Restoring a DMK + +RESTORE MASTER KEY FROM FILE = N'C:\MyDatabaseMasterKey.key' +DECRYPTION BY PASSWORD = N'0-!t4=Rtr=,' +ENCRYPTION BY PASSWORD = N'p#v8A0@+|'; + diff --git a/Source-Code/Chapter02/Listing02-11.sql b/Source-Code/Chapter02/Listing02-11.sql new file mode 100644 index 0000000..9ff9076 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-11.sql @@ -0,0 +1,5 @@ +-- Listing 2-11 +-- Dropping a DMK + +DROP MASTER KEY; + diff --git a/Source-Code/Chapter02/Listing02-12.sql b/Source-Code/Chapter02/Listing02-12.sql new file mode 100644 index 0000000..b0e7413 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-12.sql @@ -0,0 +1,6 @@ +-- Listing 2-12 +-- Opening a DMK + +OPEN MASTER KEY +DECRYPTION BY PASSWORD = N'$4yAxU%t7'; + diff --git a/Source-Code/Chapter02/Listing02-13.sql b/Source-Code/Chapter02/Listing02-13.sql new file mode 100644 index 0000000..f331f57 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-13.sql @@ -0,0 +1,5 @@ +-- Listing 2-13 +-- Closing a DMK + +CLOSE MASTER KEY; + diff --git a/Source-Code/Chapter02/Listing02-14.sql b/Source-Code/Chapter02/Listing02-14.sql new file mode 100644 index 0000000..f39af76 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-14.sql @@ -0,0 +1,14 @@ +-- Listing 2-14 +-- Retrieve list of asymmetric keys from current database + +SELECT + name, + asymmetric_key_id, + pvt_key_encryption_type_desc, + thumbprint, + algorithm_desc, + key_length, + public_key +FROM sys.asymmetric_keys; + + diff --git a/Source-Code/Chapter02/Listing02-15.sql b/Source-Code/Chapter02/Listing02-15.sql new file mode 100644 index 0000000..411e45e --- /dev/null +++ b/Source-Code/Chapter02/Listing02-15.sql @@ -0,0 +1,15 @@ +-- Listing 2-15 +-- Retrieve list of certificates from current database + +SELECT + name, + certificate_id, + pvt_key_encryption_type_desc, + subject, + cert_serial_number, + start_date, + expiry_date, + thumbprint +FROM sys.certificates; + + diff --git a/Source-Code/Chapter02/Listing02-16.sql b/Source-Code/Chapter02/Listing02-16.sql new file mode 100644 index 0000000..9ae1b39 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-16.sql @@ -0,0 +1,14 @@ +-- Listing 2-16 +-- Retrieve list of EKM provider credentials + +SELECT + credential_id, + name, + credential_identity, + create_date, + modify_date, + target_type, + target_id +FROM sys.credentials; + + diff --git a/Source-Code/Chapter02/Listing02-17.sql b/Source-Code/Chapter02/Listing02-17.sql new file mode 100644 index 0000000..3a2aabe --- /dev/null +++ b/Source-Code/Chapter02/Listing02-17.sql @@ -0,0 +1,14 @@ +-- Listing 2-17 +-- Retrieve list of registered cryptographic providers + +SELECT + provider_id, + name, + guid, + version, + dll_path, + is_enabled +FROM sys.cryptographic_providers; + + + diff --git a/Source-Code/Chapter02/Listing02-18.sql b/Source-Code/Chapter02/Listing02-18.sql new file mode 100644 index 0000000..a56b020 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-18.sql @@ -0,0 +1,13 @@ +-- Listing 2-18 +-- Retrieve cryptographic properties + +SELECT + o.name AS object_name, + SCHEMA_NAME(o.schema_id) AS object_schema, + cp.major_id, + cp.class_desc, + cp.crypt_type_desc, + cp.thumbprint +FROM sys.crypt_properties cp +INNER JOIN sys.all_objects o + ON cp.major_id = o.object_id; diff --git a/Source-Code/Chapter02/Listing02-19.sql b/Source-Code/Chapter02/Listing02-19.sql new file mode 100644 index 0000000..9a42dd9 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-19.sql @@ -0,0 +1,16 @@ +-- Listing 2-19 +-- Retrieve symmetric keys that are encrypted by certificate + +SELECT + sk.name AS key_name, + ke.crypt_type_desc, + ke.crypt_property, + c.name AS cert_name, + sk.algorithm_desc AS key_algorithm_desc, + sk.key_length, + ke.thumbprint +FROM sys.key_encryptions ke +INNER JOIN sys.symmetric_keys sk + ON sk.symmetric_key_id = ke.key_id +INNER JOIN sys.certificates c + ON ke.thumbprint = c.thumbprint; diff --git a/Source-Code/Chapter02/Listing02-20.sql b/Source-Code/Chapter02/Listing02-20.sql new file mode 100644 index 0000000..e5b135c --- /dev/null +++ b/Source-Code/Chapter02/Listing02-20.sql @@ -0,0 +1,10 @@ +-- Listing 2-20 +-- Retrieve algorithms supported by cryptographic provider + +SELECT + algorithm_id, + algorithm_tag, + key_type, + key_length +FROM sys.dm_cryptographic_provider_algorithms (65536); -- replace 65536 with your own cryptographic provider ID + diff --git a/Source-Code/Chapter02/Listing02-21.sql b/Source-Code/Chapter02/Listing02-21.sql new file mode 100644 index 0000000..712a9c8 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-21.sql @@ -0,0 +1,12 @@ +-- Listing 2-21 +-- Retrieve keys exposed by cryptographic provider + +SELECT + key_id, + key_name, + algorithm_tag, + key_type, + key_length, + key_thumbprint +FROM sys.dm_cryptographic_provider_keys (65536); -- replace 65536 with your own cryptographic provider ID + diff --git a/Source-Code/Chapter02/Listing02-22.sql b/Source-Code/Chapter02/Listing02-22.sql new file mode 100644 index 0000000..c610d86 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-22.sql @@ -0,0 +1,13 @@ +-- Listing 2-22 +-- Retrieve properties and feature support flags of EKM provider + +SELECT + provider_id, + provider_version, + sqlcrypt_version, + friendly_name, + authentication_type, + symmetric_key_support, + asymmetric_key_support +FROM sys.dm_cryptographic_provider_properties; + diff --git a/Source-Code/Chapter02/Listing02-23.sql b/Source-Code/Chapter02/Listing02-23.sql new file mode 100644 index 0000000..a0859cb --- /dev/null +++ b/Source-Code/Chapter02/Listing02-23.sql @@ -0,0 +1,9 @@ +-- Listing 2-23 +-- Enumerate all open cryptographic provider session + +SELECT + provider_id, + session_handle, + [identity], + spid +FROM sys.dm_cryptographic_provider_sessions(1); diff --git a/Source-Code/Chapter02/Listing02-24.sql b/Source-Code/Chapter02/Listing02-24.sql new file mode 100644 index 0000000..b921bf2 --- /dev/null +++ b/Source-Code/Chapter02/Listing02-24.sql @@ -0,0 +1,13 @@ +-- Listing 2-24 +-- Enumerate database encryption keys + +SELECT + d.name AS db_name, + dbek.encryption_state, + dbek.key_algorithm, + dbek.key_length, + dbek.percent_complete +FROM sys.dm_database_encryption_keys dbek +INNER JOIN sys.databases d + ON dbek.database_id = d.database_id; + diff --git a/Source-Code/Chapter03/Listing03-01.sql b/Source-Code/Chapter03/Listing03-01.sql new file mode 100644 index 0000000..b05f045 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-01.sql @@ -0,0 +1,15 @@ +-- Listing 3-1 +-- Enumerate database encryption keys + +CREATE TABLE SalesLT.EncryptedCustomer +( + CustomerID int NOT NULL PRIMARY KEY, + FirstName varbinary(200), + MiddleName varbinary(200), + LastName varbinary(200), + EmailAddress varbinary(200), + Phone varbinary(150), + rowguid uniqueidentifier +); +GO + diff --git a/Source-Code/Chapter03/Listing03-02.sql b/Source-Code/Chapter03/Listing03-02.sql new file mode 100644 index 0000000..cdbcab3 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-02.sql @@ -0,0 +1,8 @@ +-- Listing 3-2 +-- Create a certificate + +CREATE CERTIFICATE Cert1_Sales +WITH SUBJECT = N'Sales Certificate', +START_DATE = N'2009-01-01', +EXPIRY_DATE = N'2018-12-31'; +GO diff --git a/Source-Code/Chapter03/Listing03-03.sql b/Source-Code/Chapter03/Listing03-03.sql new file mode 100644 index 0000000..5d3ec8b --- /dev/null +++ b/Source-Code/Chapter03/Listing03-03.sql @@ -0,0 +1,10 @@ +-- Listing 3-3 +-- Create a AES 256 symmetric key + +CREATE SYMMETRIC KEY SymKey1_Sales +WITH ALGORITHM = AES_256, + IDENTITY_VALUE = N'Barbarians at the Gate', + KEY_SOURCE = N'We will leave the light on for you' +ENCRYPTION BY CERTIFICATE Cert1_Sales; +GO + diff --git a/Source-Code/Chapter03/Listing03-04.sql b/Source-Code/Chapter03/Listing03-04.sql new file mode 100644 index 0000000..9d6375e --- /dev/null +++ b/Source-Code/Chapter03/Listing03-04.sql @@ -0,0 +1,39 @@ +-- Listing 3-4 +-- Encrypt data with a symmetric key + +-- First wipe out the target table +TRUNCATE TABLE SalesLT.EncryptedCustomer; +GO + +-- Open the key that's protected by certificate +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Encrypt the data +INSERT INTO SalesLT.EncryptedCustomer +( + CustomerID, + FirstName, + MiddleName, + LastName, + EmailAddress, + Phone, + rowguid +) +SELECT + CustomerID, + EncryptByKey(Key_Guid(N'SymKey1_Sales'), FirstName), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), MiddleName), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), LastName), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), EmailAddress), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), Phone), + rowguid +FROM SalesLT.Customer; +GO + +-- Close the key +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO + + diff --git a/Source-Code/Chapter03/Listing03-05.sql b/Source-Code/Chapter03/Listing03-05.sql new file mode 100644 index 0000000..a959d36 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-05.sql @@ -0,0 +1,9 @@ +-- Listing 3-5 +-- View encrypted binary data + +SELECT + CustomerID, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + diff --git a/Source-Code/Chapter03/Listing03-06.sql b/Source-Code/Chapter03/Listing03-06.sql new file mode 100644 index 0000000..bde040e --- /dev/null +++ b/Source-Code/Chapter03/Listing03-06.sql @@ -0,0 +1,20 @@ +-- Listing 3-6 +-- View encrypted character data + +-- Open the key that's protected by certificate +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Decrypt the data +SELECT + CustomerID, + CAST(DecryptByKey(FirstName) AS nvarchar(100)) AS DecryptedFirstName, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + +-- Close the key +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO + diff --git a/Source-Code/Chapter03/Listing03-07.sql b/Source-Code/Chapter03/Listing03-07.sql new file mode 100644 index 0000000..e2cc42a --- /dev/null +++ b/Source-Code/Chapter03/Listing03-07.sql @@ -0,0 +1,42 @@ +-- Listing 3-7 +-- Encrypting with an authenticator + +-- First wipe out the target table +TRUNCATE TABLE SalesLT.EncryptedCustomer; +GO + +-- Open the key that's protected by certificate +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Encrypt the data with authenticator +INSERT INTO SalesLT.EncryptedCustomer +( + CustomerID, + FirstName, + MiddleName, + LastName, + EmailAddress, + Phone, + rowguid +) +SELECT + CustomerID, + EncryptByKey(Key_Guid(N'SymKey1_Sales'), FirstName, 1, + CAST(rowguid AS nvarchar(100))), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), MiddleName, 1, + CAST(rowguid AS nvarchar(100))), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), LastName, 1, + CAST(rowguid AS nvarchar(100))), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), EmailAddress, 1, + CAST(rowguid AS nvarchar(100))), + EncryptByKey(Key_Guid(N'SymKey1_Sales'), Phone, 1, + CAST(rowguid AS nvarchar(100))), + rowguid +FROM SalesLT.Customer; +GO + +-- Close the key +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO diff --git a/Source-Code/Chapter03/Listing03-08.sql b/Source-Code/Chapter03/Listing03-08.sql new file mode 100644 index 0000000..94a7fe4 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-08.sql @@ -0,0 +1,22 @@ +-- Listing 3-8 +-- Decrypting with an authenticator + +-- Open the data key that's protected by certificate +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Decrypt the data with authenticator +SELECT + CustomerID, + CAST + ( + DecryptByKey(FirstName, 1, CAST(rowguid AS nvarchar(100)) + ) AS nvarchar(100)) AS DecryptedFirstName, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + +-- Close the symmetric key +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO diff --git a/Source-Code/Chapter03/Listing03-09.sql b/Source-Code/Chapter03/Listing03-09.sql new file mode 100644 index 0000000..cbde16c --- /dev/null +++ b/Source-Code/Chapter03/Listing03-09.sql @@ -0,0 +1,5 @@ +-- Listing 3-9 +-- Turning off "automatic key management" + +ALTER MASTER KEY +DROP ENCRYPTION BY SERVICE MASTER KEY; diff --git a/Source-Code/Chapter03/Listing03-10.sql b/Source-Code/Chapter03/Listing03-10.sql new file mode 100644 index 0000000..ebda24d --- /dev/null +++ b/Source-Code/Chapter03/Listing03-10.sql @@ -0,0 +1,28 @@ +-- Listing 3-10 +-- Decrypting data without "automatic key management" + +-- Open the DMK that's protected by password; necessary because +-- the certificate is protected by the DMK +OPEN MASTER KEY +DECRYPTION BY PASSWORD = N'a0*Ui)4x-f'; +GO + +-- Open the symmetric key that's protected by certificate +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Decrypt the data +SELECT + CustomerID, + CAST(DecryptByKey(FirstName) AS nvarchar(100)) AS DecryptedFirstName, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + +-- Close the key and DMK +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO + +CLOSE MASTER KEY; +GO diff --git a/Source-Code/Chapter03/Listing03-11.sql b/Source-Code/Chapter03/Listing03-11.sql new file mode 100644 index 0000000..7e3e07e --- /dev/null +++ b/Source-Code/Chapter03/Listing03-11.sql @@ -0,0 +1,29 @@ +-- Listing 3-11 +-- Using encryption by password for symmetric key + +-- Open the DMK that's protected by password +OPEN MASTER KEY +DECRYPTION BY PASSWORD = N'a0*Ui)4x-f'; +GO + +-- Open the data encrypting key +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Add encryption by password to the key +ALTER SYMMETRIC KEY SymKey1_Sales +ADD ENCRYPTION BY PASSWORD = N'~@~*&a1B4!'; +GO + +-- Drop certificate protection from the key +ALTER SYMMETRIC KEY SymKey1_Sales +DROP ENCRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Close the key and DMK +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO + +CLOSE MASTER KEY; +GO diff --git a/Source-Code/Chapter03/Listing03-12.sql b/Source-Code/Chapter03/Listing03-12.sql new file mode 100644 index 0000000..851a3d2 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-12.sql @@ -0,0 +1,19 @@ +-- Listing 3-12 +-- Decrypting data with symmetric key, protected by password + +-- Open the symmetric key that's protected by password +OPEN SYMMETRIC KEY SymKey1_Sales +DECRYPTION BY PASSWORD = N'~@~*&a1B4!'; +GO + +-- Decrypt the data +SELECT + CustomerID, + CAST(DecryptByKey(FirstName) AS nvarchar(100)) AS DecryptedFirstName, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + +-- Close the symmetric key +CLOSE SYMMETRIC KEY SymKey1_Sales; +GO diff --git a/Source-Code/Chapter03/Listing03-13.sql b/Source-Code/Chapter03/Listing03-13.sql new file mode 100644 index 0000000..9ca3ee9 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-13.sql @@ -0,0 +1,9 @@ +-- Listing 3-13 +-- Creating AES key with the key source option + +CREATE SYMMETRIC KEY SymKey5_Sales +WITH ALGORITHM = AES_192, +KEY_SOURCE = N'She sells sea shells by the seashore.', +IDENTITY_VALUE = N'My identity is a shared secret.' +ENCRYPTION BY CERTIFICATE Cert1_Sales; +GO diff --git a/Source-Code/Chapter03/Listing03-14.sql b/Source-Code/Chapter03/Listing03-14.sql new file mode 100644 index 0000000..7010f06 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-14.sql @@ -0,0 +1,10 @@ +-- Listing 3-14 +-- Creating temporary AES key with the key source option + +CREATE SYMMETRIC KEY #TempAESKey +WITH ALGORITHM = AES_128, +KEY_SOURCE = N'I am the very model of a modern major general', +IDENTITY_VALUE = N'I think therefore I am' +ENCRYPTION BY CERTIFICATE Cert1_Sales; +GO + diff --git a/Source-Code/Chapter03/Listing03-15.sql b/Source-Code/Chapter03/Listing03-15.sql new file mode 100644 index 0000000..b33618c --- /dev/null +++ b/Source-Code/Chapter03/Listing03-15.sql @@ -0,0 +1,17 @@ +-- Listing 3-15 +-- Turning "automatic key management" back on + +-- Open the DMK +OPEN MASTER KEY +DECRYPTION BY PASSWORD = 'a0*Ui)4x-f'; +GO + +-- Add encryption by SMK +ALTER MASTER KEY +ADD ENCRYPTION BY SERVICE MASTER KEY; +GO + +-- Close the DMK +CLOSE MASTER KEY; +GO + diff --git a/Source-Code/Chapter03/Listing03-16.sql b/Source-Code/Chapter03/Listing03-16.sql new file mode 100644 index 0000000..dce0ea3 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-16.sql @@ -0,0 +1,39 @@ +-- Listing 3-16 +-- Layering symmetric keys + +-- Create a symmetric key, protect it with a certificate +CREATE SYMMETRIC KEY SymKey2_Sales +WITH ALGORITHM = AES_256 +ENCRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Open top-level symmetric key +OPEN SYMMETRIC KEY SymKey2_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Create the next symmetric key, protect it with the top-level symmetric key +CREATE SYMMETRIC KEY SymKey3_Sales +WITH ALGORITHM = AES_192 +ENCRYPTION BY SYMMETRIC KEY SymKey2_Sales; +GO + +-- Open the previously created symmetric key +OPEN SYMMETRIC KEY SymKey3_Sales +DECRYPTION BY SYMMETRIC KEY SymKey2_Sales; +GO + +-- Create the bottom-level symmetric key, protect it with the previous key +CREATE SYMMETRIC KEY SymKey4_Sales +WITH ALGORITHM = AES_128 +ENCRYPTION BY SYMMETRIC KEY SymKey3_Sales; +GO + +-- Close all open keys +CLOSE SYMMETRIC KEY SymKey3_Sales; +GO + +CLOSE SYMMETRIC KEY SymKey2_Sales; +GO + + diff --git a/Source-Code/Chapter03/Listing03-17.sql b/Source-Code/Chapter03/Listing03-17.sql new file mode 100644 index 0000000..0b95d73 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-17.sql @@ -0,0 +1,45 @@ +-- Listing 3-17 +-- Encrypting data with layered symmetric keys + +-- First wipe out the target table +TRUNCATE TABLE SalesLT.EncryptedCustomer; +GO + +-- Open the multiple levels of symmetric keys +OPEN SYMMETRIC KEY SymKey2_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +OPEN SYMMETRIC KEY SymKey3_Sales +DECRYPTION BY SYMMETRIC KEY SymKey2_Sales; +GO + +OPEN SYMMETRIC KEY SymKey4_Sales +DECRYPTION BY SYMMETRIC KEY SymKey3_Sales; +GO + +-- Encrypt the data +INSERT INTO SalesLT.EncryptedCustomer +( + CustomerID, + FirstName, + MiddleName, + LastName, + EmailAddress, + Phone, + rowguid +) +SELECT + CustomerID, + EncryptByKey(Key_GUID(N'SymKey4_Sales'), FirstName), + EncryptByKey(Key_GUID(N'SymKey4_Sales'), MiddleName), + EncryptByKey(Key_GUID(N'SymKey4_Sales'), LastName), + EncryptByKey(Key_GUID(N'SymKey4_Sales'), EmailAddress), + EncryptByKey(Key_GUID(N'SymKey4_Sales'), Phone), + rowguid +FROM SalesLT.Customer; +GO + +-- Close the symmetric keys +CLOSE ALL SYMMETRIC KEYS; +GO diff --git a/Source-Code/Chapter03/Listing03-18.sql b/Source-Code/Chapter03/Listing03-18.sql new file mode 100644 index 0000000..792fa3e --- /dev/null +++ b/Source-Code/Chapter03/Listing03-18.sql @@ -0,0 +1,29 @@ +-- Listing 3-18 +-- Decrypting data with layered symmetric keys + +-- Open the top-level symmetric key that's protected by certificate +OPEN SYMMETRIC KEY SymKey2_Sales +DECRYPTION BY CERTIFICATE Cert1_Sales; +GO + +-- Open the key that's protected by the top-level key +OPEN SYMMETRIC KEY SymKey3_Sales +DECRYPTION BY SYMMETRIC KEY SymKey2_Sales; +GO + +-- Open the data encrypting key that's protected by the previous key +OPEN SYMMETRIC KEY SymKey4_Sales +DECRYPTION BY SYMMETRIC KEY SymKey3_Sales; +GO + +-- Decrypt the data +SELECT + CustomerID, + CAST(DecryptByKey(FirstName) AS nvarchar(100)) AS DecryptedFirstName, + FirstName +FROM SalesLT.EncryptedCustomer; +GO + +-- Close all the keys +CLOSE ALL SYMMETRIC KEYS; +GO diff --git a/Source-Code/Chapter03/Listing03-19.sql b/Source-Code/Chapter03/Listing03-19.sql new file mode 100644 index 0000000..d9b2105 --- /dev/null +++ b/Source-Code/Chapter03/Listing03-19.sql @@ -0,0 +1,18 @@ +-- Listing 3-19 +-- Encrypting/decrypting data by passphrase + +-- Define the plaintext +DECLARE @plaintext nvarchar(100) = N'Four score and seven years ago our +fathers brought forth, upon this continent, a new nation...'; + +-- Encrypt the data with a passphrase +DECLARE @encryptedtext varbinary(300); + +SET @encryptedtext = EncryptByPassPhrase(N'Quick brown fox', @plaintext); + +-- Decrypt the data with the same passphrase +SELECT CAST + ( + DecryptByPassPhrase(N'Quick brown fox', @encryptedtext) AS nvarchar(100) + ) AS DecryptedData; +GO diff --git a/Source-Code/Chapter04/AsymKey1_Sales.snk b/Source-Code/Chapter04/AsymKey1_Sales.snk new file mode 100644 index 0000000000000000000000000000000000000000..b7d117ef8cbc30be00f5a251992ff3e860f7d265 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097-Wg6)B5oi@kjVFB7UB3#!(fbPSMbn>y z{9+ZkWvXVn+pn?imf_RrDa>aZp5pVtJZC7#LgmZHX;*qu$!`}*;B$Uc{2pagD66ov zYPtwkVp-aGXv{h)nVRnPOsWOWqiGaW#<k_SRqnQHQ-yp<&ys<)oj z^vRRoWs_*Zm-BHQyu3M(2fDTLMt65V2x4b~eF@}^o0$57)0o?IjSiS5| z)dV-|E&_lFQ~OCh+=~A8aBu&w&U}%Wg@o4fIKyI-y_q2fJ&){({J5Cm-~XZcm#Nvk iZYt-Eh6C)$T!qTDymXFtk zLQijO+VCXn@tM~BTQ*Ohx<>57CwFc+krbgD6Hkksn(TYv5c3}MIsu-lbHVZa8+Zbv z1t0Y+YS(-+vyuJ$Y1>75HIr3(?oLd8cbNHwgx&tLc^)aYbsf$>YrU-ZFe&alQgOxY zRQLT)jf*EK%=_H^!@1+hZw1Z?CLx+pWivLMi@N`c-#z?qb5P9birx0gx<4Z7IQq9c zt6IFMf3ZXH%mrraygxS&#G@1meZldglb z>w&&as}epXM`T~u7$?1>x z|7K!lWMEvJU=U{z1B@S8MwU>6;0A$^TU_(4-`RXW+&CeMuZ=Tkp)N_G-h?kP0K=b= zA!XZ*p6}uQE1mgn@h~hGu54d%&A{`~=@dVSZ+{Md$SW?nb%nEwU+1*5uvU@h4PpDQ zPo`(@k0=dqvR^cRgU2(D-i5C;ukMy##!!&U=Jw-=veH#1-FVOD!_W7na^^k=o8fix z!y2aRS8h*XDQgg3*JM&|`+uJ$=NfK{`D~`|}cEmaaWB zE8dW&+QX@&;&!qe*}-~KAEt$In|m#|;!(yLrQ+FecwiQW)$a%GLN~( O>&$YuofCX_?hyc&14~Q* literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter04/Cert2_Sales.pvk b/Source-Code/Chapter04/Cert2_Sales.pvk new file mode 100644 index 0000000000000000000000000000000000000000..7a19ed67fb6fced0fbcf4688ef84e0e7d8606923 GIT binary patch literal 1212 zcmV;t1Vj5C@wKo300002000010000G0001#1ONa!kdihXdQGIzTF70b+UUIp0ssI2 zBme*?!v$wlaSc9Y3+M#%N3h+9V*sS62zuKr$!|SF+E>raECop7zw!0zh7h+IGZUs) z+GRu2q6$oPDTf)Q=eZNT{q9=o3E@v6^ay1`|6=-w*&nP!?pSfA6MrQ3Afj|D2HM9E z-cN7QXKgt>!GIXxdL#PCq2xl#m*ZwTjj?!krS#H$Ww7lv+?jM;a*7#9IU4@}v~Z<* z@LMuM*bl$UJ-6ljt;SCyIfV3tZF|*+m>)-|5vo{hfX|Ln+W?uw9&TJTWMHzD8!yHJ zE`1LTDSGMSQ}59{-4m?YT_N~d4xv&H}xqzj7)h~?T0a050yJl68?NgCvNW33$ zJ3I_aE!Ze0A`ytMk6P55gwre^Q<^wQ8{zgEsW9ohgeIDKUYdv< zGg<+b@;muyl^ew9hgItwa57tRe?o}7DJxxCVL5rD(f6>y*aAql*G?d!TAju(k5_}< zo@M2!(_8JB%v^|`+8j6lk-;}vw}g3hC(UxgU`Ue+7X&ArK6$I2K|AvjNv5eI+RhC{6M*Y1X&gl?)`%lmQMDR-`OFPy$HYuf#%|cenB^NSel|RiW=gcOU3fzr z*+h;mY)$43#^F8qcFWpim**s(cJbnbtNh5yt@-P1QlnW3uvCV~bqF=8bh9?S=cC5l zx<*V5I^fDJ#lWgZg3PvKvU`2!_iHamgIqgpvdTbyy|s9kykclm0&kQOs8RFqes(l= zWkeWxqfd^K{aT4C-gCW7;~yxz)5ar}kA;sF6FoH^F)j8|x*EWn^+5|J!ESJWZkHY+ ztN5NT|3WXel)&_jQ>_E5z^_E^pGpoop*v8NMyELzQIX!cR$qQdKZ5Rxfwk3*dA+cj zyI9qpEP5{Ce!x*g((qu*IDBDuXZY&%h;FU5fMEX;EYnmz9ZF>zK)>Tb0P5dF4abtj z@l)q_Z3|DZJo`%g3>(aE=1A zf%!wQ*N)#QI(i@qEIA2^j1!J9n%J_Pw~~jRT|cn)I^`t$LRZX!-`y}U$zDZH>-M4q@efcV{~D?mV)~g9UfyKK1tP`T6_iJBzJI_yaW*zr92Sr( z>z6$_-=|#p!p_NF1bw$@=PT(WHbGeC+eKl^o|fdWGsfuJ?!4rzT#3OOrfjm;*^%B^K-VoXyZJUi)YJ0oC34Wgv?KMrZsgg{xuBoR*()QVZjG#} aif$w*tAF?N`m(4i%HCOYVnQ=^GRTy(El}S8 literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter04/CommandLine1.txt b/Source-Code/Chapter04/CommandLine1.txt new file mode 100644 index 0000000..9fa9a1f --- /dev/null +++ b/Source-Code/Chapter04/CommandLine1.txt @@ -0,0 +1,2 @@ +Rem This statement creates a strong name key file at the command line +sn -k c:\AsymKey1_Sales.snk \ No newline at end of file diff --git a/Source-Code/Chapter04/CommandLine2.txt b/Source-Code/Chapter04/CommandLine2.txt new file mode 100644 index 0000000..a65bdcc --- /dev/null +++ b/Source-Code/Chapter04/CommandLine2.txt @@ -0,0 +1,2 @@ +Rem This statement creates a certificate at the command line +makecert -sv "c:\Cert2_Sales.pvk" -pe -a sha1 -b "01/01/2009" -e "12/31/2020" -len 2048 -r -n "CN=SQL Server 2008 Test Certificate" c:\Cert2_Sales.cer \ No newline at end of file diff --git a/Source-Code/Chapter04/Listing04-01.sql b/Source-Code/Chapter04/Listing04-01.sql new file mode 100644 index 0000000..46394e8 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-01.sql @@ -0,0 +1,5 @@ +-- Listing 4-1 +-- Creating asymmetric key from SNK file + +CREATE ASYMMETRIC KEY AsymKey1_Sales +FROM FILE = N'c:\AsymKey1_Sales.snk'; diff --git a/Source-Code/Chapter04/Listing04-02.sql b/Source-Code/Chapter04/Listing04-02.sql new file mode 100644 index 0000000..c0ce169 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-02.sql @@ -0,0 +1,7 @@ +-- Listing 4-2 +-- Protecting symmetric key with asymmetric key + +CREATE SYMMETRIC KEY SymKey6_Sales +WITH ALGORITHM = AES_256 +ENCRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + diff --git a/Source-Code/Chapter04/Listing04-03.sql b/Source-Code/Chapter04/Listing04-03.sql new file mode 100644 index 0000000..94a34a6 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-03.sql @@ -0,0 +1,22 @@ +-- Listing 4-3 +-- Sample credit card info tables + +-- Nonencrypted credit card info +CREATE TABLE SalesLT. CreditCardInfo +( + SalesOrderID int not null primary key, + CreditCardNumber nvarchar(50), + CreditCardExpirationDate datetime, + TotalCharge money +); + +-- Encrypted credit card info +CREATE TABLE SalesLT.EncryptedCreditCardInfo +( + SalesOrderID int not null primary key, + CreditCardNumber varbinary(150), + CreditCardExpirationDate varbinary(150), + TotalCharge varbinary(150) +); + + diff --git a/Source-Code/Chapter04/Listing04-04.sql b/Source-Code/Chapter04/Listing04-04.sql new file mode 100644 index 0000000..1972c40 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-04.sql @@ -0,0 +1,51 @@ +-- Listing 4-4 +-- Generate random credit card info + +WITH Generate4Digits /* Generate 4 random digits */ +AS +( + SELECT SUBSTRING + ( + CAST + ( + ABS(CHECKSUM(NEWID())) % 10000 AS NVARCHAR(4) + ) + N'0000', 1, 4 + ) AS Digits +), +CardNum /* Generate a 16 digit random credit card number */ +AS +( + SELECT N'0999-' + + ( + SELECT Digits + FROM Generate4Digits + ) + N'-' + + ( + SELECT Digits + FROM Generate4Digits + ) + N'-' + + ( + SELECT Digits + FROM Generate4Digits + ) AS CardNumber +), +DaysToExpire /* Get a random amount of days to expiration */ +AS +( + SELECT ABS(CHECKSUM(NEWID()) % 700) AS Days +) +INSERT INTO SalesLT.CreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + CardNumber, + DATEADD(DAY, Days, OrderDate), + TotalDue +FROM SalesLT.SalesOrderHeader +CROSS APPLY CardNum +CROSS APPLY DaysToExpire; diff --git a/Source-Code/Chapter04/Listing04-05.sql b/Source-Code/Chapter04/Listing04-05.sql new file mode 100644 index 0000000..fdf9a5b --- /dev/null +++ b/Source-Code/Chapter04/Listing04-05.sql @@ -0,0 +1,9 @@ +-- Listing 4-5 +-- Query unencrypted credit card info + +SELECT + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +FROM SalesLT.CreditCardInfo; diff --git a/Source-Code/Chapter04/Listing04-06.sql b/Source-Code/Chapter04/Listing04-06.sql new file mode 100644 index 0000000..2789f8b --- /dev/null +++ b/Source-Code/Chapter04/Listing04-06.sql @@ -0,0 +1,36 @@ +-- Listing 4-6 +-- Encrypt credit card data + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedCreditCardInfo; +GO + +-- Open symmetric data encrypting key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedCreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CreditCardNumber), + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CAST + ( + CreditCardExpirationDate AS varbinary(10) + ) + ), + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CAST + ( + TotalCharge AS varbinary(10) + ) + ) +FROM SalesLT.CreditCardInfo; + +-- Close data encrypting key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter04/Listing04-07.sql b/Source-Code/Chapter04/Listing04-07.sql new file mode 100644 index 0000000..548efea --- /dev/null +++ b/Source-Code/Chapter04/Listing04-07.sql @@ -0,0 +1,26 @@ +-- Listing 4-7 +-- Decrypting credit card data + +-- Open symmetric data encrypting key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Decrypt previously encrypted credit card data +SELECT + SalesOrderID, + CAST + ( + DecryptByKey(CreditCardNumber) AS nvarchar(100) + ) AS CreditCardNumber, + CAST + ( + DecryptByKey(CreditCardExpirationDate) AS datetime + ) AS CreditCardExpirationDate, + CAST + ( + DecryptByKey(TotalCharge) AS money + ) AS TotalDue +FROM SalesLT.EncryptedCreditCardInfo; + +-- Close data encrypting key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter04/Listing04-08.sql b/Source-Code/Chapter04/Listing04-08.sql new file mode 100644 index 0000000..3a737b7 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-08.sql @@ -0,0 +1,5 @@ +-- Listing 4-8 +-- Add password encryption to asymmetric key + +ALTER ASYMMETRIC KEY AsymKey1_Sales +WITH PRIVATE KEY (ENCRYPTION BY PASSWORD = N'%ui!@90~p'); diff --git a/Source-Code/Chapter04/Listing04-09.sql b/Source-Code/Chapter04/Listing04-09.sql new file mode 100644 index 0000000..9a5a45e --- /dev/null +++ b/Source-Code/Chapter04/Listing04-09.sql @@ -0,0 +1,17 @@ +-- Listing 4-9 +-- Decrypt by symmetric key with auto asymmetric key + +-- Decrypt previously encrypted credit card data +SELECT + SalesOrderID, + CAST + ( + DecryptByKeyAutoAsymKey + ( + AsymKey_ID(N'AsymKey1_Sales'), + N'%ui!@90~p', + CreditCardNumber + ) AS nvarchar(100) + ) AS CreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo; + diff --git a/Source-Code/Chapter04/Listing04-10.sql b/Source-Code/Chapter04/Listing04-10.sql new file mode 100644 index 0000000..2c53b23 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-10.sql @@ -0,0 +1,7 @@ +-- Listing 4-10 +-- Remove password encryption from asymmetric key + +ALTER ASYMMETRIC KEY AsymKey1_Sales +WITH PRIVATE KEY (DECRYPTION BY PASSWORD = N'%ui!@90~p'); + + diff --git a/Source-Code/Chapter04/Listing04-11.sql b/Source-Code/Chapter04/Listing04-11.sql new file mode 100644 index 0000000..835ed05 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-11.sql @@ -0,0 +1,29 @@ +-- Listing 4-11 +-- Encrypt data with asymmetric key + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedCreditCardInfo; +GO + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedCreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + EncryptByAsymKey(AsymKey_ID(N'AsymKey1_Sales'), CreditCardNumber), + EncryptByAsymKey(AsymKey_ID(N'AsymKey1_Sales'), CAST + ( + CreditCardExpirationDate AS varbinary(10) + ) + ), + EncryptByAsymKey(AsymKey_ID(N'AsymKey1_Sales'), CAST + ( + TotalCharge AS varbinary(10) + ) + ) +FROM SalesLT.CreditCardInfo; diff --git a/Source-Code/Chapter04/Listing04-12.sql b/Source-Code/Chapter04/Listing04-12.sql new file mode 100644 index 0000000..e3b27f5 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-12.sql @@ -0,0 +1,28 @@ +-- Listing 4-12 +-- Decrypt data with asymmetric key + +-- Decrypt the credit card info with asymmetric key +SELECT + SalesOrderID, + CAST + ( + DecryptByAsymKey + ( + Asymkey_Id(N'AsymKey1_Sales'), CreditCardNumber + ) AS nvarchar(100) + ) AS CreditCardNumber, + CAST + ( + DecryptByAsymKey + ( + Asymkey_Id(N'AsymKey1_Sales'), CreditCardExpirationDate + ) AS datetime + ) AS CreditCardExpirationDate, + CAST + ( + DecryptByAsymKey + ( + Asymkey_Id(N'AsymKey1_Sales'), TotalCharge + ) AS money + ) AS TotalCharge +FROM SalesLT.EncryptedCreditCardInfo; diff --git a/Source-Code/Chapter04/Listing04-13.sql b/Source-Code/Chapter04/Listing04-13.sql new file mode 100644 index 0000000..7600df9 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-13.sql @@ -0,0 +1,5 @@ +-- Listing 4-13 +-- Remove private key from asymmetric key pair + +ALTER ASYMMETRIC KEY AsymKey1_Sales +REMOVE PRIVATE KEY; diff --git a/Source-Code/Chapter04/Listing04-14.sql b/Source-Code/Chapter04/Listing04-14.sql new file mode 100644 index 0000000..f4fa075 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-14.sql @@ -0,0 +1,16 @@ +-- Listing 4-14 +-- Table to hold encrypted address info + +CREATE TABLE SalesLT.EncryptedAddress +( + AddressID int NOT NULL PRIMARY KEY, + AddressLine1 varbinary(256) NOT NULL, + AddressLine2 varbinary(256) NULL, + City varbinary(256) NOT NULL, + StateProvince varbinary(256) NOT NULL, + CountryRegion varbinary(256) NOT NULL, + PostalCode varbinary(256) NOT NULL, + rowguid uniqueidentifier NOT NULL, + ModifiedDate datetime NOT NULL +); + diff --git a/Source-Code/Chapter04/Listing04-15.sql b/Source-Code/Chapter04/Listing04-15.sql new file mode 100644 index 0000000..a95c1a0 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-15.sql @@ -0,0 +1,11 @@ +-- Listing 4-15 +-- Register certificate from files + +CREATE CERTIFICATE Cert2_Sales +FROM FILE = N'c:\Cert2_Sales.cer' +WITH PRIVATE KEY +( + FILE = N'c:\Cert2_Sales.pvk', + DECRYPTION BY PASSWORD = N't$%0p}gI' +); + diff --git a/Source-Code/Chapter04/Listing04-16.sql b/Source-Code/Chapter04/Listing04-16.sql new file mode 100644 index 0000000..147576e --- /dev/null +++ b/Source-Code/Chapter04/Listing04-16.sql @@ -0,0 +1,7 @@ +-- Listing 4-16 +-- Create self-signed certificate on SQL Server + +CREATE CERTIFICATE Cert3_Sales +WITH SUBJECT = N'SQL Server 2008 Test Certificate 3', +START_DATE = '2009-01-01', +EXPIRY_DATE = '2020-12-31'; diff --git a/Source-Code/Chapter04/Listing04-17.sql b/Source-Code/Chapter04/Listing04-17.sql new file mode 100644 index 0000000..3ca3242 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-17.sql @@ -0,0 +1,6 @@ +-- Listing 4-17 +-- Protect symmetric key with certificate + +CREATE SYMMETRIC KEY SymKey7_Sales +WITH ALGORITHM = AES_256 +ENCRYPTION BY CERTIFICATE Cert2_Sales; diff --git a/Source-Code/Chapter04/Listing04-18.sql b/Source-Code/Chapter04/Listing04-18.sql new file mode 100644 index 0000000..9fb6b1e --- /dev/null +++ b/Source-Code/Chapter04/Listing04-18.sql @@ -0,0 +1,38 @@ +-- Listing 4-18 +-- Encrypt with symmetric key protected by certificate + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedAddress; +GO + +-- Open symmetric data encrypting key +OPEN SYMMETRIC KEY SymKey7_Sales +DECRYPTION BY CERTIFICATE Cert2_Sales; + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedAddress +( + AddressID, + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode, + rowguid, + ModifiedDate +) +SELECT + AddressID, + EncryptByKey(Key_Guid(N'SymKey7_Sales'), AddressLine1), + EncryptByKey(Key_Guid(N'SymKey7_Sales'), AddressLine2), + EncryptByKey(Key_Guid(N'SymKey7_Sales'), City), + EncryptByKey(Key_Guid(N'SymKey7_Sales'), StateProvince), + EncryptByKey(Key_Guid(N'SymKey7_Sales'), CountryRegion), + EncryptByKey(Key_Guid(N'SymKey7_Sales'), PostalCode), + rowguid, + ModifiedDate +FROM SalesLT.Address; + +-- Close data encrypting key +CLOSE SYMMETRIC KEY SymKey7_Sales; diff --git a/Source-Code/Chapter04/Listing04-19.sql b/Source-Code/Chapter04/Listing04-19.sql new file mode 100644 index 0000000..47f2e53 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-19.sql @@ -0,0 +1,14 @@ +-- Listing 4-19 +-- Querying binary encrypted addresses + +SELECT + AddressID, + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode, + rowguid, + ModifiedDate +FROM SalesLT.EncryptedAddress; diff --git a/Source-Code/Chapter04/Listing04-20.sql b/Source-Code/Chapter04/Listing04-20.sql new file mode 100644 index 0000000..bf72bf6 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-20.sql @@ -0,0 +1,23 @@ +-- Listing 4-20 +-- Decrypting encrypted addresses + +-- Open symmetric data encrypting key +OPEN SYMMETRIC KEY SymKey7_Sales +DECRYPTION BY CERTIFICATE Cert2_Sales; + +-- Decrypt sample random credit card data +SELECT + AddressID, + CAST(DecryptByKey(AddressLine1) AS nvarchar(60)), + CAST(DecryptByKey(AddressLine2) AS nvarchar(60)), + CAST(DecryptByKey(City) AS nvarchar(30)), + CAST(DecryptByKey(StateProvince) AS nvarchar(50)), + CAST(DecryptByKey(CountryRegion) AS nvarchar(50)), + CAST(DecryptByKey(PostalCode) AS nvarchar(15)), + rowguid, + ModifiedDate +FROM SalesLT.EncryptedAddress; + +-- Close data encrypting key +CLOSE SYMMETRIC KEY SymKey7_Sales; + diff --git a/Source-Code/Chapter04/Listing04-21.sql b/Source-Code/Chapter04/Listing04-21.sql new file mode 100644 index 0000000..20a0765 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-21.sql @@ -0,0 +1,31 @@ +-- Listing 4-21 +-- Encrypting data directly with certificate + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedAddress; +GO + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedAddress +( + AddressID, + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode, + rowguid, + ModifiedDate +) +SELECT + AddressID, + EncryptByCert(Cert_ID(N'Cert2_Sales'), AddressLine1), + EncryptByCert(Cert_ID(N'Cert2_Sales'), AddressLine2), + EncryptByCert(Cert_ID(N'Cert2_Sales'), City), + EncryptByCert(Cert_ID(N'Cert2_Sales'), StateProvince), + EncryptByCert(Cert_ID(N'Cert2_Sales'), CountryRegion), + EncryptByCert(Cert_ID(N'Cert2_Sales'), PostalCode), + rowguid, + ModifiedDate +FROM SalesLT.Address; diff --git a/Source-Code/Chapter04/Listing04-22.sql b/Source-Code/Chapter04/Listing04-22.sql new file mode 100644 index 0000000..ac1019a --- /dev/null +++ b/Source-Code/Chapter04/Listing04-22.sql @@ -0,0 +1,32 @@ +-- Listing 4-22 +-- Decrypting data directly with certificate + +SELECT + AddressID, + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), AddressLine1) AS nvarchar(60) + ), + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), AddressLine2) AS nvarchar(60) + ), + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), City) AS nvarchar(30) + ), + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), StateProvince) AS nvarchar(50) + ), + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), CountryRegion) AS nvarchar(50) + ), + CAST + ( + DecryptByCert(Cert_ID(N'Cert2_Sales'), PostalCode) AS nvarchar(15) + ), + rowguid, + ModifiedDate +FROM SalesLT.EncryptedAddress; diff --git a/Source-Code/Chapter04/Listing04-23.sql b/Source-Code/Chapter04/Listing04-23.sql new file mode 100644 index 0000000..118b3d2 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-23.sql @@ -0,0 +1,10 @@ +-- Listing 4-23 +-- Backup a certificate + +BACKUP CERTIFICATE Cert3_Sales +TO FILE = N'c:\Cert3_Sales.cer' +WITH PRIVATE KEY +( + FILE = N'c:\Cert3_Sales.pvk', + ENCRYPTION BY PASSWORD = N'@oo$k3-9!' +); diff --git a/Source-Code/Chapter04/Listing04-24.sql b/Source-Code/Chapter04/Listing04-24.sql new file mode 100644 index 0000000..6c7c684 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-24.sql @@ -0,0 +1,13 @@ +-- Listing 4-24 +-- Restoring a backed up certificate + +DROP CERTIFICATE Cert3_Sales; +GO + +CREATE CERTIFICATE Cert3_Sales +FROM FILE = N'c:\Cert3_Sales.cer' +WITH PRIVATE KEY +( + FILE = N'c:\Cert3_Sales.pvk', + DECRYPTION BY PASSWORD = N'@oo$k3-9!' +); diff --git a/Source-Code/Chapter04/Listing04-25.sql b/Source-Code/Chapter04/Listing04-25.sql new file mode 100644 index 0000000..3a9569e --- /dev/null +++ b/Source-Code/Chapter04/Listing04-25.sql @@ -0,0 +1,21 @@ +-- Listing 4-25 +-- Signing data with a certificate + +CREATE TABLE SalesLT.ProductDecriptionSigs +( + ProductDescriptionID int not null primary key, + Signature varbinary(256) +); +GO + +INSERT INTO SalesLT.ProductDecriptionSigs +( + ProductDescriptionID, + Signature +) +SELECT + ProductDescriptionID, + SignByCert(Cert_ID(N'Cert1_Sales'), Description) +FROM SalesLT.ProductDescription; +GO + diff --git a/Source-Code/Chapter04/Listing04-26.sql b/Source-Code/Chapter04/Listing04-26.sql new file mode 100644 index 0000000..2c69359 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-26.sql @@ -0,0 +1,10 @@ +-- Listing 4-26 +-- Querying product descriptions and signatures + +SELECT + pd.ProductDescriptionID, + pd.Description, + s.Signature +FROM SalesLT.ProductDescription pd +INNER JOIN SalesLT.ProductDecriptionSigs s +ON pd.ProductDescriptionID = s.ProductDescriptionID; diff --git a/Source-Code/Chapter04/Listing04-27.sql b/Source-Code/Chapter04/Listing04-27.sql new file mode 100644 index 0000000..07d7fda --- /dev/null +++ b/Source-Code/Chapter04/Listing04-27.sql @@ -0,0 +1,15 @@ +-- Listing 4-27 +-- Verifying certificate signatures + +SELECT + pd.ProductDescriptionID, + pd.Description, + s.Signature, + VerifySignedByCert + ( + Cert_ID(N'Cert1_Sales'), pd.Description, s.Signature + ) AS Verified +FROM SalesLT.ProductDescription pd +INNER JOIN SalesLT.ProductDecriptionSigs s +ON pd.ProductDescriptionID = s.ProductDescriptionID; + diff --git a/Source-Code/Chapter04/Listing04-28.sql b/Source-Code/Chapter04/Listing04-28.sql new file mode 100644 index 0000000..2fc29ca --- /dev/null +++ b/Source-Code/Chapter04/Listing04-28.sql @@ -0,0 +1,45 @@ +-- Listing 4-28 +-- Create logging table and encrypt credit card info + +-- Create a logging table +CREATE TABLE SalesLT.DecryptCreditCardInfoLog +( + LogID int not null identity(1, 1) primary key, + SalesOrderID int, + LogDate datetime, + LogUser sysname +); +GO + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedCreditCardInfo; +GO + +OPEN SYMMETRIC KEY SymKey7_Sales +DECRYPTION BY CERTIFICATE Cert2_Sales; + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedCreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + EncryptByKey(Key_GUID(N'SymKey7_Sales'), CreditCardNumber), + EncryptByKey(Key_GUID(N'SymKey7_Sales'), CAST + ( + CreditCardExpirationDate AS varbinary(10) + ) + ), + EncryptByKey(Key_GUID(N'SymKey7_Sales'), CAST + ( + TotalCharge AS varbinary(10) + ) + ) +FROM SalesLT.CreditCardInfo; + +CLOSE SYMMETRIC KEY SymKey7_Sales; +GO diff --git a/Source-Code/Chapter04/Listing04-29.sql b/Source-Code/Chapter04/Listing04-29.sql new file mode 100644 index 0000000..3b003ed --- /dev/null +++ b/Source-Code/Chapter04/Listing04-29.sql @@ -0,0 +1,50 @@ +-- Listing 4-29 +-- Procedure to decrypt credit card info + +CREATE PROCEDURE SalesLT.GetOrderSummary @SalesOrderID int +AS +BEGIN + OPEN SYMMETRIC KEY SymKey7_Sales + DECRYPTION BY CERTIFICATE Cert2_Sales; + + SELECT + soh.SalesOrderID, + soh.OrderDate, + soh.ShipDate, + soh.Status, + soh.TotalDue, + sod.ProductID, + p.Name AS ProductName, + CAST + ( + DecryptByKey (ecc.CreditCardNumber) AS nvarchar(100) + ) AS CreditCardNumber, + CAST + ( + DecryptByKey (ecc.CreditCardExpirationDate) AS datetime + ) AS CreditCardExp + FROM SalesLT.SalesOrderHeader soh + INNER JOIN SalesLT.SalesOrderDetail sod + ON soh.SalesOrderID = sod.SalesOrderID + INNER JOIN SalesLT.Product p + ON sod.ProductID = p.ProductID + INNER JOIN SalesLT.EncryptedCreditCardInfo ecc + ON soh.SalesOrderID = ecc.SalesOrderID + WHERE soh.SalesOrderID = @SalesOrderID; + + INSERT INTO SalesLT.DecryptCreditCardInfoLog + ( + SalesOrderID, + LogUser, + LogDate + ) + VALUES + ( + @SalesOrderID, + USER_NAME(), + GETDATE() + ); + + CLOSE SYMMETRIC KEY SymKey7_Sales; +END; +GO diff --git a/Source-Code/Chapter04/Listing04-30.sql b/Source-Code/Chapter04/Listing04-30.sql new file mode 100644 index 0000000..4201835 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-30.sql @@ -0,0 +1,12 @@ +-- Listing 4-30 +-- Create certificate and certificate user + +CREATE CERTIFICATE Cert_SignModules +WITH SUBJECT = N'Certificate to sign modules', +START_DATE = '2009-01-01', +EXPIRY_DATE = '2020-12-31'; +GO + +CREATE USER CCDecryptor +FOR CERTIFICATE Cert_SignModules; +GO diff --git a/Source-Code/Chapter04/Listing04-31.sql b/Source-Code/Chapter04/Listing04-31.sql new file mode 100644 index 0000000..4222a89 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-31.sql @@ -0,0 +1,10 @@ +-- Listing 4-31 +-- Grant permissions to certificate user + +GRANT CONTROL ON SYMMETRIC KEY::SymKey7_Sales +TO CCDecryptor; +GO + +GRANT CONTROL ON CERTIFICATE::Cert2_Sales +TO CCDecryptor; +GO diff --git a/Source-Code/Chapter04/Listing04-32.sql b/Source-Code/Chapter04/Listing04-32.sql new file mode 100644 index 0000000..15d82ca --- /dev/null +++ b/Source-Code/Chapter04/Listing04-32.sql @@ -0,0 +1,10 @@ +-- Listing 4-32 +-- Give Bob permissions + +CREATE USER Bob +WITHOUT LOGIN; +GO + +GRANT EXECUTE ON SalesLT.GetOrderSummary +TO Bob; +GO diff --git a/Source-Code/Chapter04/Listing04-33.sql b/Source-Code/Chapter04/Listing04-33.sql new file mode 100644 index 0000000..944ac37 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-33.sql @@ -0,0 +1,13 @@ +-- Listing 4-33 +-- Bob tries (and fails) to execute the procs + +EXECUTE AS USER = N'Bob'; +SELECT * +FROM SalesLT.EncryptedCreditCardInfo; +REVERT; +GO + +EXECUTE AS USER = N'Bob'; +EXEC SalesLT.GetOrderSummary 71774; +REVERT; +GO diff --git a/Source-Code/Chapter04/Listing04-34.sql b/Source-Code/Chapter04/Listing04-34.sql new file mode 100644 index 0000000..e7fbc25 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-34.sql @@ -0,0 +1,6 @@ +-- Listing 4-34 +-- Sign a proc + +ADD SIGNATURE TO SalesLT.GetOrderSummary +BY CERTIFICATE Cert_SignModules; +GO diff --git a/Source-Code/Chapter04/Listing04-35.sql b/Source-Code/Chapter04/Listing04-35.sql new file mode 100644 index 0000000..a75b443 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-35.sql @@ -0,0 +1,7 @@ +-- Listing 4-35 +-- Bob tries (and succeeds) to execute a proc + +EXECUTE AS USER = N'Bob'; +EXEC SalesLT.GetOrderSummary 71774; +REVERT; +GO diff --git a/Source-Code/Chapter04/Listing04-36.sql b/Source-Code/Chapter04/Listing04-36.sql new file mode 100644 index 0000000..e3bfcc4 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-36.sql @@ -0,0 +1,9 @@ +-- Listing 4-36 +-- Querying the log table + +SELECT + LogID, + SalesOrderID, + LogDate, + LogUser +FROM SalesLT.DecryptCreditCardInfoLog; diff --git a/Source-Code/Chapter04/Listing04-37.sql b/Source-Code/Chapter04/Listing04-37.sql new file mode 100644 index 0000000..67fcf68 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-37.sql @@ -0,0 +1,20 @@ +-- Listing 4-37 +-- Create sample state table + +USE AdventureWorksLT2008; +GO + +CREATE TABLE dbo.State +( + abbreviation nvarchar(2) not null primary key, + name nvarchar(100) not null, + capital nvarchar(100) not null, + flag_graphic nvarchar(20) not null, + entry_date date not null, + fact nvarchar(2000) not null, + capital_address nvarchar(50) not null, + zip_code nvarchar(5) not null, + longitude float not null, + latitude float not null +); +GO diff --git a/Source-Code/Chapter04/Listing04-38.txt b/Source-Code/Chapter04/Listing04-38.txt new file mode 100644 index 0000000..f14c563 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-38.txt @@ -0,0 +1,16 @@ +-- Listing 4-38 +-- XML file snippet + + + + . . . + diff --git a/Source-Code/Chapter04/Listing04-39.sql b/Source-Code/Chapter04/Listing04-39.sql new file mode 100644 index 0000000..794aa13 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-39.sql @@ -0,0 +1,34 @@ +-- Listing 4-39 +-- Create certificate and login + +-- Create certificate in master database +USE master; +GO + +CREATE CERTIFICATE LoadStates_Cert + ENCRYPTION BY PASSWORD = N'l0a8p3rm$' + WITH SUBJECT = N'Load states permissions', + START_DATE = '2009-01-01', + EXPIRY_DATE = '2016-01-01' +GO + +-- Create a login for the certificate +CREATE LOGIN LoadStates_Login +FROM CERTIFICATE LoadStates_Cert; +GO + +-- Assign "Administer Bulk Operations" permissions to the login +GRANT ADMINISTER BULK OPERATIONS +TO LoadStates_Login; +GO + +-- Backup the certificate to a file +BACKUP CERTIFICATE LoadStates_Cert +TO FILE = N'C:\Windows\Temp\LoadStates_Cert.cer' +WITH PRIVATE KEY +( + FILE = N'C:\Windows\Temp\LoadStates_Cert.pvk' , + ENCRYPTION BY PASSWORD = N'f!133nc#', + DECRYPTION BY PASSWORD = N'l0a8p3rm$' +); +GO diff --git a/Source-Code/Chapter04/Listing04-40.sql b/Source-Code/Chapter04/Listing04-40.sql new file mode 100644 index 0000000..8fcbe3b --- /dev/null +++ b/Source-Code/Chapter04/Listing04-40.sql @@ -0,0 +1,18 @@ +-- Listing 4-40 +-- Recreate certificate in target database + +-- Recreate the certificate in AdventureWorksLT 2008 database +-- from the backup. Be sure to delete the backup files from +-- the local hard drive after you recreate the certificate! +USE AdventureWorksLT2008; +GO + +CREATE CERTIFICATE LoadStates_Cert +FROM FILE = N'C:\Windows\Temp\LoadStates_Cert.cer' +WITH PRIVATE KEY +( + FILE = N'C:\Windows\Temp\LoadStates_Cert.pvk', + DECRYPTION BY PASSWORD = N'f!133nc#', + ENCRYPTION BY PASSWORD = N'l0a8p3rm$' +) +GO diff --git a/Source-Code/Chapter04/Listing04-41.sql b/Source-Code/Chapter04/Listing04-41.sql new file mode 100644 index 0000000..d7a218f --- /dev/null +++ b/Source-Code/Chapter04/Listing04-41.sql @@ -0,0 +1,50 @@ +-- Listing 4-41 +-- Create and sign LoadStates procedure + +-- Now create the LoadStates procedure to bulk load an XML file +-- and shred into a relational table +CREATE PROCEDURE dbo.LoadStates +AS +BEGIN + DECLARE @x xml; + + EXEC dbo.sp_executesql N'SELECT @x = BulkColumn + FROM OPENROWSET + ( + BULK N''c:\state-list.xml'', SINGLE_BLOB + ) AS x;', + N'@x xml OUTPUT', + @x = @x OUTPUT; + + INSERT INTO dbo.State + ( + abbreviation, + name, + capital, + flag_graphic, + entry_date, + fact, + capital_address, + zip_code, + longitude, + latitude + ) + SELECT c.value(N'@abbreviation[1]', N'nvarchar(2)'), + c.value(N'@name[1]', N'nvarchar(100)'), + c.value(N'@capital[1]', N'nvarchar(100)'), + c.value(N'@flag[1]', N'nvarchar(20)'), + c.value(N'@date[1]', N'date'), + c.value(N'@fact[1]', N'nvarchar(2000)'), + c.value(N'@address[1]', N'nvarchar(50)'), + c.value(N'@zip[1]', N'nvarchar(5)'), + c.value(N'@long[1]', N'float'), + c.value(N'@lat[1]', N'float') + FROM @x.nodes(N'//state') t(c); +END; +GO + +-- Sign the test procedure with the certificate +ADD SIGNATURE TO LoadStates +BY CERTIFICATE LoadStates_Cert +WITH PASSWORD = N'l0a8p3rm$'; +GO diff --git a/Source-Code/Chapter04/Listing04-42.sql b/Source-Code/Chapter04/Listing04-42.sql new file mode 100644 index 0000000..2b5d76b --- /dev/null +++ b/Source-Code/Chapter04/Listing04-42.sql @@ -0,0 +1,14 @@ +-- Listing 4-42 +-- Create login and user + +CREATE LOGIN Joe +WITH PASSWORD = 'p@$$w0rd'; +GO + +CREATE USER Joe +FOR LOGIN Joe; +GO + +GRANT EXECUTE ON dbo.LoadStates +TO Joe; +GO diff --git a/Source-Code/Chapter04/Listing04-43.sql b/Source-Code/Chapter04/Listing04-43.sql new file mode 100644 index 0000000..731c437 --- /dev/null +++ b/Source-Code/Chapter04/Listing04-43.sql @@ -0,0 +1,12 @@ +-- Listing 4-43 +-- Execute procedure as Joe + +-- Execute as Joe +EXECUTE AS LOGIN = N'Joe'; +GO + +EXEC dbo.LoadStates; +GO + +REVERT; +GO diff --git a/Source-Code/Chapter04/Listing04-44.sql b/Source-Code/Chapter04/Listing04-44.sql new file mode 100644 index 0000000..7f85dcd --- /dev/null +++ b/Source-Code/Chapter04/Listing04-44.sql @@ -0,0 +1,14 @@ +-- Listing 4-44 +-- Verify results of procedure + +SELECT abbreviation, + name, + capital, + flag_graphic, + entry_date, + fact, + capital_address, + zip_code, + longitude, + latitude +FROM dbo.State; diff --git a/Source-Code/Chapter04/Sidebar04-01.sql b/Source-Code/Chapter04/Sidebar04-01.sql new file mode 100644 index 0000000..a71bd11 --- /dev/null +++ b/Source-Code/Chapter04/Sidebar04-01.sql @@ -0,0 +1,5 @@ +-- Sidebar 4-1 +-- Creating asymmetric key directly in SQL Server + +CREATE ASYMMETRIC KEY AsymKey2_Sales +WITH ALGORITHM = RSA_1024; diff --git a/Source-Code/Chapter04/State-List.xml b/Source-Code/Chapter04/State-List.xml new file mode 100644 index 0000000..75c996b --- /dev/null +++ b/Source-Code/Chapter04/State-List.xml @@ -0,0 +1,554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter05/Listing05-01.sql b/Source-Code/Chapter05/Listing05-01.sql new file mode 100644 index 0000000..1e3c23f --- /dev/null +++ b/Source-Code/Chapter05/Listing05-01.sql @@ -0,0 +1,14 @@ +-- Listing 5-1 +-- Enabling EKM functionality in SQL Server + +EXEC sp_configure 'show advanced options', 1; +GO + +RECONFIGURE; +GO + +EXEC sp_configure 'EKM provider enabled', 1; +GO + +RECONFIGURE; +GO diff --git a/Source-Code/Chapter05/Listing05-02.sql b/Source-Code/Chapter05/Listing05-02.sql new file mode 100644 index 0000000..5dc1e55 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-02.sql @@ -0,0 +1,5 @@ +-- Listing 5-2 +-- Registering the Luna SA Ccryptographic Pprovider with SQL Server + +CREATE CRYPTOGRAPHIC PROVIDER LunaEKMProvider +FROM FILE = N'c:\LunaSA\EKM\LunaEKM.dll'; diff --git a/Source-Code/Chapter05/Listing05-03.sql b/Source-Code/Chapter05/Listing05-03.sql new file mode 100644 index 0000000..70e2a74 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-03.sql @@ -0,0 +1,12 @@ +-- Listing 5-3 +-- Creating an EKM Ccredential + +CREATE CREDENTIAL LunaEKMCredential +WITH IDENTITY = 'SQL2008\Michael', -- Replace with your ID +SECRET = 'x9SP-PH9C-L/FK-q/TW' -- Replace with your secret +FOR CRYPTOGRAPHIC PROVIDER LunaEKMProvider; +GO + +ALTER LOGIN [SQL2008\Michael] -- Replace with your login +ADD CREDENTIAL LunaEKMCredential; +GO diff --git a/Source-Code/Chapter05/Listing05-04.sql b/Source-Code/Chapter05/Listing05-04.sql new file mode 100644 index 0000000..5ea92c0 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-04.sql @@ -0,0 +1,30 @@ +-- Listing 5-4 +-- Querying Catalog Views and DMVs to Validate EKM Rregistration + +SELECT provider_id, + name, + guid, + version, + dll_path, + is_enabled +FROM sys.cryptographic_providers; + +SELECT + credential_id, + name, + credential_identity, + create_date, + target_type, + target_id +FROM sys.credentials; + +SELECT + provider_id, + guid, + provider_version, + sqlcrypt_version, + friendly_name, + authentication_type, + symmetric_key_support, + asymmetric_key_support +FROM sys.dm_cryptographic_provider_properties; diff --git a/Source-Code/Chapter05/Listing05-05.sql b/Source-Code/Chapter05/Listing05-05.sql new file mode 100644 index 0000000..59cb1f9 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-05.sql @@ -0,0 +1,8 @@ +-- Listing 5-5 +-- Creating an Asymmetric Key on the HSM + +CREATE ASYMMETRIC KEY Luna_RSA2048_Key +FROM PROVIDER LunaEKMProvider +WITH ALGORITHM = RSA_2048, +PROVIDER_KEY_NAME = 'Luna_RSA2048_Key', +CREATION_DISPOSITION = CREATE_NEW; diff --git a/Source-Code/Chapter05/Listing05-06.sql b/Source-Code/Chapter05/Listing05-06.sql new file mode 100644 index 0000000..3647f73 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-06.sql @@ -0,0 +1,12 @@ +-- Listing 5-6 +-- Verifying Asymmetric Key Creation Success + +SELECT + name, + asymmetric_key_id, + pvt_key_encryption_type_desc, + algorithm_desc, + key_length, + provider_type +FROM sys.asymmetric_keys +WHERE pvt_key_encryption_type = N'CP'; diff --git a/Source-Code/Chapter05/Listing05-07.sql b/Source-Code/Chapter05/Listing05-07.sql new file mode 100644 index 0000000..658d962 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-07.sql @@ -0,0 +1,7 @@ +-- Listing 5-7 +-- Creating a Symmetric Key Protected by an HSM Asymmetric Key + +CREATE SYMMETRIC KEY SymKey_ProtectedByLunaKey +WITH ALGORITHM = AES_256 +ENCRYPTION BY ASYMMETRIC KEY Luna_RSA2048_Key; + diff --git a/Source-Code/Chapter05/Listing05-08.sql b/Source-Code/Chapter05/Listing05-08.sql new file mode 100644 index 0000000..6f182b1 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-08.sql @@ -0,0 +1,19 @@ +-- Listing 5-8 +-- Verifying Symmetric Key Protection by an HSM Asymmetric Key + +SELECT + sk.name AS sym_name, + sk.symmetric_key_id AS sym_id, + sk.key_length AS sym_len, + sk.algorithm_desc AS sym_algo, + ke.crypt_type_desc AS sym_crypt_type, + ak.name AS asym_key_name, + ak.algorithm_desc As asym_algo, + ak.key_length AS asym_len, + ak.provider_type AS asym_key_provider +FROM sys.symmetric_keys sk +INNER JOIN sys.key_encryptions ke + ON sk.symmetric_key_id = ke.key_id +INNER JOIN sys.asymmetric_keys ak + ON ke.thumbprint = ak.thumbprint +WHERE ak.pvt_key_encryption_type = N'CP'; diff --git a/Source-Code/Chapter05/Listing05-09.sql b/Source-Code/Chapter05/Listing05-09.sql new file mode 100644 index 0000000..3477f91 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-09.sql @@ -0,0 +1,14 @@ +-- Listing 5-9 +-- Create a Table to Hold Encrypted Sales Order Detail Information + +CREATE TABLE SalesLT.EncryptedSalesOrderDetail +( + SalesOrderID int not null, + SalesOrderDetailID int not null, + OrderQty varbinary(256) not null, + ProductID varbinary(256) not null, + UnitPrice varbinary(256) not null, + UnitPriceDiscount varbinary(256) not null, + PRIMARY KEY (SalesOrderID, SalesOrderDetailID) +); +GO diff --git a/Source-Code/Chapter05/Listing05-10.sql b/Source-Code/Chapter05/Listing05-10.sql new file mode 100644 index 0000000..7531a83 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-10.sql @@ -0,0 +1,37 @@ +-- Listing 5-10 +-- Encrypting Data with an HSM Asymmetric Key + +INSERT INTO SalesLT.EncryptedSalesOrderDetail +( + SalesOrderID, + SalesOrderDetailID, + OrderQty, + ProductID, + UnitPrice, + UnitPriceDiscount +) +SELECT + SalesOrderID, + SalesOrderDetailID, + EncryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), CAST + ( + OrderQty AS varbinary(10) + ) + ), + EncryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), CAST + ( + ProductID AS varbinary(10) + ) + ), + EncryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), CAST + ( + UnitPrice AS varbinary(40) + ) + ), + EncryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), CAST + ( + UnitPriceDiscount AS varbinary(40) + ) + ) +FROM SalesLT.SalesOrderDetail; +GO diff --git a/Source-Code/Chapter05/Listing05-11.sql b/Source-Code/Chapter05/Listing05-11.sql new file mode 100644 index 0000000..65027bb --- /dev/null +++ b/Source-Code/Chapter05/Listing05-11.sql @@ -0,0 +1,11 @@ +-- Listing 5-11 +-- Querying the Encrypted Sales Order Detail Data + +SELECT + SalesOrderID, + SalesOrderDetailID, + OrderQty, + ProductID, + UnitPrice, + UnitPriceDiscount +FROM SalesLT.EncryptedSalesOrderDetail; diff --git a/Source-Code/Chapter05/Listing05-12.sql b/Source-Code/Chapter05/Listing05-12.sql new file mode 100644 index 0000000..70b815a --- /dev/null +++ b/Source-Code/Chapter05/Listing05-12.sql @@ -0,0 +1,27 @@ +-- Listing 5-12 +-- Decrypting Data with an HSM-enabled Asymmetric Key + +SELECT + SalesOrderID, + SalesOrderDetailID, + CAST + ( + DecryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), + OrderQty) AS smallint + ) AS OrderQty, + CAST + ( + DecryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), + ProductID) AS int + ) AS ProductID, + CAST + ( + DecryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), + UnitPrice) AS money + ) AS UnitPrice, + CAST + ( + DecryptByAsymKey(AsymKey_ID(N'Luna_RSA2048_Key'), + UnitPriceDiscount) AS money + ) AS UnitPriceDiscount +FROM SalesLT.EncryptedSalesOrderDetail; diff --git a/Source-Code/Chapter05/Listing05-13.sql b/Source-Code/Chapter05/Listing05-13.sql new file mode 100644 index 0000000..01fee58 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-13.sql @@ -0,0 +1,8 @@ +-- Listing 5-13 +-- Creating a Symmetric Key on the HSM + +CREATE SYMMETRIC KEY Luna_AES256_Key +FROM PROVIDER LunaEKMProvider +WITH PROVIDER_KEY_NAME='Luna_AES256_Key', +CREATION_DISPOSITION = CREATE_NEW, +ALGORITHM = AES_256; diff --git a/Source-Code/Chapter05/Listing05-14.sql b/Source-Code/Chapter05/Listing05-14.sql new file mode 100644 index 0000000..a3abf2f --- /dev/null +++ b/Source-Code/Chapter05/Listing05-14.sql @@ -0,0 +1,12 @@ +-- Listing 5-14 +-- Querying sys.symmetric_keys to Verify Key Creation + +SELECT + name, + symmetric_key_id, + key_length, + algorithm_desc, + provider_type +FROM sys.symmetric_keys +WHERE provider_type = N'CRYPTOGRAPHIC PROVIDER'; + diff --git a/Source-Code/Chapter05/Listing05-15.sql b/Source-Code/Chapter05/Listing05-15.sql new file mode 100644 index 0000000..0aafd4e --- /dev/null +++ b/Source-Code/Chapter05/Listing05-15.sql @@ -0,0 +1,12 @@ +-- Listing 5-15 +-- Creating Table to Hold Encrypted Product Price Information + +CREATE TABLE SalesLT.EncryptedProduct +( + ProductID int not null primary key, + Name nvarchar(50), + StandardCost varbinary(80), + ListPrice varbinary(80) +); +GO + diff --git a/Source-Code/Chapter05/Listing05-16.sql b/Source-Code/Chapter05/Listing05-16.sql new file mode 100644 index 0000000..8003d05 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-16.sql @@ -0,0 +1,34 @@ +-- Listing 5-16 +-- Encrypting Data with an HSM Symmetric Key + +INSERT INTO SalesLT.EncryptedProduct +( + ProductID, + Name, + StandardCost, + ListPrice +) +SELECT + ProductID, + Name, + EncryptByKey(Key_GUID(N'Luna_AES256_Key'), + CAST + ( + StandardCost AS varbinary(40) + ) + ), + EncryptByKey(Key_GUID(N'Luna_AES256_Key'), + CAST + ( + ListPrice AS varbinary(40) + ) + ) +FROM SalesLT.Product; +GO + +SELECT + ProductID, + Name, + StandardCost, + ListPrice +FROM SalesLT.EncryptedProduct; diff --git a/Source-Code/Chapter05/Listing05-17.sql b/Source-Code/Chapter05/Listing05-17.sql new file mode 100644 index 0000000..a57fb13 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-17.sql @@ -0,0 +1,9 @@ +-- Listing 5-17 +-- Decrypting Data with an HSM Symmetric Key + +SELECT + ProductID, + Name, + CAST(DecryptByKey(StandardCost) AS money) AS StandardCost, + CAST(DecryptByKey(ListPrice) AS money) AS ListPrice +FROM SalesLT.EncryptedProduct; diff --git a/Source-Code/Chapter05/Listing05-18.sql b/Source-Code/Chapter05/Listing05-18.sql new file mode 100644 index 0000000..1638f79 --- /dev/null +++ b/Source-Code/Chapter05/Listing05-18.sql @@ -0,0 +1,9 @@ +-- Listing 5-18 +-- Querying the list of cryptographic provider algorithms + +SELECT + algorithm_id, + algorithm_tag, + key_type, + key_length +FROM sys.dm_cryptographic_provider_algorithms (65535); diff --git a/Source-Code/Chapter06/Listing06-01.sql b/Source-Code/Chapter06/Listing06-01.sql new file mode 100644 index 0000000..d5c624f --- /dev/null +++ b/Source-Code/Chapter06/Listing06-01.sql @@ -0,0 +1,9 @@ +-- Listing 6-1 +-- Create DMK in the Mmaster Ddatabase + +USE master; +GO + +CREATE MASTER KEY +ENCRYPTION BY PASSWORD = N'm*1u~p0a92+'; +GO diff --git a/Source-Code/Chapter06/Listing06-02.sql b/Source-Code/Chapter06/Listing06-02.sql new file mode 100644 index 0000000..b258176 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-02.sql @@ -0,0 +1,9 @@ +-- Listing 6-2 +-- Create a Server Certificate + +USE master; +GO + +CREATE CERTIFICATE TDE_Certificate +WITH SUBJECT = N'TDE Encryption Server Certificate'; +GO diff --git a/Source-Code/Chapter06/Listing06-03.sql b/Source-Code/Chapter06/Listing06-03.sql new file mode 100644 index 0000000..3881e65 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-03.sql @@ -0,0 +1,14 @@ +-- Listing 6-3 +-- Backing Up the Server Certificate + +USE master; +GO + +BACKUP CERTIFICATE TDE_Certificate +TO FILE = N'c:\Server_Certificate.cer' +WITH PRIVATE KEY +( + FILE = N'c:\Server_Certificate.pvk', + ENCRYPTION BY PASSWORD = N'$$um)3l0q:' +); +GO diff --git a/Source-Code/Chapter06/Listing06-04.sql b/Source-Code/Chapter06/Listing06-04.sql new file mode 100644 index 0000000..76d5565 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-04.sql @@ -0,0 +1,11 @@ +-- Listing 6-4 +-- Create a Database Encryption Key + +USE AdventureWorksLT2008; +GO + +CREATE DATABASE ENCRYPTION KEY +WITH ALGORITHM = AES_256 +ENCRYPTION BY SERVER CERTIFICATE TDE_Certificate; +GO + diff --git a/Source-Code/Chapter06/Listing06-05.sql b/Source-Code/Chapter06/Listing06-05.sql new file mode 100644 index 0000000..bb29cb2 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-05.sql @@ -0,0 +1,10 @@ +-- Listing 6-5 +-- Turning on TDE + +USE AdventureWorksLT2008; +GO + +ALTER DATABASE AdventureWorksLT2008 +SET ENCRYPTION ON; +GO + diff --git a/Source-Code/Chapter06/Listing06-06.sql b/Source-Code/Chapter06/Listing06-06.sql new file mode 100644 index 0000000..47e3ef4 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-06.sql @@ -0,0 +1,14 @@ +-- Listing 6-6 +-- Using DEK with EKM + +USE master; +GO + +CREATE ASYMMETRIC KEY TDE_Luna_AsymKey +FROM PROVIDER LunaEKMProvider +WITH ALGORITHM = RSA_2048, +PROVIDER_KEY_NAME = N'TDE_Luna_AsymKey', +CREATION_DISPOSITION = CREATE_NEW; +GO + + diff --git a/Source-Code/Chapter06/Listing06-07.sql b/Source-Code/Chapter06/Listing06-07.sql new file mode 100644 index 0000000..47d5bda --- /dev/null +++ b/Source-Code/Chapter06/Listing06-07.sql @@ -0,0 +1,17 @@ +-- Listing 6-7 +-- Creating a Credential and a Login for the EKM + +CREATE CREDENTIAL TDE_Luna_Credential +WITH IDENTITY = 'SQL2008\Michael', -- Replace with your ID +SECRET = 'x9SP-PH9C-L/FK-q/TW' -- Replace with your secret +FOR CRYPTOGRAPHIC PROVIDER LunaEKMProvider; +GO + +CREATE LOGIN TDE_Luna_Login +FROM ASYMMETRIC KEY TDE_Luna_AsymKey; +GO + +ALTER LOGIN TDE_Luna_Login +ADD CREDENTIAL TDE_Luna_Credential; +GO + diff --git a/Source-Code/Chapter06/Listing06-08.sql b/Source-Code/Chapter06/Listing06-08.sql new file mode 100644 index 0000000..020ea5a --- /dev/null +++ b/Source-Code/Chapter06/Listing06-08.sql @@ -0,0 +1,13 @@ +-- Listing 6-8 +-- Creating a DEK and Turning on TDE + +USE AdventureWorksLT2008; +GO + +CREATE DATABASE ENCRYPTION KEY +WITH ALGORITHM = AES_256 +ENCRYPTION BY SERVER ASYMMETRIC KEY TDE_Luna_AsymKey; +GO + +ALTER DATABASE AdventureWorksLT2008 +SET ENCRYPTION ON; diff --git a/Source-Code/Chapter06/Listing06-09.sql b/Source-Code/Chapter06/Listing06-09.sql new file mode 100644 index 0000000..5d9c962 --- /dev/null +++ b/Source-Code/Chapter06/Listing06-09.sql @@ -0,0 +1,18 @@ +-- Listing 6-9 +-- Listing Encrypted Databases + +SELECT + DB_NAME(database_id) AS database_name, + database_id, + CASE encryption_state + WHEN 0 THEN N'No database encryption key present, no encryption' + WHEN 1 THEN N'Unencrypted' + WHEN 2 THEN N'Encryption in progress' + WHEN 3 THEN N'Encrypted' + WHEN 4 THEN N'Key change in progress' + WHEN 5 THEN N'Decryption in progress' + END AS encryption_state, + key_algorithm, + key_length, + percent_complete +FROM sys.dm_database_encryption_keys; diff --git a/Source-Code/Chapter07/Listing07-01.sql b/Source-Code/Chapter07/Listing07-01.sql new file mode 100644 index 0000000..99665a5 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-01.sql @@ -0,0 +1,4 @@ +-- Listing 7-1 +-- Generating an SHA-1 Hash of a Name in SQL Server + +SELECT HashBytes('SHA1', 'Galileo Galilei'); diff --git a/Source-Code/Chapter07/Listing07-02.sql b/Source-Code/Chapter07/Listing07-02.sql new file mode 100644 index 0000000..e8f9e21 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-02.sql @@ -0,0 +1,5 @@ +-- Listing 7-2 +-- SHA-1 Hash of a Slightly Modified Name + +SELECT HashBytes('SHA1', 'Galileo Galilei IV'); + diff --git a/Source-Code/Chapter07/Listing07-03.sql b/Source-Code/Chapter07/Listing07-03.sql new file mode 100644 index 0000000..e9938e5 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-03.sql @@ -0,0 +1,12 @@ +-- Listing 7-3 +-- Hashing the Same String As varchar and nvarchar + +SELECT + 'varchar' AS Type, + HashBytes('SHA1', 'Albert Einstein') AS HashValue + +UNION ALL + +SELECT + 'nvarchar', + HashBytes('SHA1', N'Albert Einstein'); diff --git a/Source-Code/Chapter07/Listing07-04.sql b/Source-Code/Chapter07/Listing07-04.sql new file mode 100644 index 0000000..48911a9 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-04.sql @@ -0,0 +1,14 @@ +-- Listing 7-4 +-- Comparing SHA-1 Hashes of an 8,000 Byte String and a 9,000 Byte String + +DECLARE + @string8000 varchar(max) = REPLICATE('A', 8000), + @string9000 varchar(max) = REPLICATE('A', 8000) + REPLICATE('Z', 1000); + +SELECT + '8,000 bytes' AS Length, + HashBytes('SHA1', @string8000) AS HashValue +UNION ALL +SELECT + '9,000 bytes', + HashBytes('SHA1', @string9000); diff --git a/Source-Code/Chapter07/Listing07-05.sql b/Source-Code/Chapter07/Listing07-05.sql new file mode 100644 index 0000000..0f4db54 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-05.sql @@ -0,0 +1,26 @@ +-- Listing 7-5 +-- User-Defined Function to Generate an Extended SHA-1 Hash + +CREATE FUNCTION dbo.Sha1ExtendedHash (@input varchar(max)) +RETURNS varbinary(20) +AS +BEGIN + DECLARE + @hashRegister1 varbinary(20) = NULL, + @hashRegister2 varbinary(40) = NULL, + @i int = 1; + + SELECT @hashRegister1 = HashBytes('SHA1', SUBSTRING(@input, @i, 8000)); + SET @i = @i + 8000; + + WHILE @i < DATALENGTH(@input) + BEGIN + SET @hashRegister2 = @hashRegister1 + + HashBytes ('SHA1', SUBSTRING(@input, @i, 8000)); + SET @hashRegister1 = HashBytes('SHA1', @hashRegister2); + SET @i = @i + 8000; + END; + + RETURN @hashRegister1; +END; +GO diff --git a/Source-Code/Chapter07/Listing07-06.sql b/Source-Code/Chapter07/Listing07-06.sql new file mode 100644 index 0000000..33b0175 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-06.sql @@ -0,0 +1,22 @@ +-- Listing 7-6 +-- Testing the Extended Hash Function + +DECLARE + @string8000 varchar(max) = CAST(REPLICATE('A', 8000) AS varchar(max)), + @string9000 varchar(max) = CAST(REPLICATE('A', 8000) AS varchar(max)) + REPLICATE('Z', 1000); + +SELECT + '8,000 bytes, normal' AS Length, + HashBytes('SHA1', @string8000) AS HashValue + +UNION ALL + +SELECT + '8,000 bytes, extended', + dbo.Sha1ExtendedHash(@string8000) + +UNION ALL + +SELECT + '9,000 bytes, extended', + dbo.Sha1ExtendedHash(@string9000); diff --git a/Source-Code/Chapter07/Listing07-07.sql b/Source-Code/Chapter07/Listing07-07.sql new file mode 100644 index 0000000..fcc40e5 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-07.sql @@ -0,0 +1,36 @@ +-- Listing 7-7 +-- MD5 Hashing of Rows in a Table + +SELECT + AddressID, + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode, + HashBytes + ( + 'MD5', + COALESCE(AddressLine1, 0x00) + '|' + + COALESCE(AddressLine2, 0x00) + '|' + + COALESCE(City, 0x00) + '|' + + COALESCE(StateProvince, 0x00) + '|' + + COALESCE(CountryRegion, 0x00) + '|' + + COALESCE(PostalCode, 0x00) + '|' + ) AS AddressHash +INTO SalesLT.AddressHash +FROM SalesLT.Address; +GO + +SELECT + AddressID, + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode, + AddressHash +FROM SalesLT.AddressHash; +GO diff --git a/Source-Code/Chapter07/Listing07-08.sql b/Source-Code/Chapter07/Listing07-08.sql new file mode 100644 index 0000000..f5de621 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-08.sql @@ -0,0 +1,15 @@ +-- Listing 7-8 +-- Generating Checksum Hash Values for a Table + +SELECT + AddressID, + CHECKSUM + ( + AddressLine1, + AddressLine2, + City, + StateProvince, + CountryRegion, + PostalCode + ) AS AddressChecksums +FROM SalesLT.Address; diff --git a/Source-Code/Chapter07/Listing07-09.sql b/Source-Code/Chapter07/Listing07-09.sql new file mode 100644 index 0000000..62132e4 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-09.sql @@ -0,0 +1,12 @@ +-- Listing 7-9 +-- CHECKSUM Function 16-Character Cycle + +SELECT + 'LE' AS String, + CHECKSUM('LE') AS CheckSumHash + +UNION ALL + +SELECT + 'AAAAAAAAAAAAAAAALE', + CHECKSUM('AAAAAAAAAAAAAAAALE'); diff --git a/Source-Code/Chapter07/Listing07-10.sql b/Source-Code/Chapter07/Listing07-10.sql new file mode 100644 index 0000000..f2d2624 --- /dev/null +++ b/Source-Code/Chapter07/Listing07-10.sql @@ -0,0 +1,12 @@ +-- Listing 7-10 +-- Two-Character Collisions with CHECKSUM + +SELECT + 'LE' AS String, + CHECKSUM('LE') AS CheckSumHash + +UNION ALL + +SELECT + 'MU', + CHECKSUM('MU'); diff --git a/Source-Code/Chapter07/Listing07-11.sql b/Source-Code/Chapter07/Listing07-11.sql new file mode 100644 index 0000000..c6f6a4e --- /dev/null +++ b/Source-Code/Chapter07/Listing07-11.sql @@ -0,0 +1,24 @@ +-- Listing 7-11 +-- BINARY_CHECKSUM Collisions + +SELECT + 'LE' AS String, + BINARY_CHECKSUM('LE') AS CheckSumHash + +UNION ALL + +SELECT + 'MU', + BINARY_CHECKSUM('MU') + +UNION ALL + +SELECT + 'Ne', + BINARY_CHECKSUM('Ne') + +UNION ALL + +SELECT + 'Ou', + BINARY_CHECKSUM('Ou'); diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.sln b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.sln new file mode 100644 index 0000000..96760e3 --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DecryptAesByPassPhrase", "DecryptAesByPassPhrase\DecryptAesByPassPhrase.csproj", "{64F9CD45-22C7-4F80-9090-6F4E80E9672A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Release|Any CPU.Build.0 = Release|Any CPU + {64F9CD45-22C7-4F80-9090-6F4E80E9672A}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.suo b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase.suo new file mode 100644 index 0000000000000000000000000000000000000000..0e3d969b38fe16556b4856d8ecb8acaada9478a0 GIT binary patch literal 9728 zcmeI2OKenC7{^bmAc%@o1RsbaB0jLSk14dgr^7TDOQ^OM7d56#9|~=!cBWV&x^|&a z6XRo{iHR7a#>f(bCbDp0Vjw2EFfMTC%E!u;t-t>{_p~$9J2Q8XheXcJchBp)=R4;+ z-|L*2GpARaegF7vznG%5!(3%%W|x}9dF?fn1vcGiOf3b~XJ%(-U86A+ucXU}1AjBu ztAjmUM6Uh523P_t1+E9K1(pHV0n33K0Jh((0JQglE9vs&z+)!ElQS`sGUMcv<_NnQ zJ*_f}=5$_iQ!ah}?8&pQ4}Dv66-c`zK%{OcX3RnJFw}=BrOdSJi1=QG70Ty)#Luk! z3b)q`n5;Quy38}=IrBL0A?D=UvlRwhZ)$5+gCl*>JSw2uZrM!XEA>Kcz>Jwr);dUwY|zFxOG0AiMoh(C_tEd*bbYZ_^xo+3UaT zf%IQ?z}tX2$~OVRy*bFmlUsmWf!l!Ffi=J#z*^u=z>mF-^4-9C;2vNDa4&Ela6j+> zun~9=s0SK=hk!;vV>AbOoV+zCZzgX8+Jm~MrF;i%JAqw6pXc5GF|T{-$9KL;Z0q{) z%agq~A2{&_EU7B}k(8G>_jIhzMHI6$8bgxNWi>Kq_L&Lff81)w808F-KL9*~^dF&j zm}ivQI9R)_)(lt));KGH{q~DPX!N*A7wFC?UkonzMiMR?IB3W2v9{3ZrbfI_$*um} zN7wfUfFzcnf6jVkDer|hY4bFk8G=v!tar#-x*WWi2^$y+|FXZb z%TejePmcpi^7j+aNZ9puQ0stAqaU0k?=<7* z$g|{Wa${b;$TN_yAI19*Tl#(;zJ4+0Q!Iaqzod7P2^WQw*Mbc}{3S0CRsMwQ?n`+a0DWtJbVi9vU$~tzSftYQkFYPYNb|9l`=ape*Du;ig}vdmeEU~S ze=ocrgR1m$f53~3c@7y3PY(wCchsZNm+k2dhAY&FaCvmCmtH?48EN)I`drQ?g>$NO zYaj{*2>+(7V4w<>#iphPlwTEp6DV(7^lB~QIXnAi?c7yM+mov$u{Oo}RTfHNiq$@k zNsMDC+c9msDYX(RH}fRTW=iU5!}QhD-)Ny8{7w^>zUScPB)pZyoVT?8WHtoPa}1*s zi7*R2lFlEJJ;nOU3#S!cE0q5X<4+;;ZsdHK?}nyMKjkb@BlL9^5&xpnm%q-;>3?bZ z{w(OD%dpinoP++w7)WO!CD}Piv|pp+^DwI(vG#BNH0bb)-{^mhB3GTsqOSigaDTP} zMwp;x)W-F61EbN?2Rj8;o;0vC!QQkaV zog8z}nWriX5k5C(-GsZu-aDMnxou@r&i86{GE*e%;_{?4LHs6h6RYz57oUmgi?6~cgZo8%5X5F@EZRTmF ztsOf0qRAS8Ch}IE&d5|1B_xmp`If`%QxfSIvGTCQ-rtp%rLACAPCaJ*vcD4>U-^2^ z@t;0Eebcf1%e%~(FaCVurFAD#pKkdf{q|qey7D9Sn6}}Sr)EyA?fT%|!Oz}W`+IvS zOot!s{b*_Z3PZkOXDZ#^B(P}{NQiWM0C(0!+>oZEn;qRD=iiXY z9u!7za)8p*c?aju`}@$|gII8#wTolCKIFer;{K&Zcf7h&i5h=2f!h}hoMZ*g!Rp*T zge@4>caBOwKmPQ5QXD+NTy*kM$l$z%;@$E|^mPxe`-`abTfluU7*@BF zqB>yDG=mHFEkG-oiT|SOQ%S_Uj{NoSf$M{o_Bd-EWj6XHLVm*qPI;e&7IpvTX)6y! zDr(H9zmG^kcOW|32}bfbznhlHqHl|<@V{#Mih{lm2I^q783Nidc3_e`>c0DVtbzZE zn>-JEd%1iIo%(G<$^Xvee}C#B%#;kugNrkz&i(Fd{bo}A`eoVu{Y$C)zHn<1j_pF$ zYOJ20z2;xM1G?ku!vi1D HmjnL*Zk4?& literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.cs b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.cs new file mode 100644 index 0000000..10a3fd5 --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.cs @@ -0,0 +1,96 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using Microsoft.SqlServer.Server; +using System.Security.Cryptography; +using System.Text; +using System.IO; + +namespace Apress.Samples +{ + public partial class CustomEncryption + { + [Microsoft.SqlServer.Server.SqlFunction + ( + IsDeterministic = true, + DataAccess = DataAccessKind.None + )] + [return: SqlFacet(MaxSize = -1)] + public static SqlBytes DecryptAesByPassPhrase + ( + SqlString PassPhrase, + [SqlFacet(MaxSize = -1)] SqlBytes Ciphertext, + SqlBoolean AddAuthenticator, + SqlString Authenticator + ) + { + try + { + // Automatically return NULL if passphrase or plaintext is NULL + if (PassPhrase.IsNull || Ciphertext.IsNull) + return SqlBytes.Null; + + // Get the ciphertext into a byte array + byte[] rawData = Ciphertext.Value; + + // Get the 16-byte salt from the byte array + byte[] Salt = new byte[16]; + for (int i = 0; i < 16; i++) + Salt[i] = rawData[i]; + + // Generate hash for authenticator + SHA1Managed Sha1 = new SHA1Managed(); + string AuthHash = ""; // If no authenticator, use empty string + // Convert the authenticator hash to Base64 to avoid conversion problems + if (AddAuthenticator.IsTrue && !Authenticator.IsNull) + AuthHash = Convert.ToBase64String + ( + Sha1.ComputeHash(Encoding.Unicode.GetBytes(Authenticator.Value)) + ); + // Append authenticator to passphrase + string AuthPass = PassPhrase.Value + AuthHash; + + // Next derive a key from the passphrase + authenticator, with 16-bit Salt + Rfc2898DeriveBytes keyGenerator = new Rfc2898DeriveBytes(AuthPass, Salt); + + // Create a Rijndael/AES encryption object + Rijndael Aes = Rijndael.Create(); + Aes.KeySize = 256; + Aes.Mode = CipherMode.CBC; + Aes.IV = keyGenerator.GetBytes(Aes.BlockSize >> 3); // Assign the IV + Aes.Key = keyGenerator.GetBytes(Aes.KeySize >> 3); // Assign the key + + // Wrap a CryptoStream in a MemoryStream to decrypt the data + using (MemoryStream memoryStream = new MemoryStream()) + { + using + ( + CryptoStream cryptoStream = new CryptoStream + ( + memoryStream, + Aes.CreateDecryptor(), + CryptoStreamMode.Write + ) + ) + { + // Decrypt and write out the decrypted data with the CryptoStream + // ...ignore the leading 16 bytes, the Salt + cryptoStream.Write(rawData, 16, rawData.Length - 16); + cryptoStream.Close(); + + // Put the decrypted MemoryStream in a byte array and return as SqlBytes + byte[] decrypted = memoryStream.ToArray(); + return new SqlBytes(decrypted); + } + } + } + catch + { + // If there's an exception return NULL + return SqlBytes.Null; + } + } + } +} + diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj new file mode 100644 index 0000000..4a2ef36 --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + {c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 9.0.30729 + 2.0 + {64F9CD45-22C7-4F80-9090-6F4E80E9672A} + Library + false + DecryptAesByPassPhrase + 512 + DecryptAesByPassPhrase + + + true + full + false + bin\Debug\ + false + DEBUG;TRACE + 4 + + + false + true + bin\Release\ + false + TRACE + 4 + + + + + + + + + + + + + + + Content + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj.user b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj.user new file mode 100644 index 0000000..4611ad5 --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/DecryptAesByPassPhrase.csproj.user @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Properties/AssemblyInfo.cs b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7fa04e9 --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Data.Sql; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DecryptAesByPassPhrase")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("DecryptAesByPassPhrase")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] + diff --git a/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Test Scripts/Test.sql b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Test Scripts/Test.sql new file mode 100644 index 0000000..56e659f --- /dev/null +++ b/Source-Code/Chapter08/DecryptAesByPassPhrase/DecryptAesByPassPhrase/Test Scripts/Test.sql @@ -0,0 +1,35 @@ +-- Examples for queries that exercise different SQL objects implemented by this assembly + +----------------------------------------------------------------------------------------- +-- Stored procedure +----------------------------------------------------------------------------------------- +-- exec StoredProcedureName + + +----------------------------------------------------------------------------------------- +-- User defined function +----------------------------------------------------------------------------------------- +-- select dbo.FunctionName() + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- CREATE TABLE test_table (col1 UserType) +-- go +-- +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 1')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 2')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 3')) +-- +-- select col1::method1() from test_table + + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- select dbo.AggregateName(Column1) from Table1 + + +select 'To run your project, please edit the Test.sql file in your project. This file is located in the Test Scripts folder in the Solution Explorer.' diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.sln b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.sln new file mode 100644 index 0000000..8185301 --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncryptAesByPassPhrase", "EncryptAesByPassPhrase\EncryptAesByPassPhrase.csproj", "{B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Release|Any CPU.Build.0 = Release|Any CPU + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.suo b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase.suo new file mode 100644 index 0000000000000000000000000000000000000000..3f9171e3e5bf638f765ce08f142fed9f14812503 GIT binary patch literal 9728 zcmeI2OKj9d9LHy?ynLa6_{J3xQE1&hDQ~*VHW*8&wiaS)u-!gX+HTX`Dnu|IJ!sU# zL_J7iBF3mO;U-2+46j%ma3tR&O)#?Un$MI-!_0Pn!p!K13;Lj<}AH-_=;5e9ng)X60A7 z-KNiE%wf}Eo+8hhNBIu2Cf}Z^GT}N?6S)Z->5JA;1>JVbW(r@a8)|)K)U>nrNq8_o zEz4TclzZ$-GC?h2+jK%{GvWsG-3oo_rRPDeqe4M;`~9Hb>#xql+X3IEHTtsGf7t`+ zzwCgw0V^o41cZBIkc%fb1GfOT0=EIT19t#xfI9&{_gcz#1M7f$fc3z=zy{zx;C^5u zunDLI>VOA;7@#>Cg1m{mIVf)?Zw0mlbx%wAPTF<>yMsQ@yZ>Xp;?ViGzG&Ot@!sd3 zb>G;3`gK?`r}TS5USj^~9AzUvZ9XosziH zkL4ZaC%Ol$B#Ce0R`nEx{%X)fTdDd87h_36m5S-dS%akRu$6d8cedg>Ho$+`U)klb z^yR0=044eRacH#J{l=+vLOsK;6COz8hK!9;3W8_m_JLN zAy1JT^U^=O0{Qw8y#J7;@7Lk$|HOKVt9`{g&I*>9$o9duOE_(6z3s*u4I!+bEKV)<_QAfTFhO{)MG4bX-i^6_fTr3H%5OgxD95H^gRnVC*Z9t=8UEFH?u)_ zo@Ib;B*HB8NVzscS2LQpGuY}27TQ{#J{lg<*(B@ z{Vz}7-vxbiS!z#p^U%L26X`CbBs(XG_Iq@E9%9$S*8a`h1|5F!7yXYYa@CzI?Edcp z_eU#m6k3pi%^Z6YiD^S(;^w$HhMTOzAv;Zazc9}dfe!E>BP3yQZH z?UhbTk7JyZ%F^g|`dX|;D;!c=jJ%2SY&DIPn<=;0(Z@OG`i91)<`xQt3H#$L5Y6(- z(&KMFY+CW#)UTm*S#kG17(HSoSkad5Xo|VUb8kDw?6CT2%r=%}*x0;G6`PqYs&)8+ zXKj=>LsvJ)EOch5%0iT0o3n1hU25MQ7IJOdIFyCnt!`$Dgk4;I3<_fiX%tcDIAa>--){5X3LBMFYGlqrsa#4va= zd$qX6IIMS*vTi(J~s}lW2tI7?u;Hnv+dMq?m#kp-rf_%#}$V>w17`F1T)V|+UmZfcAR!?1K z-PIS`HopAj-cvt(aCYU%1Is(ixljK%_~P2r$&a>vmwNNhBYN^9b(z+oRcEHotm%07 z?SYTqSo7PKa+nT3-1p(AF|V@6OUc~l{gtfhCKQHz#mQ8Ay=lXyjUxln?LORD2XRA+ zl3sT7hMfOGCVNmAy~zQVcE0;@a!+Hyb=NMA@p_Q9YKixkh~9YhrV=*(s0X(vm^i@> zoP*W9eGpq-yovy^Oy=L8^zIy%et!Jv`J^~_oVDoYrI5jS3&p#Ylj!RmT<;fQ={JIV zBA8aMlcL&Z?=%Cm&MiPIn~DFT>r+|8ypH_+?}h6Fmi8EX9$_{5ON9J}3!L(Xl`QK0 z&C^z15~-*$pZ$n~MN2qun`1VTqRysEX2>$O({_js+gqe~-d2n&2+`Zq=KcD@}vilokx%a-()}l1F z3t8u4_5AAfH=p7Y&>LTmjRETM>AJvHN(ax%%gsL}6J4G2A8pK;5VreLzBIKHAtd3l z9taXP64BM69xI^eL@`dIIh3i>2a?%$0o>A(K2S1s}W9?}0StOCN) t-vRFVY7@_)-|K!@`g52%6zbohFZ;6Og-;&y{_Ee`L#T~jMp|$V`~}JHzjput literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.cs b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.cs new file mode 100644 index 0000000..2559fbe --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.cs @@ -0,0 +1,98 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using Microsoft.SqlServer.Server; +using System.Security.Cryptography; +using System.Text; +using System.IO; + +namespace Apress.Samples +{ + public partial class SqlEncryption + { + [Microsoft.SqlServer.Server.SqlFunction + ( + IsDeterministic = false, + DataAccess = DataAccessKind.None + )] + [return: SqlFacet(MaxSize = -1)] + public static SqlBytes EncryptAesByPassPhrase + ( + SqlString PassPhrase, + [SqlFacet(MaxSize = -1)] SqlBytes Plaintext, + SqlBoolean AddAuthenticator, + SqlString Authenticator + ) + { + try + { + // Automatically return NULL if passphrase or plaintext is NULL + if (PassPhrase.IsNull || Plaintext.IsNull) + return SqlBytes.Null; + + // Generate hash for authenticator + SHA1Managed Sha1 = new SHA1Managed(); + string AuthHash = ""; // If authenticator not used, use empty string + // Convert the authenticator hash to Base64 to avoid conversion problems + if (AddAuthenticator.IsTrue && !Authenticator.IsNull) + AuthHash = Convert.ToBase64String + ( + Sha1.ComputeHash + ( + Encoding.Unicode.GetBytes(Authenticator.Value) + ) + ); + // Append authenticator to passphrase + string AuthPass = PassPhrase.Value + AuthHash; + + // Next derive a key from the passphrase + authenticator + // with random 16 byte Salt + Rfc2898DeriveBytes KeyGenerator = new Rfc2898DeriveBytes(AuthPass, 16); + + // Create a Rijndael/AES encryption object + Rijndael Aes = Rijndael.Create(); + Aes.KeySize = 256; + Aes.Mode = CipherMode.CBC; + Aes.IV = KeyGenerator.GetBytes(Aes.BlockSize >> 3); // Assign the IV + Aes.Key = KeyGenerator.GetBytes(Aes.KeySize >> 3); // Assign the Key + + // Now get the raw plain text + byte[] rawData = Plaintext.Value; + + // Use a MemoryStream wrapping a CryptoStream with a Rijndael encryptor + // to encrypt the data + using (MemoryStream memoryStream = new MemoryStream()) + { + using + ( + CryptoStream cryptoStream = new CryptoStream + ( + memoryStream, + Aes.CreateEncryptor(), + CryptoStreamMode.Write + ) + ) + { + // First write out the 16 byte salt so we can regenerate the same + // key next time + memoryStream.Write(KeyGenerator.Salt, 0, 16); + // Now write out the encrypted data + cryptoStream.Write(rawData, 0, rawData.Length); + cryptoStream.Close(); + + // Convert the encrypted data in memory to an array and return + // as a SqlBytes object + byte[] encrypted = memoryStream.ToArray(); + return new SqlBytes(encrypted); + } + } + } + catch + { + // Return NULL if an encryption error occurs + return SqlBytes.Null; + } + } + } +} diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj new file mode 100644 index 0000000..c1d5b75 --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + {c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 9.0.30729 + 2.0 + {B7264AC5-9018-4EFD-8A0C-22D627FE5A9B} + Library + false + EncryptAesByPassPhrase + 512 + EncryptAesByPassPhrase + + + true + full + false + bin\Debug\ + false + DEBUG;TRACE + 4 + + + false + true + bin\Release\ + false + TRACE + 4 + + + + + + + + + + + + + + + Content + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj.user b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj.user new file mode 100644 index 0000000..721ad0a --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/EncryptAesByPassPhrase.csproj.user @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Properties/AssemblyInfo.cs b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..58d8928 --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Data.Sql; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("EncryptAesByPassPhrase")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("EncryptAesByPassPhrase")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] + diff --git a/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Test Scripts/Test.sql b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Test Scripts/Test.sql new file mode 100644 index 0000000..56e659f --- /dev/null +++ b/Source-Code/Chapter08/EncryptAesByPassPhrase/EncryptAesByPassPhrase/Test Scripts/Test.sql @@ -0,0 +1,35 @@ +-- Examples for queries that exercise different SQL objects implemented by this assembly + +----------------------------------------------------------------------------------------- +-- Stored procedure +----------------------------------------------------------------------------------------- +-- exec StoredProcedureName + + +----------------------------------------------------------------------------------------- +-- User defined function +----------------------------------------------------------------------------------------- +-- select dbo.FunctionName() + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- CREATE TABLE test_table (col1 UserType) +-- go +-- +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 1')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 2')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 3')) +-- +-- select col1::method1() from test_table + + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- select dbo.AggregateName(Column1) from Table1 + + +select 'To run your project, please edit the Test.sql file in your project. This file is located in the Test Scripts folder in the Solution Explorer.' diff --git a/Source-Code/Chapter08/GetHash/GetHash.sln b/Source-Code/Chapter08/GetHash/GetHash.sln new file mode 100644 index 0000000..365b10a --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetHash", "GetHash\GetHash.csproj", "{C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Release|Any CPU.Build.0 = Release|Any CPU + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source-Code/Chapter08/GetHash/GetHash.suo b/Source-Code/Chapter08/GetHash/GetHash.suo new file mode 100644 index 0000000000000000000000000000000000000000..2bb89badee62d84915e19246273cb9f9412f9a5b GIT binary patch literal 9216 zcmeI1OKg-?6vyv?D2R$Y6+|4dA_}e3CsXj%PFo?CP-$(6sUf8=pwma%DU<-lr7;>4 zV|*-Jn20fAOjsF=n#j_`z(yC!LU*o2SFULN{qOhP&a3my*P%j)oXPp_`<{ExJ+FJ` z(#4g(eSB`i? zq&n|Az@^|a@GkI9a5;E4cn`?Yn-!qWU3d#_UJmRxqx@1PYMRXm>9{$;$%cn@X34D1 zOKyVTxyxs#-s%4#vY1YrxO}ANpCRUozRz#Iv&h61Y~5lKl9t24(m*u9dLD8qsvSGMaS6y>A&p2 zN^ljp8dTr4ekz{a53UC{fDeEhK{ww+-)Vg}fvr{}Q)ZtTL;gpsh76M*Me=*VBS`-VS_k+gDUHyp$!blHm0-=Y2JEsU zhS2B{)0?F`Nk;VLjgf@Q2KL#x+pR71bW=0_SK#fw^w~AO2~1!Kx@WD|1o^%2rq>*X zGyU+Xn_m6a(xu?V80F_Fr%XG2dVMQ=j1hg*j+^~_2h9t7i+KatKS`8qiqbGUkzTrf zovf*Y70IR@;ycBPv;wWAms~N}jQyAGksS(4UvZ9Xoj_bUgykLNC%Ro$lEgQ0t2jiV zzm9IAEhs+1i?Jl3f?WEItU*#YWF=nGoeEsXR`@UbE4v()zWj6>DA*0H33l7<73ckR ze4O{doB^8WRnU`TFDe*>7xIl!yrZ;UClbXgOqsZ;!!tM;mq(lc2jEo{uPIMH$;c!n z>G32|Esq*C^`^qa7}p7%Zscp6)^2)_lNSfxyv{3-uTQeW0ZZSl!& zjFov&NU#=c@#8Offw1zYzApaBrLU8g4Q}VWChfTd+W_cW`=dKbSo-SQB7+4KrhkHS zkwr>+9SeNj{zY3*pj%dTrv1yMzZc#QLsfBjm(Pn)a~v6+8@87a|H}4s_|s);#N6`e z)!umhkYx079@6K2tFLqOWWKe&C}a)0mb$EoiWF`)kqBM>Q2b4xylu(bixAJ5nU@#M zKDESO*&~Uy5bai8U9uq=If+TDG*y_&M$^DAPN-Z(+CptPp>f>Q+Fac1zzn+9YUz6l zZjQrSS3B-iYjPMG5-%AXDfrB#@nxM7uqDd>&xegVz3~Z-ZX{ z+%NhcQRJ%YblCkX%D!v`j!XmcQiD^h;+vpUX-=C{xXB6>EdMKWrR#Eb5Sb1lyr8mB zxdK*C;99&Z|0zleS|_QK04iu5X5*Pbs}wzxo`STL4QjohCAjR-JH>uZva>q&w}V~Q zkeB?&2=|qjcC^q|M=s8<&ep|9Yv4-URMWGTe4QPA8lF{F@$mrt^)#5GL`t#Pk7sLE zU77wflrK=+x)&BCtpq4q(H%!I%h>GOh%rxF`8H-3%P?%FBvofy`A1!WEj@0dq%>XK zyi(9fQ#&9VkdGIjK+; zijuIoM(Sha8u``Rx_VTt0h9}p1CrX+g7c%=#5lRG7G|gwH_Sas1? zTMcy@(+I}E8dedOs=RCik|5iB3~5Oq9fMXLmfH94U|HHl&*IQ-%9dYk*!I@|x>mHBOJDze;PuVto4?rkQ||}=OvzmU?Iu33=EC%aO|74N)c584o37Ls>gn|l z_uWT~dlU<#yH>7`?}T5)fctkuZ+yB_hxI=d^zHN~PM~Ab#R+?F>&F)5uEOtFAaU;x zdUp&SQfor4H3G?gAO6ddV`Q%t;DA48w3X~=Ed?s z-SgU-6YcIPC$B9`#cpg{pOw84WIl;B>YoVtJuf6HHizEdoa`wr)?e+J^0$vjM{gjy z+X)9VG_Q%8@gftVfAglV=^y&A`&p@TIe4RVS5+i(r3)C S>*LFum%LG&3Si>@wCP`*27>zl literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter08/GetHash/GetHash/GetHash.cs b/Source-Code/Chapter08/GetHash/GetHash/GetHash.cs new file mode 100644 index 0000000..5a6f01d --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash/GetHash.cs @@ -0,0 +1,58 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using Microsoft.SqlServer.Server; +using System.Security.Cryptography; + +namespace Apress.Samples +{ + public partial class CustomEncryption + { + [Microsoft.SqlServer.Server.SqlFunction + ( + IsDeterministic = true, + DataAccess = DataAccessKind.None + )] + public static SqlBytes GetHash + ( + SqlString Algorithm, + [SqlFacet(MaxSize = -1)] SqlBytes Plaintext + ) + { + // Return NULL if Algorithm or Plaintext is NULL + if (Algorithm.IsNull || Plaintext.IsNull) + return SqlBytes.Null; + + bool HashDefined = true; + HashAlgorithm Hash = null; + switch (Algorithm.Value.ToUpper()) + { + case "SHA256": + Hash = new SHA256Managed(); + break; + + case "SHA384": + Hash = new SHA384Managed(); + break; + + case "SHA512": + Hash = new SHA512Managed(); + break; + + default: + HashDefined = false; + break; + } + if (!HashDefined) + throw new Exception + ("Unsupported hash algorithm - use SHA256, SHA384 or SHA512"); + + // Generate the hash value + byte[] HashBytes = Hash.ComputeHash(Plaintext.Value); + // Convert result into a SqlBytes result + return new SqlBytes(HashBytes); + } + } +} + diff --git a/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj b/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj new file mode 100644 index 0000000..52dd48e --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + {c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 9.0.30729 + 2.0 + {C12FBAA8-2AF1-4851-8798-2A3AB4024CA1} + Library + false + GetHash + 512 + GetHash + + + true + full + false + bin\Debug\ + false + DEBUG;TRACE + 4 + + + false + true + bin\Release\ + false + TRACE + 4 + + + + + + + + + + + + + + + Content + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj.user b/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj.user new file mode 100644 index 0000000..bf76951 --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash/GetHash.csproj.user @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/GetHash/GetHash/Properties/AssemblyInfo.cs b/Source-Code/Chapter08/GetHash/GetHash/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..238783e --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Data.Sql; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GetHash")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("GetHash")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] + diff --git a/Source-Code/Chapter08/GetHash/GetHash/Test Scripts/Test.sql b/Source-Code/Chapter08/GetHash/GetHash/Test Scripts/Test.sql new file mode 100644 index 0000000..56e659f --- /dev/null +++ b/Source-Code/Chapter08/GetHash/GetHash/Test Scripts/Test.sql @@ -0,0 +1,35 @@ +-- Examples for queries that exercise different SQL objects implemented by this assembly + +----------------------------------------------------------------------------------------- +-- Stored procedure +----------------------------------------------------------------------------------------- +-- exec StoredProcedureName + + +----------------------------------------------------------------------------------------- +-- User defined function +----------------------------------------------------------------------------------------- +-- select dbo.FunctionName() + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- CREATE TABLE test_table (col1 UserType) +-- go +-- +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 1')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 2')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 3')) +-- +-- select col1::method1() from test_table + + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- select dbo.AggregateName(Column1) from Table1 + + +select 'To run your project, please edit the Test.sql file in your project. This file is located in the Test Scripts folder in the Solution Explorer.' diff --git a/Source-Code/Chapter08/Listing08-03.sql b/Source-Code/Chapter08/Listing08-03.sql new file mode 100644 index 0000000..2baebcf --- /dev/null +++ b/Source-Code/Chapter08/Listing08-03.sql @@ -0,0 +1,38 @@ +-- Listing 8-3 +-- Encrypt/decrypt a BLOB + +-- Generate a 20,000 byte (10 chars X 2000 = 20,000 chars) character string +DECLARE @plaintext varchar(max); +SET @plaintext = REPLICATE(CAST('ABCDEFGHIJ' AS varchar(max)), 2000); + +-- Encrypt the BLOB +DECLARE @encrypted varbinary(max); +SET @encrypted = dbo.EncryptAesByPassPhrase + ( + 'This is my passphrase', + CAST(@plaintext AS varbinary(max)), + 1, + 'This is my authenticator' + ); + +-- Decrypt the BLOB +DECLARE @decrypted varbinary(max); +SET @decrypted = dbo.DecryptAesByPassPhrase + ( + 'This is my passphrase', + @encrypted, + 1, + 'This is my authenticator' + ); + +-- Compare decrypted string and plaintext lengths +SELECT + DATALENGTH(@decrypted) AS decrypted_len, + DATALENGTH(@plaintext) AS plaintext_len; + +-- Compare decrypted string and plaintext contents +SELECT + CASE WHEN @decrypted = @plaintext + THEN 'Decrypted value is equal to plaintext' + ELSE 'Decrypted value is not equal to plaintext' + END AS equal; diff --git a/Source-Code/Chapter08/Listing08-05.sql b/Source-Code/Chapter08/Listing08-05.sql new file mode 100644 index 0000000..d79548d --- /dev/null +++ b/Source-Code/Chapter08/Listing08-05.sql @@ -0,0 +1,34 @@ +-- Listing 8-5 +-- Hash a BLOB + +-- Generate a 20,000 byte (10 chars X 2000) character string +DECLARE @plaintext varchar(max); +SET @plaintext = REPLICATE(CAST('ABCDEFGHIJ' AS varchar(max)), 2000); + +-- Generate hash values using all three algorithms +DECLARE + @sha256 varbinary(32), + @sha384 varbinary(48), + @sha512 varbinary(64); + +SELECT + @sha256 = dbo.GetHash('SHA256', CAST(@plaintext AS varbinary(max))), + @sha384 = dbo.GetHash('SHA384', CAST(@plaintext AS varbinary(max))), + @sha512 = dbo.GetHash('SHA512', CAST(@plaintext AS varbinary(max))); + +-- Show results +SELECT + 'SHA-256' AS algorithm, + @sha256 AS hash + +UNION ALL + +SELECT + 'SHA-384', + @sha384 + +UNION ALL + +SELECT + 'SHA-512', + @sha512; diff --git a/Source-Code/Chapter08/Listing08-07.sql b/Source-Code/Chapter08/Listing08-07.sql new file mode 100644 index 0000000..19f11aa --- /dev/null +++ b/Source-Code/Chapter08/Listing08-07.sql @@ -0,0 +1,36 @@ +-- Listing 8-7 +-- Generating Salted Hashes + +-- Generate a 20,000 byte (10 chars X 2000) character string +DECLARE @plaintext varchar(max); +SET @plaintext = REPLICATE(CAST('ABCDEFGHIJ' AS varchar(max)), 2000); + +DECLARE @salt varbinary(16); +SET @salt = Crypt_Gen_Random(16); + +DECLARE + @sha256 varbinary(32), + @sha384 varbinary(48), + @sha512 varbinary(64); + +SELECT + @sha256 = dbo.SaltedHash('SHA256', CAST(@plaintext AS varbinary(max)), @salt), + @sha384 = dbo.SaltedHash('SHA384', CAST(@plaintext AS varbinary(max)), @salt), + @sha512 = dbo.SaltedHash('SHA512', CAST(@plaintext AS varbinary(max)), @salt); + +SELECT + 'SHA-256' AS algorithm, + @sha256 AS hash + +UNION ALL + +SELECT + 'SHA-384', + @sha384 + +UNION ALL + +SELECT + 'SHA-512', + @sha512; + diff --git a/Source-Code/Chapter08/SaltedHash/SaltedHash.sln b/Source-Code/Chapter08/SaltedHash/SaltedHash.sln new file mode 100644 index 0000000..f9085cd --- /dev/null +++ b/Source-Code/Chapter08/SaltedHash/SaltedHash.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaltedHash", "SaltedHash\SaltedHash.csproj", "{99FE42D6-4870-4B8C-96B9-8C81AFB31E32}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Release|Any CPU.Build.0 = Release|Any CPU + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source-Code/Chapter08/SaltedHash/SaltedHash.suo b/Source-Code/Chapter08/SaltedHash/SaltedHash.suo new file mode 100644 index 0000000000000000000000000000000000000000..cd01f3a20a89dc6892fb61db5751724331b48edd GIT binary patch literal 9216 zcmeI1OKg-?6vyv?C=V4W4;2ANtcXJE^g$osBh%?Ls3jmREsGi~owh=!4?9z61zfxE z72|W^LLsFGia$O+wf0Yw1y7oVW_o6cxizgmKv`(vE@Ku@(D(Gr%#2rQ48@yp14-Z#bG;?C zhl_Y?zi$HwkK?|6E|9h@?Qk9ypGg!{%wY4^WDlNw2}@a}8c7UHU$|SsfN_r|C5b zGi2J$A>K)|k7qw~a`lN416G;^fxDrRy=WdK$ZfNHrsxHoaO*Y0rj4~vAcGiRN#-(2 zxy#NZk@||*I_=P?iF=)SZil~Y)X8ABp-4e~`}0)0vtjLt^8>Cbi>JpB%0DhvLJ zC`!y9PFBbo(BEl2H-PQdB9msf8AJa^tc46y9!2we!9!^O6s-gN;(U!j)oQJ#*J`lF zSp|069z$64i0R9)oj5&WIenzz@_{isc8B$ao^5Kxs|DWb=RdmoKLbYa1U<9fD?xb| zvgtD~BAI^V)WdrFt*1*Oi!r`CXo>Uekmn>b(hM}0K1!uvBmQ5$M}EjJf8{yybplD{Af9)SpZIoLO_JOs ztz`Ijwe{5B5Key6FWlm>w-@Y`ZZ2#57gt7wf5Jp@eCB}de)UhZF8|5qubq|;?qI(r?7kHD0r0o}M`skj{6*U) zhXoYoKgGVtBgH+!0#CPo@fH*y%cxHGf7$$ZA^TytDi7~Y$zs$TMMv|))_LT=@;#lY z;W8~Ezdm}k*WW&*8GY=B?783CYkrxOTbojajBb}xmoZR@k6TS30LfqWOtjW)S@h-t z)N^L$n+3C1Eltm#k;YmG_NXk9On57B4CmI2ql}t*Q;S+RkSf>XC>wEjDz#9KP->>7 zg=dxhZj!w#28<(HdCWOa>rQ6<$UI3`ok&EP8Ig4UklriTpP&AZGX4ZQ?~R!yVf7StgpB@{kN}JqP%w(0*hM>QnsTrl5(E0*}D~Ep0M_zQ*b@>^K=z? zRizqVeAH%Hb9{AjOTuT4t1LAC+&u3h+Qs(VeSO<+pMA0AUTCia;?)dA3#CTtnkltlH6gUW$%fUiZ?1~cVKhO${Rr9;K|2PmJ}kD^pT%`a zH&&&g!&EN26yEas4?9o&`o;N`C%c!on+xCmyZ_aVr=wqO|GDpj|0Z?i26ULFfmLUx z&u(b{^rP6&KU5&!YGY-2H>@9sTl8&%a%kqdaJgxhV5i=<&Rj!b))vf8B%X{OXr~4YVVvVRbtt zuDv#=jm`RO&o36r`cs{GN&e#NV6LTbDSiF zQ|k6B%D)BD5{Td?CQ3M^r z5_E?lzgmNL)3X@tKc90JC`O*swiDkJv${8e&d1S4{S%?M&|t?hT9Wzy8-L1>C;|lsB&e{qk>y_Ki{lm(lL_-Y@?$hW15z nIsBuMjy=AZ6d-!phwr^Qhel&wTDtCC7k96h> + + + Debug + AnyCPU + {c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 9.0.30729 + 2.0 + {99FE42D6-4870-4B8C-96B9-8C81AFB31E32} + Library + false + SaltedHash + 512 + SaltedHash + + + true + full + false + bin\Debug\ + false + DEBUG;TRACE + 4 + + + false + true + bin\Release\ + false + TRACE + 4 + + + + + + + + + + + + + + + Content + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.csproj.user b/Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.csproj.user new file mode 100644 index 0000000..ebc00e3 --- /dev/null +++ b/Source-Code/Chapter08/SaltedHash/SaltedHash/SaltedHash.csproj.user @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter08/SaltedHash/SaltedHash/Test Scripts/Test.sql b/Source-Code/Chapter08/SaltedHash/SaltedHash/Test Scripts/Test.sql new file mode 100644 index 0000000..56e659f --- /dev/null +++ b/Source-Code/Chapter08/SaltedHash/SaltedHash/Test Scripts/Test.sql @@ -0,0 +1,35 @@ +-- Examples for queries that exercise different SQL objects implemented by this assembly + +----------------------------------------------------------------------------------------- +-- Stored procedure +----------------------------------------------------------------------------------------- +-- exec StoredProcedureName + + +----------------------------------------------------------------------------------------- +-- User defined function +----------------------------------------------------------------------------------------- +-- select dbo.FunctionName() + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- CREATE TABLE test_table (col1 UserType) +-- go +-- +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 1')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 2')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 3')) +-- +-- select col1::method1() from test_table + + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- select dbo.AggregateName(Column1) from Table1 + + +select 'To run your project, please edit the Test.sql file in your project. This file is located in the Test Scripts folder in the Solution Explorer.' diff --git a/Source-Code/Chapter09/GetHmac/GetHmac.sln b/Source-Code/Chapter09/GetHmac/GetHmac.sln new file mode 100644 index 0000000..88fc46c --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetHmac", "GetHmac\GetHmac.csproj", "{BEC6B73A-40D1-4F48-A336-2F4ADC259096}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Release|Any CPU.Build.0 = Release|Any CPU + {BEC6B73A-40D1-4F48-A336-2F4ADC259096}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Source-Code/Chapter09/GetHmac/GetHmac.suo b/Source-Code/Chapter09/GetHmac/GetHmac.suo new file mode 100644 index 0000000000000000000000000000000000000000..ac63a6f1b72d317a5df481fe5c2b2dd97f592ae6 GIT binary patch literal 9216 zcmeI1OKenC7{||mC=V5Rs(?6RMG#tBn3k6M$aLBfV+lx0VNpZ+n3l)THtm#0D8{8R z8aKqp!i5PKqsD~9#9-7!5;rCWT+E`z~-HxCp!(TnsJ&?*Z=x*?O}S)V>RE!>ucUeP)d_QG-495v6weSlhOF>}ncn*Il2C^G6Pnbd6D~}k-cahWytMo`ApFZI^ou1j+-QFA4dlL zv@*D!8PDoa2@Ezdzg9@d<5J8J_=TWkAWM($H7hDX7CAc z3%C`m1~tZ$ep%<2+bLsy-SJS_8!3O-le2@H4SpLd$ zy4!2c`sw62>kkV)&^RxHo*sKy!633wY>W~eW%b&TC{f{*X*3N)2B+hSh-2UYvWgNl z70Ji>GEGZ%JdRc?qDD=VsWG*D*9D($Rz1qwZm36n3B3L<&p@$0%?bxBe>V@;Hs9kzoG~q=F9{rDi`iken>eX*3}@GB>TE4ZtC3oq zciW+=HrsHkG1+?tX^tXWdCaV*btkhFGS4uuP9&ntk4QRyNbi;FSEm2Nj6aUfdn4!S z{9btK^b_QXYT>W5h~yWRzvA`hk~+`|k5c^ISpb5}8dRyri;Jy9QB@5n8+>{{$^1t>g4b0hP2KXW_X?s|-DtpOUl;$(c)9g4-Uy z3D$FlbvCfh9auq(x-6jlC+jnO}|nL_0>|wkV_-hQj2tAwDt8_WLCG0hX>fN zXTdZT*EWOSe;iwWZSs#$u|Rq2ZbXo_8lY@NXB_1$Bhz;y#yoBH+n8o1U|38=rp~g8 zx4H&jdeUY|S-v`XW#E(LDhr!=Zk~4#?LvEQpUb&5Gvm2ltxh(|Bz5bPLNVg_v(sdT z38cLrg&#n+vN+lFDtaFQ5F!WvUOA*Y^N3+^Nd%D|eyIw+IqU;~ENLQSq_He8z+wFQ(x*4c5z zQ#~FB&#W~k8Ev(lh1{CvBi*lO)-AK(swf*r6Xcsupe+fsW61_Q}p4``-Ecl)?qjVHyWkUY@+XzWw}r z{hz+Q{#sKhN{>F=a}PQ0Q9O{&T7@yb3pthp&fgK;@##z*HvZH=+vN|Oz{X^YWA@yZ z!WR|J!Y3?Ixcdj)JBH<-n}543M|sc)b5Z84VB~o_fR7KpGF(?PlV#0my(qmL-%h^_f(dn z*ZW-k+e4aK+W%~pElJG`+`mTjpY=*GEPq9{iJ6D1sMqa%SpF3;3Hazn e_#Y18d*|ZN$LVP3vu|CL{I4VxAjJRatA7BA41%-( literal 0 HcmV?d00001 diff --git a/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.cs b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.cs new file mode 100644 index 0000000..4305d1f --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.cs @@ -0,0 +1,60 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using Microsoft.SqlServer.Server; +using System.Security.Cryptography; + +namespace Apress.Samples +{ + public partial class CustomEncryption + { + [Microsoft.SqlServer.Server.SqlFunction + ( + IsDeterministic = true, + DataAccess = DataAccessKind.None + )] + public static SqlBytes GetHmac + ( + SqlString Algorithm, + [SqlFacet(MaxSize = -1)] SqlBytes PlainText, + SqlBytes Key + ) + { + if (Algorithm.IsNull || PlainText.IsNull || Key.IsNull) + return SqlBytes.Null; + bool HmacDefined = true; + HMAC Hmac = null; + switch (Algorithm.Value.ToUpper()) + { + case "SHA256": + Hmac = new HMACSHA256(Key.Value); + break; + + case "SHA384": + Hmac = new HMACSHA384(Key.Value); + break; + + case "SHA512": + Hmac = new HMACSHA512(Key.Value); + break; + + case "RIPEMD160": + Hmac = new HMACRIPEMD160(Key.Value); + break; + + default: + HmacDefined = false; + break; + } + if (!HmacDefined) + throw new Exception + ( + "Unsupported hash algorithm - use SHA256, SHA384, SHA512 or RIPEMD160" + ); + byte[] HmacBytes = Hmac.ComputeHash(PlainText.Value); + return new SqlBytes(HmacBytes); + } + } +} + diff --git a/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj new file mode 100644 index 0000000..ffc58d9 --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj @@ -0,0 +1,56 @@ + + + + Debug + AnyCPU + {c252feb5-a946-4202-b1d4-9916a0590387};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 9.0.30729 + 2.0 + {BEC6B73A-40D1-4F48-A336-2F4ADC259096} + Library + false + GetHmac + 512 + GetHmac + + + true + full + false + bin\Debug\ + false + DEBUG;TRACE + 4 + + + false + true + bin\Release\ + false + TRACE + 4 + + + + + + + + + + + + + + + Content + + + + \ No newline at end of file diff --git a/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj.user b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj.user new file mode 100644 index 0000000..3c9e37c --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac/GetHmac.csproj.user @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Source-Code/Chapter09/GetHmac/GetHmac/Properties/AssemblyInfo.cs b/Source-Code/Chapter09/GetHmac/GetHmac/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cccf04d --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Data.Sql; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GetHmac")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("GetHmac")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] + diff --git a/Source-Code/Chapter09/GetHmac/GetHmac/Test Scripts/Test.sql b/Source-Code/Chapter09/GetHmac/GetHmac/Test Scripts/Test.sql new file mode 100644 index 0000000..56e659f --- /dev/null +++ b/Source-Code/Chapter09/GetHmac/GetHmac/Test Scripts/Test.sql @@ -0,0 +1,35 @@ +-- Examples for queries that exercise different SQL objects implemented by this assembly + +----------------------------------------------------------------------------------------- +-- Stored procedure +----------------------------------------------------------------------------------------- +-- exec StoredProcedureName + + +----------------------------------------------------------------------------------------- +-- User defined function +----------------------------------------------------------------------------------------- +-- select dbo.FunctionName() + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- CREATE TABLE test_table (col1 UserType) +-- go +-- +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 1')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 2')) +-- INSERT INTO test_table VALUES (convert(uri, 'Instantiation String 3')) +-- +-- select col1::method1() from test_table + + + +----------------------------------------------------------------------------------------- +-- User defined type +----------------------------------------------------------------------------------------- +-- select dbo.AggregateName(Column1) from Table1 + + +select 'To run your project, please edit the Test.sql file in your project. This file is located in the Test Scripts folder in the Solution Explorer.' diff --git a/Source-Code/Chapter09/Listing09-01.sql b/Source-Code/Chapter09/Listing09-01.sql new file mode 100644 index 0000000..bed6fe6 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-01.sql @@ -0,0 +1,121 @@ +-- Listing 9-1 +-- Creating Encryption Keys and Sample Data + +-- Create DMK, asymmetric key, symmetric key +CREATE MASTER KEY +ENCRYPTION BY PASSWORD = 'a0*Ui)4x-f'; +GO + +CREATE ASYMMETRIC KEY AsymKey1_Sales +FROM FILE = N'c:\AsymKey1_Sales.snk'; +GO + +CREATE SYMMETRIC KEY SymKey6_Sales +WITH ALGORITHM = AES_256 +ENCRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; +GO + +-- Nonencrypted credit card info +CREATE TABLE SalesLT.CreditCardInfo +( + SalesOrderID int not null primary key, + CreditCardNumber nvarchar(50), + CreditCardExpirationDate datetime, + TotalCharge money +); + +-- Encrypted credit card info +CREATE TABLE SalesLT.EncryptedCreditCardInfo +( + SalesOrderID int not null primary key, + CreditCardNumber varbinary(150), + CreditCardExpirationDate varbinary(150), + TotalCharge varbinary(150) +); +GO + +-- Generate plaintext sample data +WITH Generate4Digits /* Generate 4 random digits */ +AS +( + SELECT SUBSTRING + ( + CAST + ( + ABS(CHECKSUM(NEWID())) % 10000 AS NVARCHAR(4) + ) + N'0000', 1, 4 + ) AS Digits +), +CardNum /* Generate a 16 digit random credit card number */ +AS +( + SELECT N'0999-' + + ( + SELECT Digits + FROM Generate4Digits + ) + N'-' + + ( + SELECT Digits + FROM Generate4Digits + ) + N'-' + + ( + SELECT Digits + FROM Generate4Digits + ) AS CardNumber +), +DaysToExpire /* Get a random amount of days to expiration */ +AS +( + SELECT ABS(CHECKSUM(NEWID()) % 700) AS Days +) +INSERT INTO SalesLT.CreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + CardNumber, + DATEADD(DAY, Days, OrderDate), + TotalDue +FROM SalesLT.SalesOrderHeader +CROSS APPLY CardNum +CROSS APPLY DaysToExpire; +GO + +-- Wipe out the sample data in the table +TRUNCATE TABLE SalesLT.EncryptedCreditCardInfo; +GO + +-- Open symmetric data encrypting key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Encrypt sample random credit card data +INSERT INTO SalesLT.EncryptedCreditCardInfo +( + SalesOrderID, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +) +SELECT + SalesOrderID, + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CreditCardNumber), + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CAST + ( + CreditCardExpirationDate AS varbinary(10) + ) + ), + EncryptByKey(Key_Guid(N'SymKey6_Sales'), CAST + ( + TotalCharge AS varbinary(10) + ) + ) +FROM SalesLT.CreditCardInfo; + +-- Close data encrypting key +CLOSE SYMMETRIC KEY SymKey6_Sales; +GO diff --git a/Source-Code/Chapter09/Listing09-02.sql b/Source-Code/Chapter09/Listing09-02.sql new file mode 100644 index 0000000..d109e22 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-02.sql @@ -0,0 +1,23 @@ +-- Listing 9-2 +-- Simple encrypted search + +-- First get a decrypted credit card number from the plaintext table +DECLARE @n nvarchar(50); + +SELECT @n = CreditCardNumber +FROM SalesLT.CreditCardInfo +WHERE SalesOrderID = 71780; + +-- Open the symmetric key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Perform the search and return the result +SELECT + SalesOrderID, + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) AS DecCreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo +WHERE DecryptByKey(CreditCardNumber) = @n; + +-- Close symmetric key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter09/Listing09-03.sql b/Source-Code/Chapter09/Listing09-03.sql new file mode 100644 index 0000000..008510e --- /dev/null +++ b/Source-Code/Chapter09/Listing09-03.sql @@ -0,0 +1,8 @@ +-- Listing 9-3 +-- Create a Nonclustered Index on the CreditCardNumber Column + +CREATE NONCLUSTERED INDEX IX_EncryptedCreditCardInfo +ON SalesLT.EncryptedCreditCardInfo + ( + CreditCardNumber + ); diff --git a/Source-Code/Chapter09/Listing09-04.sql b/Source-Code/Chapter09/Listing09-04.sql new file mode 100644 index 0000000..61c8f3b --- /dev/null +++ b/Source-Code/Chapter09/Listing09-04.sql @@ -0,0 +1,21 @@ +-- Listing 9-4 +-- Adding a Column to Hold the Credit Card Number Last Four Digits + +ALTER TABLE SalesLT.EncryptedCreditCardInfo +ADD CreditCardLast4 nvarchar(4); +GO + +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +UPDATE SalesLT.EncryptedCreditCardInfo +SET CreditCardLast4 = RIGHT + ( + CAST + ( + DecryptByKey(CreditCardNumber) AS nvarchar(50) + ), 4 + ); + +CLOSE SYMMETRIC KEY SymKey6_Sales; +GO diff --git a/Source-Code/Chapter09/Listing09-05.sql b/Source-Code/Chapter09/Listing09-05.sql new file mode 100644 index 0000000..3388565 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-05.sql @@ -0,0 +1,10 @@ +-- Listing 9-5 +-- Querying the Sample Data with the Last Four Credit Card Digits + +SELECT + SalesOrderID, + CreditCardLast4, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +FROM SalesLT.EncryptedCreditCardInfo; diff --git a/Source-Code/Chapter09/Listing09-06.sql b/Source-Code/Chapter09/Listing09-06.sql new file mode 100644 index 0000000..1215b04 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-06.sql @@ -0,0 +1,10 @@ +-- Listing 9-6 +-- Create Nonclustered Index on Last Four Digits of Credit Card Column + +CREATE NONCLUSTERED INDEX IX_EncryptedCreditCardInfo +ON SalesLT.EncryptedCreditCardInfo + ( + CreditCardLast4, + CreditCardNumber + ) +WITH (DROP_EXISTING = ON); diff --git a/Source-Code/Chapter09/Listing09-07.sql b/Source-Code/Chapter09/Listing09-07.sql new file mode 100644 index 0000000..19543d5 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-07.sql @@ -0,0 +1,24 @@ +-- Listing 9-7 +-- Modified Query to Utilize the CreditCardLast4 Column + +-- First get a decrypted credit card number from the plaintext table +DECLARE @n nvarchar(50); + +SELECT @n = CreditCardNumber +FROM SalesLT.CreditCardInfo +WHERE SalesOrderID = 71780; + +-- Open the symmetric key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Perform the search and return the result +SELECT + SalesOrderID, + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) AS DecCreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo +WHERE CreditCardLast4 = RIGHT(@n, 4) + AND DecryptByKey(CreditCardNumber) = @n; + +-- Close symmetric key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter09/Listing09-08.sql b/Source-Code/Chapter09/Listing09-08.sql new file mode 100644 index 0000000..f787a5d --- /dev/null +++ b/Source-Code/Chapter09/Listing09-08.sql @@ -0,0 +1,39 @@ +-- Listing 9-8 +-- Adding a Cryptographic Hash of the Plaintext Credit Card Number + +-- Drop nonclustered index +DROP INDEX IX_EncryptedCreditCardInfo +ON SalesLT.EncryptedCreditCardInfo; +GO + +-- Drop credit card last 4 digits column +ALTER TABLE SalesLT.EncryptedCreditCardInfo +DROP COLUMN CreditCardLast4; +GO + +-- Add a credit card hash column +ALTER TABLE SalesLT.EncryptedCreditCardInfo +ADD CreditCardHash varbinary(64); +GO + +-- Populate the credit card hash +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +UPDATE SalesLT.EncryptedCreditCardInfo +SET CreditCardHash = HashBytes + ( + 'SHA1', + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) + ); + +CLOSE SYMMETRIC KEY SymKey6_Sales; +GO + +-- Recreate nonclustered index +CREATE NONCLUSTERED INDEX IX_EncryptedCreditCardInfo +ON SalesLT.EncryptedCreditCardInfo + ( + CreditCardHash, + CreditCardNumber + ); diff --git a/Source-Code/Chapter09/Listing09-09.sql b/Source-Code/Chapter09/Listing09-09.sql new file mode 100644 index 0000000..f8481c2 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-09.sql @@ -0,0 +1,10 @@ +-- Listing 9-9 +-- Querying the Encrypted Credit Card Info with Credit Card Hash + +SELECT + SalesOrderID, + CreditCardHash, + CreditCardNumber, + CreditCardExpirationDate, + TotalCharge +FROM SalesLT.EncryptedCreditCardInfo; diff --git a/Source-Code/Chapter09/Listing09-10.sql b/Source-Code/Chapter09/Listing09-10.sql new file mode 100644 index 0000000..cf360dc --- /dev/null +++ b/Source-Code/Chapter09/Listing09-10.sql @@ -0,0 +1,24 @@ +-- Listing 9-10 +-- Hash-Based Searching for Credit Card Numbers + +-- First get a decrypted credit card number from the plaintext table +DECLARE @n nvarchar(50); + +SELECT @n = CreditCardNumber +FROM SalesLT.CreditCardInfo +WHERE SalesOrderID = 71780; + +-- Open the symmetric key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Perform the search and return the result +SELECT + SalesOrderID, + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) AS DecCreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo +WHERE CreditCardHash = HashBytes('SHA1', @n) + AND DecryptByKey(CreditCardNumber) = @n; + +-- Close symmetric key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter09/Listing09-11.sql b/Source-Code/Chapter09/Listing09-11.sql new file mode 100644 index 0000000..25ef64e --- /dev/null +++ b/Source-Code/Chapter09/Listing09-11.sql @@ -0,0 +1,17 @@ +-- Listing 9-11 +-- Generating Salted Hashes of Credit Card Numbers + +-- Populate the credit card hash +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +UPDATE SalesLT.EncryptedCreditCardInfo +SET CreditCardHash = dbo.SaltedHash + ( + 'SHA256', + DecryptByKey(CreditCardNumber), + 0x359a82109cfe + ); + +CLOSE SYMMETRIC KEY SymKey6_Sales; +GO diff --git a/Source-Code/Chapter09/Listing09-12.sql b/Source-Code/Chapter09/Listing09-12.sql new file mode 100644 index 0000000..5202934 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-12.sql @@ -0,0 +1,29 @@ +-- Listing 9-12 +-- Salted Hash-Based Searching for Credit Card Numbers + +-- First get a decrypted credit card number from the plaintext table +DECLARE @n nvarchar(50); + +SELECT @n = CreditCardNumber +FROM SalesLT.CreditCardInfo +WHERE SalesOrderID = 71780; + +-- Open the symmetric key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Perform the search and return the result +SELECT + SalesOrderID, + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) AS DecCreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo +WHERE CreditCardHash = dbo.SaltedHash + ( + 'SHA256', + CAST(@n AS varbinary(100)), + 0x359a82109cfe + ) + AND DecryptByKey(CreditCardNumber) = @n; + +-- Close symmetric key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter09/Listing09-14.sql b/Source-Code/Chapter09/Listing09-14.sql new file mode 100644 index 0000000..5b2ddf6 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-14.sql @@ -0,0 +1,17 @@ +-- Listing 9-14 +-- Populating the Sample Table with HMACs + +-- Populate the credit card hash +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +UPDATE SalesLT.EncryptedCreditCardInfo +SET CreditCardHash = dbo.GetHmac + ( + 'SHA256', + DecryptByKey(CreditCardNumber), + 0x359a82109cfe + ); + +CLOSE SYMMETRIC KEY SymKey6_Sales; +GO diff --git a/Source-Code/Chapter09/Listing09-15.sql b/Source-Code/Chapter09/Listing09-15.sql new file mode 100644 index 0000000..9beab03 --- /dev/null +++ b/Source-Code/Chapter09/Listing09-15.sql @@ -0,0 +1,28 @@ +-- Listing 9-15 +-- First get a decrypted credit card number from the plaintext table + +DECLARE @n nvarchar(50); + +SELECT @n = CreditCardNumber +FROM SalesLT.CreditCardInfo +WHERE SalesOrderID = 71780; + +-- Open the symmetric key +OPEN SYMMETRIC KEY SymKey6_Sales +DECRYPTION BY ASYMMETRIC KEY AsymKey1_Sales; + +-- Perform the search and return the result +SELECT + SalesOrderID, + CAST(DecryptByKey(CreditCardNumber) AS nvarchar(50)) AS DecCreditCardNumber +FROM SalesLT.EncryptedCreditCardInfo +WHERE CreditCardHash = dbo.GetHmac + ( + 'SHA256', + CAST(@n AS varbinary(100)), + 0x359a82109cfe + ) + AND DecryptByKey(CreditCardNumber) = @n; + +-- Close symmetric key +CLOSE SYMMETRIC KEY SymKey6_Sales; diff --git a/Source-Code/Chapter10/CommandLine1.txt b/Source-Code/Chapter10/CommandLine1.txt new file mode 100644 index 0000000..4525ea0 --- /dev/null +++ b/Source-Code/Chapter10/CommandLine1.txt @@ -0,0 +1,2 @@ +Rem The following statement creates a certificate using makecert +makecert -pe -n "CN=knrlt.apress.com" -ss my -sr Localmachine -a sha1 -eku 1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1 -r "sql_2008.cer" diff --git a/Source-Code/Chapter10/ListingA.sql b/Source-Code/Chapter10/ListingA.sql new file mode 100644 index 0000000..88f4596 --- /dev/null +++ b/Source-Code/Chapter10/ListingA.sql @@ -0,0 +1,17 @@ +SELECT TOP 1000 [BusinessEntityID] + ,[NationalIDNumber] + ,[LoginID] + ,[OrganizationNode] + ,[OrganizationLevel] + ,[JobTitle] + ,[BirthDate] + ,[MaritalStatus] + ,[Gender] + ,[HireDate] + ,[SalariedFlag] + ,[VacationHours] + ,[SickLeaveHours] + ,[CurrentFlag] + ,[rowguid] + ,[ModifiedDate] + FROM [AdventureWorks2008].[HumanResources].[Employee] diff --git a/Source-Code/Notes.txt b/Source-Code/Notes.txt new file mode 100644 index 0000000..cb0a7b7 --- /dev/null +++ b/Source-Code/Notes.txt @@ -0,0 +1,5 @@ +Note that the .sql scripts in this file are designed to be run in SQLCMD or SQL Server Management Studio. Most samples use the AdventureWorksLT2008 sample database, except where noted. + +The .NET SQL CLR projects provided in this file are .NET SQL Server database projects, and require Visual Studio 2008 Professional to compile and deploy. Note that SQL CLR projects are not supported by Visual Studio standard or express versions. + +Additional files are included, such as XML files and text files to allow readers to execute the samples in the book. \ No newline at end of file diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file