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
Related
I am using the pgcrypto extension in Postgresql to encrypt and salt the storage of user passwords in a database and I am having trouble retrieving them.
Specifically, the insert statement for a user looks like this:
INSERT INTO Users (username, password) VALUES ('test1', crypt('Password1234', gen_salt('bf', 8)));
This works fine however when I try to retrieve from the database, this query:
SELECT username, password FROM Users WHERE username = 'test1' AND password = crypt('Password1234', gen_salt('bf', 8));
returns no results, the query does not fail, just no results.
Currently, I am not using python to interact with the database (I will be in the future) I am just using psql in the terminal. I know something is wrong with this query but I am not sure what and how to fix it. Is there some other way that this should be structured or what am I doing wrong? Thanks for any help!
You are re-salting the password with a new salt, which of course leads to a different answer than before. That is the whole point of salting.
You need to reuse the first salt in the new hashing, which you do by feeding the password hash in place of gen_salt(...). (The stored hashed password has the salt embedded within it, and crypt knows how to extract and reuse it).
SELECT username, password FROM Users WHERE username = 'test1' AND password = crypt('Password1234', password);
But, why are you selecting "password"? Once you have verified that is hashes correctly, what further use is there in seeing it?
I created a role with login permission, but I can't login with it, I get:
FATAL: password authentication failed for user "myuser"
I have confirmed by select * from pg_roles that the role exists and has login permission.
I suspect an error in my db set up script caused it to be created with a different password to what I believed it was set to.
I realise that you cannot lookup the existing password of a role but I figure there ought to be a function which can be used to tell if a plaintext matches password for a role?
eg in a web app when we store passwords in the db they are salted and hashed... you can't tell what is the password from looking at that, but you can take a new plaintext and run the password hashing on it and say if the hash of your plaintext matches the stored password.
Is there something like that for psql?
I found other SO questions, eg Authenticate PostgreSQL user and password without database, about how to check password but they suggest trying to login with that role from commandline, which I can't do ("password authentication failed").
In my case I realise I should just trust the error message and assume role was created with wrong password... but let's imagine I'd created a role without LOGIN permission - this way of checking wouldn't be possible.
There are other ways to debug my script of course, but I am curious if such a 'password check' function exists.
For example, I found these in the docs:
http://www.postgresql.org/docs/8.3/static/pgcrypto.html
...but they are provided as helpers for building applications on top of Postgres - it is not clear if they are used by Postgres iteself for role passwords.
As posted in the comments, this answer is to compare a given plain text password with a stored md5 hashed PostgreSQL role password. I consider this somewhat of a hack, but let's do it anyway.
The following can be done with the "plain" md5() function in core PostgreSQL.
PostgreSQL's role passwords are hashed with md5 and salted with the role name. As an added bonus, they are prefixed with 'md5'. So a query to match a password to a role would be
select * from pg_authid WHERE rolpassword = 'md5' || md5('the-plain-text-password' || 'the-role-name');
The important bit (of course) is:
'md5' || md5('the-plain-text-password' || 'the-role-name');
Where we concatenate a string "md5" with an md5 hash of the plain text password and the role name as the salt.
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
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?