I want to do column level encryption. For example:
--Create Master Key
USE EncryptTest
GO
CREATE MASTER KEY ENCRYPTION
BY PASSWORD = 'Test'
GO
--Create Server Cert
USE EncryptTest
GO
CREATE CERTIFICATE EncryptTestCert
WITH SUBJECT = 'Test'
GO
/* Create Symmetric Key */
USE EncryptTest
GO
CREATE SYMMETRIC KEY TestTableKey
WITH ALGORITHM = TRIPLE_DES ENCRYPTION
BY CERTIFICATE EncryptTestCert
GO
/* Encrypt the Column.*/
USE EncryptTest
GO
OPEN SYMMETRIC KEY TestTableKey DECRYPTION
BY CERTIFICATE EncryptTestCert
UPDATE TestTable
SET EncryptSecondCol = ENCRYPTBYKEY(KEY_GUID('TestTableKey'),SecondCol)
GO
--View encrypted
USE EncryptTest
GO
SELECT *
FROM TestTable
GO
My question however, is how to back up the Cert or key? The scenario being the DBA (not me of course) accidentally deletes the cert/key leaving the database secure, but useless. I bring this up as I have seen more actual issues with someone flubbing security with a fat finger, then with actual security breaches.
Did you follow the article at Microsoft TechNet on backing up a cert?
http://technet.microsoft.com/en-us/library/ms178578.aspx
Related
I'm using Postgres on AWS RDS. My application is encrypting selected columns in a table using AWS KMS encryption. I tried but could not find a way to configure KMS keys and use the decrypt() in select query.
e.g. my app is encrypting myTable.secureColumnusing KMS. now I'm trying to fire below query:
SELECT *
FROM myTable
WHERE decrypt(secureColumn, 'key', 'aes') = 'data';
I didn't find how to configure KMS keys in pgCrypto and use in above query.
Has anyone tried this?
Thanks in advance.
I am trying to solve a problem where I need to generate a non-sequential and cryptographically random primary key as each record is inserted into a table.
The reason for this is each record is generated from an email list, but those records should not be able to be linked back to those email addresses (secret ballot situation). If someone managed to access the email list, they could derive from the insertion order who supplied the data for each record.
Is it possible to do this without generating an id of some kind in the application code, and be done purely in PostgreSQL? If not, what is the next best solution?
It seems that the best choice is to use pgcrypto and do the following:
CREATE EXTENSION pgcrypto;
CREATE TABLE whatever (
id uuid PRIMARY KEY DEFAULT gen_random_uuid()
)
The PostgreSQL 9.4 documentation on pgcrypto states that gen_random_uuid() generates a cryptographically random V4 UUID, which suits this situation perfectly.
Its good practice to Go with uuid as you can check out this link as well.
Advantages and Disadvantages of UUID and
whats-your-opinion-on-using-uuids-as-database-row-identifiers-particularly-in
Note: You need to enable the pgcrypto (only PostgreSQL >= 9.4) or uuid-ossp extension to generate random UUIDs..
pgcrypto generator function
uuid-ossp generator functions
Hope this help you !!!
Another option is to use encryption to generate the unique row keys. Simply encrypt the numbers 0, 1, 2, 3, ... in turn using a block cypher. Provided you always use the same cypher key, the outputs are guaranteed unique because the inputs are unique. For 64 bit row keys use 3DES, for 128 bit row keys use AES. For other sizes use Hasty Pudding cypher, which can work with effectively any block size you want.
I updated my question to reflect the sql encryption rather than asp.net.
I created my key in sql
USE DatabaseName
GO
CREATE ASYMMETRIC KEY MyKey
WITH ALGORITHM = RSA_2048
ENCRYPTION BY PASSWORD = 'Password1'
Then I Modified the keys private key password
ALTER ASYMMETRIC KEY MKey
WITH PRIVATE KEY
(ENCRYPTION BY PASSWORD = 'ADifferentPassword',
DECRYPTION BY PASSWORD = 'Password1')
I would like to know why the ENCRYPTION BY PASSWORD is the password used to decrypt the data instead of the DECRYPTION BY PASSWORD?
and then too ENCRYPT I dont really need a password I just need to reference MyKey is this correct?
INSERT dbo.BookSellerBankRouting
(BookSellerID, BankRoutingNBR)
VALUES (22,
EncryptByAsymKey(AsymKey_ID('MyKey'),
'1234567'))
I thought you would have to specify the encryption password to encrypt and the decryption password to decrypt.
But when i use the encryption password in the statement below it decrypts the data and the decrypt password fails
SELECT CAST(DecryptByAsymKey
( AsymKey_ID('MyKey'),
BankRoutingNBR,
N'ADifferentPassword') as varchar(100)) BankRoutingNBR
FROM dbo.BookSellerBankRouting
WHERE BookSellerID = 22
It sounds like you are way overcomplicating things. SQL Server has built in support for encryption and user roles. You're better off trusting that the professionals who built that knew what they were doing than trying to implement your own scheme. Start reading about SQL Server encryption here: http://technet.microsoft.com/en-us/library/bb510663.aspx
As part of my job, assume I have a table
create table bank(accountnumber int, accountholdername varchar(50),
amount decimal(10,2),lastdrawn varchar(5))
Now my requirement is all table data is confidential so at the time of insertion only the data
has to be entered in table in encrypted format.
And if we want to see the encrypted data then we have to decrypt it.
But finally always the data in a table should be in encrypted format.
Now can I resolve this problem? Can anyone help with step by step explanation?
You can use several encryption algorithms to encrypt data before inserting to database:
MD5 encryption http://bloggingabout.net/blogs/rick/archive/2005/05/18/4118.aspx
BASE 64 Encryption http://bytes.com/topic/asp-net/answers/529500-base64-decoding
SHA or DES Encryption. http://www.codeproject.com/Articles/10154/NET-Encryption-Simplified
I am looking for an example of salting passwords withing a T-SQL Stored Procedure. And of course the matching proc to validate a user.
CREATE PROC ChangePassword(#Username nVarChar(50), #Password nVarChar(50))
CREATE PROC ValidateUser(#Username nVarChar(50), #Password nVarChar(50))
First, I'm going to go out on a limb here and say that hashing passwords in the database is in general a bad practice with respect to security. You would not be protected against traffic sniffers watching traffic to the database. The only way to protect against that is to ensure your connection to the database was encrypted which generally means all other traffic to the database is going to be encrypted. It's possible to work around this, but the better solution is to have the application(s) do the hashing.
As Sam Saffron stated, you can use the Hashbytes functions to get SHA1 hashing. If you want better algorithms you would need to create a CLR procedure. Salting would involve storing a cryptographically random value for each user, then appending that value to the password and running it through Hashbytes:
Create Procedure ValidateUser
#Username nvarchar(50)
, #Password nvarchar(50)
As
Declare #PasswordSalt varbinary(256)
Set #PasswordSalt = ( Select PasswordSalt From Users Where Username = #Username )
If #PasswordSalt Is Null
-- generate a salt?
Declare #Hash varbinary(max)
Set #Hash = Hashbytes('SHA1', #PasswordSalt + Cast('|' As binary(1)) + Cast(#Password As varbinary(100))
If Exists( Select 1
From Users
Where Username = #Username
And PasswordHash = #Hash )
-- user is valid
Else
-- user is not valid
Remember that the salt should be cryptographically random so I would not recommend using NewId(). Instead, I would generate that using something like .NET's RNGCryptoServiceProvider class.
You can use HASHBYTES to SHA1 a string, and NEWID() to generate a random Guid as salt.
have you considered salting passswords at the application level as.the server hardware for app servers esp. Cpu might have been more suitable than the dbms's to process hashing and salting?