Question: How to Generate Random Password in SQL Server?
Answer: This is a fantastic question and here is the script to generate a random password in SQL Server
DECLARE @char CHAR = '' DECLARE @charI INT = 0 DECLARE @password VARCHAR(100) = '' DECLARE @len INT = 12 -- Length of Password WHILE @len > 0 BEGIN SET @charI = ROUND(RAND()*100,0) SET @char = CHAR(@charI) IF @charI > 48 AND @charI < 122 BEGIN SET @password += @char SET @len = @len - 1 END END SELECT @password [PassWord]
Well, that’s it. It will generate a password with alphabets, numerics, and special characters. If you want to change the length of the password, you can easily do so by changing the parameter @len. Please note that this function is based on the random function so you will probably never get the same password again in the near future. Here are the sample 10 passwords I generated from the above script to give you an idea what the final outcome looks like.
TUC:GR8?MHYP 6I9G2B]LG3H2 U8OO:^7DE;cb 93RW4]>VI`L9 [V?W^;M1E4Oc
Here are few another related blog post on the similar subject:
- How to Enforce Password Policy of Windows to SQL Server? – Interview Question of the Week #142
- MySQL – Fix – Error – Your Password does not Satisfy the Current Policy Requirements
- SQL SERVER – Best Practices About SQL Server Service Account and Password Management
- SQL SERVER – Change Password of SA Login Using Management Studio
- When was Domain Account Password Changed in SQL Server? – Interview Question of the Week #093
- SQL SERVER – Forgot the Password of Username SA
If you know any other way to generate a random password, please share it and I will publish with due credit.
Reference: Pinal Dave (http://blog.SQLAuthority.com)
Use CRYPT_GEN_RANDOM to get random binary and then cast to XML to use it’s base 64 function to convert it to an alphanumeric password.
article should be titled “How to insecurely generate random passwords in SQL Server”
That is a good title but why would we call it insecurely?
For those playing at home, a cryptographically secure random password:
DECLARE @randombinary varbinary(max), @password varchar(max), @length int
SET @length = 10
SET @randombinary = CRYPT_GEN_RANDOM(@length)
SELECT @password = CAST (” as xml).value(‘xs:base64Binary(sql:variable(“@randombinary”))’,’varchar(max)’)
SELECT LEFT(@password, @length) — Base64 will always be longer and this removes = / == from end as well
Not really, Chris.
While using a slightly more random random-number generator is good, it will have particularly little effect on the overall security of the password. What is really important is the diversity of the characters used in it.
In Pinal’s original version (with bug), used a range of 51 characters to create the password.
Yours uses a range of 64 characters.
My fix to Pinal’s (given in a different comment) uses 75 characters.
DECLARE @char CHAR = ”
DECLARE @charI INT = 0
DECLARE @password VARCHAR(100) = ”
DECLARE @len INT = 12 — Length of Password
WHILE @len > 0
SET @charI = ROUND(RAND()*75,0)+48
SET @char = CHAR(@charI)
SET @password += @char
SET @len = @len – 1
SELECT @password [PassWord]
The line “IF @charI > 48 AND @charI 47 AND @charI < 123, BUT as originally written, charI would only be in the range 0-99 anyway, so the upper limit is pointless, and you're then throwing out half the values generated.
As corrected above, the value produced for @charI is always in the proper range, so the IF becomes superfluous.
Hmm… Somethig went wrong and a bit of my text was dropped there.
The line “IF @charI > 48 AND @charI 47 AND @charI 48 AND @charI < 122" has a number of problems. First of all, character #48 ('0') and #122 ('z') are good characters, so it should be "IF @charI 47 AND @charI < 123," ….
Also, the first step should be "Reconsider your need to generate a password in SQL as this is quite out of scope for what an data server is designed to do, and there are far better tools to do it on your host computer"
Pinal, here is an alternative way to generate your password:
DECLARE @len INT = 30,
@pwd NVARCHAR(512) = N”
SELECT TOP (@len) @pwd += CHAR(fn.rnd) –, fn.rnd
FROM master.dbo.spt_values sv
CROSS APPLY (
SELECT [rnd] = (ABS(CHECKSUM(NewId())) % 122)
WHERE fn.rnd > 48 AND fn.rnd < 122
Turned it into a proc with a little bit more flexibility in choosing which characters show up in the password.
IF OBJECT_ID (N’tempdb..#GenerateRandPwd1′) IS NOT NULL BEGIN
DROP PROC #GenerateRandPwd1
CREATE PROCEDURE #GenerateRandPwd1 (@length int = 20, @allowAtoZ BIT = 1, @allow0to9 BIT = 1, @allowSpecials1 BIT = 0, @allowSpecials2 BIT = 0)
DECLARE @pwd VARCHAR(512) = ”
SELECT TOP (@length) @pwd += CHAR(fn.rnd)
FROM master.dbo.spt_values sv
CROSS APPLY (
— (max – min) + min
SELECT [rnd] = (ABS(CHECKSUM(NEWID())) % (123 – 48)) + 48
WHERE (@allowAtoZ = 1 AND ((fn.rnd >= 65 AND fn.rnd = 97 AND fn.rnd = 48 AND fn.rnd = 33 AND fn.rnd = 58 AND fn.rnd <= 64))
EXEC #GenerateRandPwd1 @length = 30, @allowSpecials1 = 0, @allowSpecials2 = 0
EXEC #GenerateRandPwd1 @length = 30, @allow0to9 = 0, @allowSpecials1 = 1, @allowSpecials2 = 1
I know this is old, but I had written a gist that is a lot better than the proc I commented before: https://gist.github.com/tcartwright/c27a45a4a211f7cc79466140fb80a56d