I am using Django for an application capturing some sensitive data, and I need those data to be encrypted in the database. I have to use a database encryption.
So to save my fields, I use:
query = """
OPEN SYMMETRIC KEY MyKey
DECRYPTION BY CERTIFICATE MyCertificate
UPDATE mytable
SET name = ENCRYPTBYKEY(KEY_GUID('MyKey'), %s)
WHERE id = %s
CLOSE SYMMETRIC KEY MyKey
"""
args = ["Test Name", data.id]
cursor = connection.cursor()
cursor.execute(query, args)
transaction.commit_unless_managed()
The field is saved in database but, when I uncrypt the data saved in base, I get 0x540065007300740020004E0061006D006500 where I should get 0x54657374204E616D65.
Do someone know why there are some 0x00 bytes inserted in my string?
I have tried to get the query string using connection.queries[-1] and run it directly in the database, and the data is clean when I uncrypt it.
Apparently, SQL Server is implicitly doing some kind of string conversion.
I solved my problem by casting the data as a varchar before encryption:
query = """
OPEN SYMMETRIC KEY MyKey
DECRYPTION BY CERTIFICATE MyCertificate
UPDATE mytable
SET name = ENCRYPTBYKEY(KEY_GUID('MyKey'), CAST(%s AS VARCHAR(1023)))
WHERE id = %s
CLOSE SYMMETRIC KEY MyKey
"""
args = ["Test Name", data.id]
cursor = connection.cursor()
cursor.execute(query, args)
transaction.commit_unless_managed()
Related
I'm trying to reset a password and I keep on running into this error, which I don't see how it applied here.
UPDATE [Servicename].[dbo].[Password]
SET salt = 'zfkI0NkJiIJR8Rubuuf800cxjp7epM7EjYkQIfzUxI=',
hash = '96u76IApmLmLzatzGnvFzPq2h4noZZCpc+GATM2VUxk='
WHERE userid = 'admin'`
hi i forget admin password but i can connect to sql
i try to replace another user password to recover
but got this error:
the pass field is like this :
Are you looking for this?
UPDATE [my_users_table]
SET [pas] = CAST('newpass' AS VARBINARY(MAX))
WHERE [nam] = 'admin'
Open new window and try to set the password like this. Anyway, if the data is encrypted and then stored as binary, you will first need to get a valid encrypted binary before setting the new password.
UPDATE [my_users_table]
SET [pas] = 0x0DE3446D8F782E9B
WHERE [nam] = 'admin'
I am developing a routine that imports data from a 3rd party SFTP server. This server uses WinSCP to create the SFTP Connection and uses a SSH Private Key for the connection rather than a username and password. So I create my connection as below in a script task:
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = ftpSite,
UserName = username,
Password = password,
SshHostKeyFingerprint = sshKey,
SshPrivateKeyPassphrase = "mypassword",
SshPrivateKeyPath = #"C:\path\to\private.ppk"
};
I'm happy enough storing the Private Key Path in a database table (which contains my connectoin settings) but I want to store the SshPrivateKeyPassphrase somehwere that is encrypted. I was initially thinking can I create an Encrypted Variable, so if you look at the xml of the package, it won't expose the password directly, but I can reference the variable in code to pass the password to the connection.
I was also looking at creating a dummy Connection and see if I can refer to the connection and get the password in the code, but it seems a bit of a fudge.
The solution the package is in is passworded, i'm just trying to cover all bases, so if someone gets access to the package who shouldn't, they won't get the private key passphrase as that would cause us all sorts of issues.
I am trying to encrypt one of my sensitive columns in a SQL Server table.
I tried AES256 encryption with this script, and it works perfect.
But I don't want to create Certificates, or Symmetric Keys on my SQL Server as it may be a security problem later.
How can I encrypt the data with a single password or key in my query ?
Another problem with this method is, I can use only a single master password for
my encryption.
CREATE MASTER KEY ENCRYPTION
BY PASSWORD = '$Passw0rd'
GO
CREATE CERTIFICATE AESEncryptTestCert
WITH SUBJECT = 'AESEncrypt'
GO
CREATE SYMMETRIC KEY AESEncrypt
WITH ALGORITHM = AES_256 ENCRYPTION -- TRIPLE_DES ENCRYPTION
BY CERTIFICATE AESEncryptTestCert;
OPEN SYMMETRIC KEY AESEncrypt DECRYPTION
BY CERTIFICATE AESEncryptTestCert
SELECT ENCRYPTBYKEY(KEY_GUID('AESEncrypt'),'The text to be encrypted');
You can use EncryptByPassPhrase and DecryptByPassPhrase, for example:
DECLARE #CypherText varbinary(8000)
DECLARE #ClearText varchar(128) = 'Text to encrypt'
SET #CypherText = EncryptByPassPhrase ('MyP#ssword123', #ClearText)
DECLARE #DecryptedText varchar(128)
SET #DecryptedText = DecryptByPassPhrase('MyP#ssword123', #CypherText)
SELECT #CypherText AS CypherText, #DecryptedText As DecryptedText
EDIT:
The above code produces the following output
+----------------------------------------------------------------------------+-----------------+
| CypherText | DecryptedText |
+----------------------------------------------------------------------------+-----------------+
| 0x01000000F1D813F399246484FDA8D7C7D22BFBCF748D3F6033D4E9980FCDC58A387A1A93 | Text to encrypt |
+----------------------------------------------------------------------------+-----------------+
I'm looking for a simple way to generate passwords that will only work once for a limited amount of time, e.g. 1 day, 1 week, 1 month. This has to be implemented in an application that has no connectivity so a server isn't possible. The use case is something like:
1. Generate password for a specific date and length of time.
2. Send to user (email, phone, etc).
3. User enters in application.
4. Application is enabled for a specific time.
5. Password cannot be reused, even on another PC.
I'm assuming the only way to do this is to generate passwords that only work between a specific set of dates. Can anyone recommend an algorithm that can do this? It doesn't have to be incredibly secure, and I know you can crack this by resetting the time on the PC!
Thanks.
I know I'm late but I'll provide my advice anyway in case someone else who needs it found their way here.
To prevent it being used on another PC, you could probably use the MAC address or hardware address. However, this is subject to the network hardware being still available when checking the password. Please make sure you use the hardware address of the machine where the password will be checked.
private string GetBase64Mac()
{
System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
if (interfaces.Length == 0)
{
System.Net.NetworkInformation.PhysicalAddress add = interfaces[0].GetPhysicalAddress();
if (add != null)
return System.Convert.ToBase64String(add.GetAddressBytes());
}
return "";
}
To limit it by some expiry date simply use the text string of the expiry date.
private string GetExpiryDate(DateTime expiryDate)
{
return expiryDate.ToString("yyyyMMdd");
}
Simply use a hash function to hash the combine expiry date, hardware address and a secret key. Prefix or suffix the hash output with the expiry date.
private void GeneratePassword(string prefix)
{
string secretKey = "MySecretKey";
System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
byte[] preHash = System.Text.Encoding.UTF32.GetBytes(prefix + secretKey + GetBase64Mac());
byte[] hash = sha.ComputeHash(preHash);
string password = prefix + System.Convert.ToBase64String(hash);
return password;
}
In the case above, i prefix the hash with the expiry date. So, when we check the password, we simply extract the expiry date from the password, use the same function to generate the same password. If the generated password match the provided password, then you have green light.
private void TestPassword()
{
int duration = 15; // in days
string prefix = GetExpiryDate(DateTime.Today.AddDays(duration));
string generated = GeneratePassword(prefix);
// Positive test
string testPrefix = generated.Substring(0, 8);
string testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return false;
// Negative test
generated[2] = '2';
generated[12] = 'b';
testPrefix = generated.Substring(0, 8);
testPassword = GeneratePassword(testPrefix);
if (generated != TestPassword)
return true;
return false;
}
Sample output password:
20110318k3X3GEDvP0LkBN6zCrkijIE+sNc=
If you can't get the hardware address, then simply use the customer's name. It won't prevent the password from being used in multiple machines, but it will ensure that the same person is using it.
Your application should have a attribute like validity for the password something like this
username password_hash validity_from Validity_end
xyz a73839$56 11-Nov-2010 12-Nov-2010
and then in your application you can validate that your password has expired or not
Generate passwords by any method you'd like (a word list, random letters, etc). Put them into some data structure, like an associative array, where you can associate a date with each password. Then you consult this data structure in the program that hands out passwords to give one out with the proper expiration date. The client program has the same list of passwords and dates, so when it gets a password, it just looks up the associated expiration date there.