I am developing an intranet application that contains a few connection strings in a database table with passwords (the previous developer did this - I know it is bad practice). The plan was to upgrade from SQL Server 2005 to SQL Server 2008, so I was going to wait for this and then use TDE (Transparent Data Encryption) as no changes are required to code even when the data is encrypted.
I have now discovered that we are not upgrading to SQL Server 2008. What other options do I have to minimise changes required to the application? I thought of using the encryption facility in the web.config but I believe a lot of changes will be required. What other options do I have? There are two client applications that connect to it i.e. VB6 and VB.NT.
I can think of three options that you can take. First is to have your system administrator provision a service account from active directory, grant the same permissions as the sql account, then configure the Application Identity property in the advanced settings of the application pool in IIS. You will then be able to remove the username and password from the configuration string and replace it with the property "trusted_connection=true".
Second, you can apply column level encryption to encrypt the connection strings stored in your database. It can be done without any code changes for your intranet app. You will need to rename the table, create a view with the old table name containing the function decryptautokeybycert. I'll post an example at the end of the post.
Third, you can have the DBA configure the server to force all connections to be encrypted using SSL\TLS.
use master
go
create database EncryptedData
go
use EncryptedData
create master key encryption by password='P#ssw0rd!'
create certificate KeyProtection with subject='Key Protection'
create symmetric key ColumnKey
with algorithm=AES_256
encryption by certificate KeyProtection
create table SecretMessages(Ciphertext varbinary(4000))
go
create view dbo.MessageRecords
as
select
cast(DECRYPTBYKEYAUTOCERT( cert_id('KeyProtection'), null,Ciphertext) as varchar(max)) MessageRecord
from dbo.SecretMessages
go
open symmetric key ColumnKey decryption by certificate KeyProtection
insert into SecretMessages(Ciphertext) values (ENCRYPTBYKEY(key_guid('ColumnKey'),'Hello world 1'))
insert into SecretMessages(Ciphertext) values (ENCRYPTBYKEY(key_guid('ColumnKey'),'Hello world 2'))
insert into SecretMessages(Ciphertext) values (ENCRYPTBYKEY(key_guid('ColumnKey'),'Hello world 3'))
insert into SecretMessages(Ciphertext) values (ENCRYPTBYKEY(key_guid('ColumnKey'),'Hello world 4'))
insert into SecretMessages(Ciphertext) values (ENCRYPTBYKEY(key_guid('ColumnKey'),'Hello world 5'))
close symmetric key ColumnKey
select * from MessageRecords
Related
We need to configure Always Encrypted feature for all databases. We wanted to create common Column Master Key in Master database so that we can link CMK to all databases on server. But we are not able to link CMK created in master DB to all databases. We need to create individually create master key in each database. Is there any way to create a CMK in master database and refer to all databases on the server.
Column Master Key is per-database object, i.e. you can't share it between databases. However, it is nothing more than metadata, i.e. a pointer where the actual key (certificate) is stored. With Always Encrypted the database do not have access to the actual encryption keys. They are stored in external key store (Windows Certificate Store, Azure Key Vault). So what you need to do is to replicate (copy) the existing certificate by registering it in the rest of the databases. Just script the existing CMK as CREATE COLUMN MASTER KEY statement and execute it in each of the databases:
CREATE COLUMN MASTER KEY [CMK_Auto1]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
KEY_PATH = N'CurrentUser/my/2CC027B4FCA85D4244B528E8CA5F73D1EBB18C69'
)
GO
This will create a new CMK in each database, but all of them will use the same certificate to encrypt the data. Then encrypt the columns you want using the existing CMK, which you created with the script above.
I have two instances of SQL Server 2016 Enterprise, each running on a different server. They are standalone servers. There is a shared drive on ServerA which can be accessed from ServerB.
I have set up log shipping from a database (TESTDB) on MAIN_DB to one on MAIN_UAT. I did this by creating the same local user profile on each server (SQLService) with the same password and changing the SQL Agent and SQL Server jobs to run under this profile on each server using SQL Server Configuration Manager. This seems to work quite happily.
I then tried to implement TDE on the databases.
In the first instance, I stopped log shipping. I then created a second database (TESTDB2) on MAIN_DB and set up log shipping to that from the primary database on MAIN_UAT. Then I used this script to set up TDE. Once the backup and restore cycle had run, TESTDB2 was also encrypted. Again, this worked without problems.
use master
go
create master key encryption by password='something cryptic'
go
create certificate TDECertificate with subject='Log Shipping certificate'
go
create database encryption key with algorithm=AES_256 encryption by server certificate TDECertificate
alter database TestDB set encryption on
I then tried to reproduce this on the secondary server – MAIN_UAT. On the primary server I ran this script.
backup certificate TDECertificate to file='D:\Certificates\myCertificate.crt'
with private key (file='D:\LANSHARE\Certificates\LogShippingKey.key',encryption by password='something cryptic')
backup master key to file='D:\Certificates\MasterKey.key' encryption by password='something cryptic'
I copied the three resulting files into a folder on the secondary server and gave SQLService (the local user) full control over the folder and files. I then tried to install the certificate on the secondary server with this script.
use master
go
restore master key from file='D:\Certificates\MasterKey.key' decryption by password='something cryptic'encryption by password='something cryptic'
go
create certificate TDECertificate from file='D:\Certificates\myCertificate.crt' with private key (file='D:\Certificates\LogShippingKey.key',decryption by password='something cryptic',encryption by password='something cryptic')
go
use TESTDB2
go
create database encryption key with algorithm=AES_256 encryption by server certificate TDECertificate
This gave me this error, which is where I’m stuck.
Msg 15151, Level 16, State 1, Line 14
Cannot find the certificate 'TDECertificate', because it does not exist or you do not have permission.
In a nutshell, how do I implement TDE with log shipping on servers on different domains?
Thanks for any help you can give.
We start with the facts:
Logins are in the master database,
users are in a user database.
Azure does not allow to change database with USE statement.
SQL requires the user to be in the master database in order to execute ALTER LOGIN statement.
.
--USE master;
--**ERROR** USE statement is not supported to switch between databases. Use a new connection to connect to a different database.
--GO
ALTER LOGIN nonadmin WITH PASSWORD='new5as$word' OLD_PASSWORD='old5a$sword';
--**ERROR** User must be in the master database.
GO
It is possible to migrate the database to contained mode, but this way would be quite exhausting as the legacy code have plenty of places like this:
IF(OBJECT_ID('tempdb..#temp1') IS NOT NULL)
BEGIN
DROP TABLE #temp1
END;
CREATE TABLE #temp1
(
id int not null IDENTITY,
CONSTRAINT PK_tt1 PRIMARY KEY(id)
)
Is there a suitable workaround except migrating to contained database mode?
You are trying to change the password of a contained user. Contained users don't have server logins so you can't use the ALTER LOGIN statement.
You need to use ALTER USER :
ALTER USER nonadmin WITH PASSWORD='new5as$word' OLD_PASSWORD='old5a$sword';
A server login is the identity with which you login to a server. In SSMS, you'll find logins in a server's Security node. These logins are then granted access to specific databases as users. These users are stored in the master database.
elect the Database choice on the left, then select Servers:
Then, after selecting the server of choice, you'll see the option on the right for resetting admin password:
source : Password reset for Azure database
I have a database that was moved off of an old SQL Server 2008R2 instance and into a SQL Server 2012 AlwaysOn cluster. There are several fields within the database that are encrypted using SQL Servers built-in encryption features (master key, cert, symmetric key.)
I have run the following commands on my QA AO instance (the same steps that had been run on the old server):
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'password'
CREATE CERTIFICATE myCert
WITH SUBJECT = 'password'
CREATE SYMMETRIC KEY myKeyName
WITH ALGORITHM = TRIPLE_DES
ENCRYPTION BY CERTIFICATE myCert
Additionally I had to run the following commands to correctly decrypt the data:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
When I run this command I then see all of the data decrypted:
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
CLOSE SYMMETRIC KEY myKeyName
So far so good. However, if I run these same steps on my production AO cluster this query:
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
returns NULL for the password. To make this a little bit more maddening, this statement (run in the context of the QA environment) decrypts everything from both databases just fine:
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
SELECT TOP 1000
userid,
CONVERT(nVARCHAR(255),DECRYPTBYKEY(password))
FROM users
SELECT TOP 1000
userid,
CONVERT(nVARCHAR(255),DECRYPTBYKEY(password))
FROM PRODUCTIONAO.prod_database.dbo.users
CLOSE SYMMETRIC KEY myKeyName
I am not sure why this would work on my QA instance, but not on my production instance. Any help would be greatly appreciated!
The reason your last query works is due to the fact that you're using the QA instance's key/cert to do the decryption of the production data. In QA you can auto-decrypt the cert with the database master key (DMK) since it's encrypted by the QA service master key (SMK) as follows:
Service Master Key (QA)
Database Master Key (QA)
Certificate (QA)
Symmetric Key (QA)
Data (Prod)
In prod, you have a different SMK so the only option to open the DMK is by using the password. It seems that you ran the following in the QA environment but not in prod:
/* Add service master key encryption to the database master key */
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY
Try this in prod:
OPEN MASTER KEY DECRYPTION BY PASSWORD = 'password'
OPEN SYMMETRIC KEY myKeyName
DECRYPTION BY CERTIFICATE myCert
select TOP 1000 userid, CONVERT(nVARCHAR(255),DECRYPTBYKEY(password)) from users
CLOSE SYMMETRIC KEY myKeyName
If that returns data, you need to add the SMK encryption to your DMK in production (the first script). The other option is backing up the SMK from the source instance and restoring it on the secondary. I'd only recommend this in HA use-cases where the instances are fail-over partners and both are in the same environment. Sharing SMKs between QA and prod is a bad practice.
When a database master key is created, the server saves 2 versions of key. One version is encrypted by the master service key and by default is used by the server. The second version is encrypted by the password that you supply to the server when you create the database master key. This version usually is not used. When you move your database into a different environment (production in your case), the new server has a different master service key. Since it is not the service key that was used to encrypt the database’s master key, it also can’t be used in order to open the database’s master key. This is where you should use the version that was encrypted with your password. You need to open the master key using your password, then encrypt it using the new service key and close it. After you do that, the database’s master key can work with the master service key, so you don’t need to do it again.
steps/code:
open master key decryption by password = 'WriteYouOriginalPasswordHere'
alter master key add encryption by service master key
close master key
I am trying to create a table in SQL Server
create table admin (name varchar(40), pass varchar(40))
The problem is I don't want password to be visible I mean it should be shown like **** as usual in log in systems.
Waiting to hear from you soon.