January 28, 2012 at 6:31 pm
Comments posted to this topic are about the item Should we outsource identity management
January 29, 2012 at 1:04 am
Perhaps some sort of regulation for security? Our application (browser-based and currently delivered via SSL) is completely HIPAA compliant with passwords hashed in a separate table in the security database (which is kept separate from the main application database). But it was required so perhaps if it was required for everyone and all applications (or at minimum certain classes of applications) then we would see better compliance with such a standard. :ermm:
January 29, 2012 at 5:06 am
If I understood well I think that it might be a business decision rather than something developers can chose from.
A security audit shall help developers understand the weekneses of differnet approaches regarding authentication.
Personaly I would outsource identity management only if I would have no other option, and even so I would keep an eye on it.
Microsoft Passport and OAuth sounds good.
But I still believe that a business decision based on security audit shall be able to push things forward through a less risky identity management.
KR,
Iulian
January 30, 2012 at 2:01 am
My daughter just learnt the hard way about password security - her hotmail account was hacked. Her new password is more than double its old length.
January 30, 2012 at 7:29 am
I've been doing application development, database development, and DBA work since 1986. In my experience, developers learn about the importance of good security over time and eventually learn that their "custom method" is not better than any standard. I think the problem with convincing developers they can't manage identity better is more a matter of education and experience. Sending them to classes on security early on in their career will help them learn sooner that the "custom method" is usually just smoke and mirrors or security by obscurity rather than real security.
I also totally agree with Iulian that management should be making security decisions not developers. But the decisions must be based on education/knowledge and experience. So if management is not knowledgable in security matters then they need to be sure their security decisions are based on recommendations from people who do have the knowledge and experience. Not on the recommendations of a new developer who doesn't know any better.
New unexperienced management + New unexperienced developer = All the headlines we read about security breaches.
January 30, 2012 at 10:30 am
Good, modern password security is often considered either "too cumbersome" for users, or "too CPU intensive"; at this point, as far as I am aware, GPGPU hashing is only aware for those that write dedicated code; i.e. those doing cracking (security audits/legitimate activity and/or malicious activity and/or not intentionally malicious activity, etc.). Thus, crackers at this time have on the order of a thousand-fold hash speed advantage (i.e. about 15 years of password life) over most corporate password hashing capabilities. That's likely to continue until hashing makes it to CPU's, as most corporations aren't going to fork over the $$, power, and cooling budget for Tesla or other industrial GPGPU cards.
The basic steps to take are:
1) Determine how long you need this password to last
a) Note that all the "you must change your password every N time units" rules fail for people who don't log in that often unless they're forced to completely re-register after
b) Note that some data needs to be protected for N years for regulatory reasons
c) Note that people are living longer lives; some information (particularly health care or sealed juvenile records) should be protected for at least an individual's entire lifespan.
2) Determine the level of adversary you wish to handle
3) Determine the current rates at which hashes are being cracked by on a given machine today, and then extrapolate that to the level of adversary.
a) For example, as of late 2011, a single machine with 8 GPU's was recorded as cracking 15.7 billion (with a B) SHA-1 hashes every second. At $330/ea, that's $2,640 in video cards; being generous, that's perhaps $3500 per machine. If you wish to deal with a $10,000 budget adversary, assume 3 machines, or 47.1 billion SHA-1 hashes per second _today_. If you wish to deal with a $500,000 budget adversary, assume 2.3 Trillion SHA-1 hashes every second.
4) Account for Moore's Law! If today's machine will take 147,000 years to crack the password, then realize that the advancement of technology, if we assume a doubling every 18 months, will crack the password in about 25 years - well within the lifetime of most users. Further, in about 35 years, that password will be cracked in less than a year by a far less well funded adversary.
a) Rule of thumb: Expect your adversary to get 128 times faster every 10.5 years, or 16,384 times faster every 21 years.
b) This is much more critical for encryption, particular for legally protected information in your jurisdiction!!! If someone makes a copy of your encrypted data... and then decrypts it in 25 years, that could still be a big deal (for instance, financial, health care, or sealed juvenile information).
5) Having picked your hash (If possible, please use SHA512, SHA256, Whirlpool, one of the SHA3 finalists, your country's regulatory approved hash suites or, if you must, SHA1. DO NOT use MD5, or MD4), determine the balance between length, complexity, and number of PBKDF2 hashing iterations required to actually meet the requirements you determined.
a) PBKDF2 (Password-Based Key Derivation Function, PKCS #5 2.0) is a specific algorithm for having multiple iterating hashes for generating a password; see the Wikipedia PBKDF2 link, IETF RFC2898 (PKCS #5 2.0)
b) Microsoft .NET Framework provides Rfc2898DeriveBytes but only for SHA1 (very unfortunate)
c) BouncyCastle also has a C# (linked) and Java library released under a modified MIT X11 license (lawfully free for commercial and noncommercial use) that has PBKDF2 functionality; a C# example discussion can be found on StackOverflow
d) Yes, you need to use PBKDF2; don't fall into the trap of the two-key TripleDES specification, which combined three iterations of 56-bit DES and arrived at all of 80 bits of security due to a very technical mathematical property. Note that even three-key TripleDES combines three iterations of 56-bit DES at arrives at only 112 bits of security.
6) Follow other normal rules - salt with a long (128 bit or more), random salt that's different for every password (can be stored in the clear; it's just a salt/nonce), use random IV's (Initialization Vectors) for encryption, also stored in the clear, etc.
7) Always use Cryptographically sound random number generators (For .NET, I believe that is RNGCryptoServiceProvider), not the normal pseudorandom number generators.
a) Why not? Well, a normal pseudorandom number generator inherently predictable; that's why with the same seed, we get the same results. For crypto purposes, we do not want predictable results.
8) Hire a professional security consultant (or see if your current security vendor will) code review your security code; there are many, many easy mistakes to make.
a) And the examples you see on the Internet typically make almost all of them, apparently being from the "If it doesn't crash, and my app functions like I expect, it's GOOD!" school of thought.
9) And check to see if the passwords users propose have any chance at all of standing up to a hybrid dictionary attack. Users will choose "password" as their password, and if you say "Use upper case and lower case both", they'll choose "Password"; if you want a number also, you get "Password1", if you want symbols too, you get "Password1!", until you force them to change their password every 30 days, in which case you get "Password2!", "Password3!", and so on.
a) None of which survive very well in an environment where an attacker with a single $3500 machine can try a ten million word dictionary, apply a rule to use lowercase, all uppercase, and uppercase the first letter and lowercase the rest, apply a rule to add every number from 0 to 999 after each word, and apply a rule to add one of the32 standard keyboard symbols to the end of that. This is 10,000,000 * 3 * 1001 * 33 = 990,990,000,000 possibilities (1001 and 33 because there's also the option of "don't use that rule"). This sounds like a lot... but at 15.7 billion hashes a second, if you applied only a single SHA1 hash to it, that takes only 64 seconds.
Here's some very primitive code to run very basic password checks. It assumes a table of lowercase + number + symbol passwords (essentially, it assumes that the cracking rules will handle case combinations, and thus compares in a case-insensitive fashion). You'll need to modify this to fit your rules; right now it's based on the very standard "minimum 8 characters, at least three of Upper, Lower, Number, Symbol" rules, the less standard "14 or more is good!" rule, and the less standard "If _these_ hybrid dictionary rules find your password, imagine what a real attacker will use" rule. Note that many bad passwords will make it through; there's no provision for taking two words together, and the suffix rules are limited to "two symbol/three number/common year suffix", and prefix rules are barely even present.
Password lists to start you off can be found by a Google search on "wordlist" - Darknet, Ob-security, Korelogic, Skullsecurity, the U.S. Census, and others have good lists, including (unabridged) dictionaries for various languages, name lists for various languages, Facebook name lists, themed lists (sports, music, movies, etc.), place names, leaked passwords others have seen and/or cracked (Gawker, Rockyou, etc.). Many cracking tools also come with dictionaries, including the Backtrack linux distribution. If you're going to look for these, keep your antivirus software up to date, try to stay on what appear to be major security, government, or educational sites and try to only download text files or compressed text files; take a look inside before decompressing.
USE [YourDB]
GO
CREATE TABLE [dbo].[YourPasswordList_LowercaseOnly](
[Password] [varchar](255) NOT NULL,
CONSTRAINT [PK_YourPasswordList_LowercaseOnly] PRIMARY KEY CLUSTERED
(
[Password] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = ON, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Fill [YourPasswordList_LowercaseOnly] from your favorite sources
GO
CREATE PROCEDURE [dbo].[YourNamingConvention_IsBadPassword]
@Password [varchar](255),
@Username [varchar](255) = NULL,
@Firstname [varchar](255) = NULL,
@Lastname [varchar](255) = NULL,
@Email [varchar](255) = NULL,
@IsBad [bit] OUTPUT,
@Message [varchar](255) OUTPUT
WITH EXECUTE AS CALLER
AS
/*
DECLARE @IsBadOut BIT
DECLARE @MessageOut VARCHAR(255)
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '@Password123!!'
,@email = 'MyEmail@domain.tld'
,@firstname = 'John'
,@lastname = 'James'
,@username = 'Bob'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'J&áN>A-,ë4^¯j[#÷ŸÚQÈ«pzKÏÇßüÒxÐ'
,@email = 'Ancient@BonestrewnCrest.org'
,@firstname = 'Jane'
,@lastname = 'Adriel'
,@username = 'Carol'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'shrt3t'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'pa$$w0rd'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'pa$$w0rd2000'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'pa$$w0rd123'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'password1;'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'nevar, ky123'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '}rhundrede805'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '}rhundredeabc'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '08/15/2011'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'Sep 15 2011 00:00:00'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '08/15/2011aldsfjlasfj'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'use6rname1$'
,@username = 'use6rname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@username = 'usadsfADSFArname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@lastname = 'use6rname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@lastname = 'usadsfADSFArname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@firstname = 'use6rname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@firstname = 'usadsfADSFArname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@email = 'use6rname'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@email = 'use6rname@bob.com'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'QQQQuse6rname1$'
,@email = 'usadsfADSFArname@bob.com'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = '%8a1|0o|/|s2'
,@email = 'usadsfADSFArname@bob.com'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'P@ssword'
,@email = 'usadsfADSFArname@bob.com'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
EXEC YourDB.[dbo].[YourNamingConvention_IsBadPassword]
@Password = 'vVozniak1'
,@email = 'usadsfADSFArname@bob.com'
,@IsBad = @IsBadOut OUTPUT
,@Message = @MessageOut OUTPUT
SELECT @IsBadOut, @MessageOut
*/
SET @IsBad = 0; -- default to good
SET @Message = 'Acceptable, though 14 characters or more is better.'
DECLARE @PWTrim VARCHAR(255);
DECLARE @PWTrimLow VARCHAR(255);
DECLARE @PWTrimLowLeftBut1 VARCHAR(255);
DECLARE @PWTrimLowLeftBut2 VARCHAR(255);
DECLARE @PWTrimLowLeftBut3Num VARCHAR(255);
DECLARE @PWTrimLowLeftBut4Num VARCHAR(255);
DECLARE @PWTrimLowRightBut1 VARCHAR(255);
DECLARE @PWTrimLowRightBut1LeftBut1 VARCHAR(255);
DECLARE @PWNoLetterNumber VARCHAR(255);
DECLARE @PWLeetTempLow VARCHAR(255);
DECLARE @PWLeetTempLowLeftBut1 VARCHAR(255);
DECLARE @PWLeetTempLowLeftBut2 VARCHAR(255);
DECLARE @PWLeetTempLowRightBut1 VARCHAR(255);
DECLARE @PWLeetTempLowRightBut1LeftBut1 VARCHAR(255);
DECLARE @PWLeetTempLowLeftBut3Num VARCHAR(255);
DECLARE @PWLeetTempLowLeftBut4Num VARCHAR(255);
DECLARE @HasUpper BIT;
SET @HasUpper = 0
DECLARE @HasLower BIT;
SET @HasLower = 0
DECLARE @HasNumber BIT;
SET @HasNumber = 0
DECLARE @HasSymbol BIT;
SET @HasSymbol = 0
SET @PWTrim = LTRIM(RTRIM(@Password));
SET @PWTrimLow = LOWER(@PWTrim);
IF LEN(@PWTrimLow) < 8
BEGIN
SET @IsBad = 1;
SET @Message = 'This password is far too short. 8 characters is the minimum, though 14 or more characters is much better.'
RETURN;
END
ELSE IF LEN(@PWTrimLow) >= 14
SET @Message = 'Good!'
SET @PWTrimLowLeftBut1 = LEFT(@PWTrimLow,LEN(@PWTrimLow)-1)
SET @PWTrimLowLeftBut2 = LEFT(@PWTrimLow,LEN(@PWTrimLow)-2)
IF ISNUMERIC(RIGHT(@PWTrimLow,3)+'0.0e0') = 1
SET @PWTrimLowLeftBut3Num = LEFT(@PWTrimLow,LEN(@PWTrimLow)-3)
IF ISNUMERIC(RIGHT(@PWTrimLow,4)+'0.0e0') = 1
SET @PWTrimLowLeftBut4Num = LEFT(@PWTrimLow,LEN(@PWTrimLow)-4)
SET @PWTrimLowRightBut1 = RIGHT(@PWTrimLow,LEN(@PWTrimLow)-1)
SET @PWTrimLowRightBut1LeftBut1 = LEFT(@PWTrimLowRightBut1,LEN(@PWTrimLowRightBut1)-1)
IF @PWTrim COLLATE Latin1_General_BIN LIKE '%[A-Z]%' COLLATE Latin1_General_BIN
SET @HasUpper = 1;
IF @PWTrim COLLATE Latin1_General_BIN LIKE '%[a-z]%' COLLATE Latin1_General_BIN
SET @HasLower = 1;
IF @PWTrim LIKE '%[0-9]%'
SET @HasNumber = 1;
SET @PWNoLetterNumber = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow,'a',''),'b',''),'c',''),'d',''),'e',''),'f',''),'g',''),'h',''),'i',''),'j',''),'k',''),'l',''),'m',''),'n',''),'o',''),'p',''),'q',''),'r',''),'s',''),'t',''),'u',''),'v',''),'w',''),'x',''),'y',''),'z',''),'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''),'8',''),'9','')
IF LEN(@PWNoLetterNumber) > 0
SET @HasSymbol = 1;
IF CAST(@HasUpper AS TINYINT) + CAST(@HasLower AS TINYINT) + CAST(@HasNumber AS TINYINT) + CAST(@HasSymbol AS TINYINT) < 3
BEGIN
SET @IsBad = 1;
SET @Message = 'Your password must contain at least 3 of the following: Upper case, Lower case, Numbers, and Symbols.';
RETURN;
END
IF IsDate(@PWTrimLow) = 1
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a date; do not choose dates as passwords.';
RETURN;
END
IF @PWTrimLow LIKE '%' + @Username + '%'
BEGIN
SET @IsBad = 1;
SET @Message = 'Do not have your username as part of your password.';
RETURN;
END
IF @PWTrimLow LIKE '%' + @Firstname + '%'
BEGIN
SET @IsBad = 1;
SET @Message = 'Do not have your first name as part of your password.';
RETURN;
END
IF @PWTrimLow LIKE '%' + @Lastname + '%'
BEGIN
SET @IsBad = 1;
SET @Message = 'Do not have your last name as part of your password.';
RETURN;
END
IF @PWTrimLow LIKE '%' + @email + '%'
BEGIN
SET @IsBad = 1;
SET @Message = 'Do not have your email address as part of your password.';
RETURN;
END
IF @PWTrimLow LIKE '%' + LEFT(@email,CHARINDEX('@',@email)-1) + '%'
BEGIN
SET @IsBad = 1;
SET @Message = 'Do not have your email address as part of your password.';
RETURN;
END
-- It passes basic rules; now let's see if it or simple variations of it are common.
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLow)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password, and is in common cracking dictionaries.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowLeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password plus a character, and is vulnerable to dictionary + suffix attacks.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowRightBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password, and is vulnerable to prefix + dictionary attacks.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowLeftBut2)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password plus two characters, and is vulnerable to dictionary + suffix attacks.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowRightBut1LeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password plus a character, and is vulnerable to prefix + dictionary + suffix attacks.';
RETURN;
END
IF @PWTrimLowLeftBut3Num IS NOT NULL
BEGIN --IF @PWTrimLowLeftBut3Num IS NOT NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password plus three numbers, and is vulnerable to dictionary + suffix attacks.';
RETURN;
END
-- The last 3 are numbers or @; let's see if there's 4, and they're a common year!
IF @PWTrimLowLeftBut4Num IS NOT NULL
IF RIGHT(@PWTrimLow,4) BETWEEN '1900' AND '2035'
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWTrimLowLeftBut4Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password plus a common year, and is vulnerable to dictionary + suffix attacks.';
RETURN;
END
END --IF @PWTrimLowLeftBut3Num IS NOT NULL
-- NOTE the Leet speak translations are very primitive, and will let a lot through.
-- That said, they should catch a few of the most common single letter replacements, trivial replacements, and perhaps some complete replacements.
-- Better than nothing; if this catches it, John the ripper or hashcat with a good ruleset will certainly catch it!
-- First leet translation.
SET @PWLeetTempLow = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
SET @PWLeetTempLowLeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
SET @PWLeetTempLowLeftBut2 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut2,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
SET @PWLeetTempLowRightBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
SET @PWLeetTempLowRightBut1LeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1LeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
IF @PWTrimLowLeftBut3Num IS NOT NULL
SET @PWLeetTempLowLeftBut3Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut3Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
ELSE
SET @PWLeetTempLowLeftBut3Num = NULL
IF @PWTrimLowLeftBut4Num IS NOT NULL
SET @PWLeetTempLowLeftBut4Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut4Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i')
ELSE
SET @PWLeetTempLowLeftBut4Num = NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLow)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to common cracking dictionaries with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut2)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus two characters, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to prefix + dictionary attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1LeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to prefix + dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF @PWTrimLowLeftBut3Num IS NOT NULL
BEGIN --IF @PWTrimLowLeftBut3Num IS NOT NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus three numbers, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
-- The last 3 are numbers or @; let's see if there's 4, and they're a common year!
IF @PWTrimLowLeftBut4Num IS NOT NULL
IF RIGHT(@PWTrimLow,4) BETWEEN '1900' AND '2035'
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a common year, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
END --IF @PWTrimLowLeftBut3Num IS NOT NULL
-- Second leet translation; | means l instead of i.
SET @PWLeetTempLow = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
SET @PWLeetTempLowLeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
SET @PWLeetTempLowLeftBut2 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut2,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
SET @PWLeetTempLowRightBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
SET @PWLeetTempLowRightBut1LeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1LeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
IF @PWTrimLowLeftBut3Num IS NOT NULL
SET @PWLeetTempLowLeftBut3Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut3Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
ELSE
SET @PWLeetTempLowLeftBut3Num = NULL
IF @PWTrimLowLeftBut4Num IS NOT NULL
SET @PWLeetTempLowLeftBut4Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut4Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l')
ELSE
SET @PWLeetTempLowLeftBut4Num = NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLow)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to common cracking dictionaries with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut2)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus two characters, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to prefix + dictionary attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1LeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to prefix + dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF @PWTrimLowLeftBut3Num IS NOT NULL
BEGIN --IF @PWTrimLowLeftBut3Num IS NOT NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus three numbers, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
-- The last 3 are numbers or @; let's see if there's 4, and they're a common year!
IF @PWTrimLowLeftBut4Num IS NOT NULL
IF RIGHT(@PWTrimLow,4) BETWEEN '1900' AND '2035'
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a common year, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
END --IF @PWTrimLowLeftBut3Num IS NOT NULL
-- Third leet translation, vv means w
SET @PWLeetTempLow = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
SET @PWLeetTempLowLeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
SET @PWLeetTempLowLeftBut2 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut2,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
SET @PWLeetTempLowRightBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
SET @PWLeetTempLowRightBut1LeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1LeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
IF @PWTrimLowLeftBut3Num IS NOT NULL
SET @PWLeetTempLowLeftBut3Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut3Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
ELSE
SET @PWLeetTempLowLeftBut3Num = NULL
IF @PWTrimLowLeftBut4Num IS NOT NULL
SET @PWLeetTempLowLeftBut4Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut4Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','i'),'vv','w')
ELSE
SET @PWLeetTempLowLeftBut4Num = NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLow)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to common cracking dictionaries with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut2)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus two characters, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to prefix + dictionary attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1LeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to prefix + dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF @PWTrimLowLeftBut3Num IS NOT NULL
BEGIN --IF @PWTrimLowLeftBut3Num IS NOT NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus three numbers, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
-- The last 3 are numbers or @; let's see if there's 4, and they're a common year!
IF @PWTrimLowLeftBut4Num IS NOT NULL
IF RIGHT(@PWTrimLow,4) BETWEEN '1900' AND '2035'
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a common year, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
END --IF @PWTrimLowLeftBut3Num IS NOT NULL
-- Fourth leet translation; | means l instead of i, and vv means w
SET @PWLeetTempLow = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
SET @PWLeetTempLowLeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
SET @PWLeetTempLowLeftBut2 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut2,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
SET @PWLeetTempLowRightBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
SET @PWLeetTempLowRightBut1LeftBut1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowRightBut1LeftBut1,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
IF @PWTrimLowLeftBut3Num IS NOT NULL
SET @PWLeetTempLowLeftBut3Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut3Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
ELSE
SET @PWLeetTempLowLeftBut3Num = NULL
IF @PWTrimLowLeftBut4Num IS NOT NULL
SET @PWLeetTempLowLeftBut4Num = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLowLeftBut4Num,'@','a'),'/-\','a'),'4','a'),'8','b'),'|)','d'),'1)','d'),'3','e'),'|=','f'),'6','g'),'|-|','h'),'_/','j'),'|<','k'),'|\/|','m'),'/\/\','m'),'\/\/','w'),'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n'),'0','o'),'|>','p'),'&','q'),'|2','r'),'5','s'),'$','s'),'7','t'),'|_|','u'),'><','x'),'''/','y'),'\/','v'),'2','z'),'1','l'),'(','c'),'!','i'),'|','l'),'vv','w')
ELSE
SET @PWLeetTempLowLeftBut4Num = NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLow)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to common cracking dictionaries with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut2)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus two characters, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution, and is vulnerable to prefix + dictionary attacks with l337 translation rules.';
RETURN;
END
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowRightBut1LeftBut1)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a character plus a well known password with a simple leet speak (l337 speak) substitution plus a character, and is vulnerable to prefix + dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
IF @PWTrimLowLeftBut3Num IS NOT NULL
BEGIN --IF @PWTrimLowLeftBut3Num IS NOT NULL
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus three numbers, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
-- The last 3 are numbers or @; let's see if there's 4, and they're a common year!
IF @PWTrimLowLeftBut4Num IS NOT NULL
IF RIGHT(@PWTrimLow,4) BETWEEN '1900' AND '2035'
IF EXISTS(SELECT * FROM YourDB.dbo.YourPasswordList_LowercaseOnly WITH (nolock) WHERE Password = @PWLeetTempLowLeftBut3Num)
BEGIN
SET @IsBad = 1;
SET @Message = 'This is a well known password with a simple leet speak (l337 speak) substitution plus a common year, and is vulnerable to dictionary + suffix attacks with l337 translation rules.';
RETURN;
END
END --IF @PWTrimLowLeftBut3Num IS NOT NULL
/*
First Leet translation:
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PWTrimLow
,'@','a'),'/-\','a'),'4','a')
,'8','b')
,'|)','d'),'1)','d')
,'3','e')
,'|=','f')
,'6','g')
,'|-|','h')
,'_/','j')
,'|<','k')
,'|\/|','m'),'/\/\','m')
,'\/\/','w')
,'/\/','n'),'|\|','n'),'|/|','n'),'1\1','n')
,'0','o')
,'|>','p')
,'&','q')
,'|2','r')
,'5','s'),'$','s')
,'7','t')
,'|_|','u')
,'><','x')
,'''/','y')
,'\/','v')
,'2','z')
,'1','l')
,'(','c')
,'!','i'),'|','i')
Multiuse:
| i l
Ordering:
/\/ - m inside w inside n inside v
*/
GO
P.S. Failing to account for Moore's Law is the #2 failing I've seen in most password strength estimates. Failing to account for hybrid dictionary + rule attacks is, of course, the #1 failing ("Password123#" - upper case, lower case, numbers, symbols, 12 characters long... and almost as pathetic a password as you'll ever see, since Password123 is itself in most cracking dictionaries, and adding a character at the end is one of the first rules you'll see).
P.P.S. For a brief example of a small variety of what hybrid dictionary attacks can do, see the Hashcat Wiki rule_based_attack page. Note there are available rulesets for "keywalking" as well! Note that the Hashcat tools are only free for noncommercial use; for commercial use, please contact the author for permission.
P.P.P.S. Even leaving aside hybrid dictionary attacks, and assuming a user uses a purely random password (a good generator, rolling dice, etc.), for pure brute force, here are some rough guesses based on Moore's Law/computer power doubling every 18 months; these illustrate the premise that overall keyspace (number of possible characters^length) trumps all else, though number of iterations can provide a good buffer in the short term:
8 char, Upper/Lower/Number, 1xSHA1, 100x$3500 machine: 3 minutes
8 char, Upper/Lower/Number, 1xSHA1, $3500 machine: 4 hours
8 char, Upper/Lower/Number, 32768xSHA1, $3500 machine: 5 years
8 char, Upper/Lower/Number, 262144xSHA1, $3500 machine: 10 years
10 char, Upper/Lower/Number, 1xSHA1, 100x$3500 machine: 6 days
10 char, Upper/Lower/Number, 1xSHA1, $3500 machine: less than 2 years
10 char, Upper/Lower/Number, 32768xSHA1, $3500 machine: 23 years
10 char, Upper/Lower/Number, 262144xSHA1, $3500 machine: 28 years
14 char, Upper/Lower/Number, 1xSHA1, 100x$3500 machine: 26 years
14 char, Upper/Lower/Number, 1xSHA1, $3500 machine: 36 years
14 char, Upper/Lower/Number, 32768xSHA1, $3500 machine: 59 years
14 char, Upper/Lower/Number, 262144xSHA1, $3500 machine: 63 years
32 char, Upper/Lower/Number, 1xSHA1, 100x$3500 machine: 187 years
32 char, Upper/Lower/Number, 1xSHA1, $3500 machine: 197 years
32 char, Upper/Lower/Number, 32768xSHA1, $3500 machine: 220 years
32 char, Upper/Lower/Number, 262144xSHA1, $3500 machine: 224 years
128 char, Upper/Lower/Number, 1xSHA1, 100x$3500 machine: 1045 years
128 char, Upper/Lower/Number, 1xSHA1, $3500 machine: 1054 years
8 char, Upper/Lower/Number/Parts of Printable Extended ASCII (total 152 possibilities per character), 1xSHA1, $3500 machine: 6 months
10 char, Upper/Lower/Number/Parts of Printable Extended ASCII (total 152 possibilities per character), 1xSHA1, $3500 machine: 20 years
14 char, Upper/Lower/Number/Parts of Printable Extended ASCII (total 152 possibilities per character), 1xSHA1, $3500 machine: 63 years
NOTE: Upper/Lower/Number was chosen because A) people tend to prefer numbers to symbols when given the choice, B) most people choose from less than 10 symbols most of the time, even when they use symbols, and C) Various and sundry software has various and sundry requirements for various and sundry symbols, some require escaping ', some require escaping ", some require escaping [], some require escaping {}, and almost no software properly escapes any of these.
P.P.P.P.S. If anyone would like to improve the l337 speak translation rules in the code above, please feel free to do so! The current copy/paste of the section once for every l337 speak variant is a horrifically bad way of implementing this. Any other improvements would also be welcome.
January 30, 2012 at 1:34 pm
Nadrek (1/30/2012)
Good, modern password security is often considered either "too cumbersome" for users, or "too CPU intensive";...
Wow, excellent writeup. Nice rules of thumb as well.
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply