|
Post by tsh73 on Apr 12, 2019 8:08:06 GMT -5
Hmm interesting. That's because closing window does not end program... Now this will end it - but does you need it this way?
else IncorrectTries = IncorrectTries + 1 #Pass.pw, "!selectall" if IncorrectTries = 3 then notice "Too many failed attempts! Program will Exit." close #Pass end 'ends program so next Notice will not fire end if notice "The password you entered is incorrect! Please try again." end if
EDIT better code structure helps
IncorrectTries = IncorrectTries + 1 #Pass.pw, "!selectall" if IncorrectTries = 3 then notice "Too many failed attempts! Program will Exit." close #Pass 'end else notice "The password you entered is incorrect! Please try again." end if
|
|
|
Post by Mark Dunham on Apr 12, 2019 9:37:55 GMT -5
Hmm interesting. That's because closing window does not end program... Now this will end it - but does you need it this way? else IncorrectTries = IncorrectTries + 1 #Pass.pw, "!selectall" if IncorrectTries = 3 then notice "Too many failed attempts! Program will Exit." close #Pass end 'ends program so next Notice will not fire end if notice "The password you entered is incorrect! Please try again." end if
EDIT better code structure helps IncorrectTries = IncorrectTries + 1 #Pass.pw, "!selectall" if IncorrectTries = 3 then notice "Too many failed attempts! Program will Exit." close #Pass 'end else notice "The password you entered is incorrect! Please try again." end if
I just saw that I did not end the program. I would have to think how I would actually want it to function. I don't think I would need it that way I guess it's all preference.
|
|
|
Post by tenochtitlanuk on Apr 12, 2019 11:46:29 GMT -5
Some interesting ideas here on password protection and validating inputs.
BUT, a caution, anyone can list BASIC bas file, if provided, and it is not that difficult to read the text string for the password from a tkn file either. And NO, I won't show you how!
It may be more practical to obfuscate your code ( misdirect hackers) or make it self-delete if three tries fail. Examples on my website...
|
|
|
Post by Mark Dunham on Apr 12, 2019 12:40:16 GMT -5
Some interesting ideas here on password protection and validating inputs. BUT, a caution, anyone can list BASIC bas file, if provided, and it is not that difficult to read the text string for the password from a tkn file either. And NO, I won't show you how! It may be more practical to obfuscate your code ( misdirect hackers) or make it self-delete if three tries fail. Examples on my website... Would storing the password in an array make it more secure? Of course in live version the password variable will be called something totally misleading like "BoxWidth" or "Banana" you get the point. I like the idea of deleting the password on failed attempts but also would want to make sure we have a recovery system in place as well.
|
|
|
Post by Chris Iverson on Apr 12, 2019 12:47:43 GMT -5
Some interesting ideas here on password protection and validating inputs. BUT, a caution, anyone can list BASIC bas file, if provided, and it is not that difficult to read the text string for the password from a tkn file either. And NO, I won't show you how! It may be more practical to obfuscate your code ( misdirect hackers) or make it self-delete if three tries fail. Examples on my website... Obfuscation and self-deletion can still be worked around. Would storing the password in an array make it more secure? Of course in live version the password variable will be called something totally misleading like "BoxWidth" or "Banana" you get the point. I like the idea of deleting the password on failed attempts but also would want to make sure we have a recovery system in place as well. Wouldn't help too much, as you'd still have to compare the input against the password on file. Once you know what you're comparing against, it's easy to figure out what data it actually is. The best thing to do is to protect the password itself. And the best way to do that is to use the same techniques always recommend for password storage: DON'T store the password. Store a unique encoded form that cannot be reverse-engineered. In other words, a hash. Use something like below, and only save the hash of your chosen password in your program. Then, regenerate the hash when you want to check it, and compare it to what you've saved. (The correct password in this example is just the word "test".) print GetSHA256Hash$("test")
passwordHash$ = "9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08" Input "Enter password. >";pass$
inpHash$ = GetSHA256Hash$(pass$)
if inpHash$ <> passwordHash$ then print "Password invalid!" else print "Correct password!" End if
'===================================== ' HELPER FUNCTIONS '=====================================
Sub InitCrypto Open "crypt32.dll" for DLL as #crypt32 open "advapi32.dll" for DLL as #cryptadvapi32
Global CRYPT.STRING.BASE64HEADER CRYPT.STRING.BASE64HEADER = 0
Global CRYPT.STRING.BASE64 CRYPT.STRING.BASE64 = 1
Global CRYPT.STRING.BASE64REQUESTHEADER CRYPT.STRING.BASE64REQUESTHEADER = 3
Global CRYPT.STRING.HEX CRYPT.STRING.HEX = 4
Global CRYPT.STRING.HEXASCII CRYPT.STRING.HEXASCII = 5
Global MS.ENH.RSA.AES.PROV$ MS.ENH.RSA.AES.PROV$ = "Microsoft Enhanced RSA and AES Cryptographic Provider"
Global CALG.AES.256 CALG.AES.256 = hexdec("6610")
Global CALG.RSA.SIGN CALG.RSA.SIGN = hexdec("2400")
Global CALG.RSA.KEYX CALG.RSA.KEYX = hexdec("a400")
Global CALG.SHA.256 CALG.SHA.256 = hexdec("800c")
Global PROV.RSA.AES PROV.RSA.AES = 24
Global HP.HASHSIZE HP.HASHSIZE = 4
Global HP.HASHVAL HP.HASHVAL = 2
Global ERROR.MORE.DATA ERROR.MORE.DATA = 234
Global CRYPT.EXPORTABLE CRYPT.EXPORTABLE = 1
Global SIMPLEBLOB SIMPLEBLOB = 1
Global PUBLICKEYBLOB PUBLICKEYBLOB = 6
Global PRIVATEKEYBLOB PRIVATEKEYBLOB = 7
Global PLAINTEXTKEYBLOB PLAINTEXTKEYBLOB = 8
Global AES.BLOCK.SIZE AES.BLOCK.SIZE = 16
Global AT.KEYEXCHANGE AT.KEYEXCHANGE = 1
Global AT.SIGNATURE AT.SIGNATURE = 2
Global RSA2048BIT.KEY RSA2048BIT.KEY = hexdec("08000000")
Global CRYPT.VERIFYCONTEXT CRYPT.VERIFYCONTEXT = hexdec("F0000000") End Sub
Sub EndCrypto Close #crypt32 close #cryptadvapi32 End Sub
Function GetLastError() CallDLL #kernel32, "GetLastError",_ GetLastError as long End Function
Function GetRSAAESContext() hProv = 0 a = CryptAcquireContext(hProv, "", MS.ENH.RSA.AES.PROV$, PROV.RSA.AES, CRYPT.VERIFYCONTEXT) If a = 0 then GetRSAAESContext = 0 Else GetRSAAESContext = hProv End If End Function
Function GetSHA256Hash$(pData$) Call InitCrypto
hProv = GetRSAAESContext() if hProv = 0 then goto [exit]
DeriveAES256Key = 0 hHash = 0
noKey = 0 'SHA256 is not a keyed algorithm, so we pass 0 noFlags = 0 'We are not using any flags for this hash if ( CryptCreateHash(hProv, CALG.SHA.256, noKey, noFlags, hHash) = 0) then 'Hash creation failed. goto [exit] end if
lenData = len(pData$)
if ( CryptHashData(hHash, pData$, lenData, noFlags) = 0 ) then 'Hash data failed. goto [DHexit] end if
'Now we need to retrieve the hash. hashSize = 0 if ( CryptGetHashSize(hHash, hashSize) = 0 ) then goto [DHexit] end if
hashBufLen = hashSize hashBuf$ = space$(hashBufLen) if ( CryptGetHashValue(hHash, hashBuf$, hashBufLen) = 0 ) then goto [DHexit] end if
hashVal = 0 for x = 1 to hashBufLen hashVal = (hashVal * 256) + asc(mid$(hashBuf$, x, 1)) next x
GetSHA256Hash$ = dechex$(hashVal)
[DHexit] 'Clear memory for hash when we're done with it a = CryptDestroyHash(hHash) a = CryptReleaseContext(hProv)
[exit] Call EndCrypto End Function
Function CryptAcquireContext(byref hProv, pContainer$, pProvider$, dwProvType, dwFlags) struct a, hProv as ulong
a.hProv.struct = hProv
if pContainer$ = "" then CallDLL #cryptadvapi32, "CryptAcquireContextA",_ a as struct,_ _NULL as ulong,_ pProvider$ as ptr,_ dwProvType as long,_ dwFlags as long,_ CryptAcquireContext as long else CallDLL #cryptadvapi32, "CryptAcquireContextA",_ a as struct,_ pContainer$ as ptr,_ pProvider$ as ptr,_ dwProvType as long,_ dwFlags as long,_ CryptAcquireContext as long end if
hProv = a.hProv.struct End Function
Function CryptCreateHash(hProv, algId, hKey, dwFlags, byref pHash) struct a, pHash as ulong
CallDLL #cryptadvapi32, "CryptCreateHash",_ hProv as ulong,_ algId as long,_ hKey as ulong,_ dwFlags as long,_ a as struct,_ CryptCreateHash as long
pHash = a.pHash.struct End Function
Function CryptDestroyHash(hHash) CallDLL #cryptadvapi32, "CryptDestroyHash",_ hHash as ulong,_ CryptDestroyHash as long End Function
Function CryptHashData(hHash, pData$, dataLen, dwFlags) CallDLL #cryptadvapi32, "CryptHashData",_ hHash as ulong,_ pData$ as ptr,_ dataLen as long,_ dwFlags as long,_ CryptHashData as long End Function
Function CryptGetHashSize(hHash, byref bSize) struct a, bSize as long
struct b, size as long
b.size.struct = len(a.struct)
CallDLL #cryptadvapi32, "CryptGetHashParam",_ hHash as ulong,_ HP.HASHSIZE as long,_ a as struct,_ b as struct,_ 0 as long,_ CryptGetHashSize as long
bSize = a.bSize.struct End Function
Function CryptGetHashValue(hHash, byref pData$, byref pDataLen) struct a, pDataLen as long a.pDataLen.struct = pDataLen
CallDLL #cryptadvapi32, "CryptGetHashParam",_ hHash as ulong,_ HP.HASHVAL as long,_ pData$ as ptr,_ a as struct,_ 0 as long,_ CryptGetHashValue as long
pDataLen = a.pDataLen.struct End Function
Function CryptReleaseContext(hProv) CallDLL #cryptadvapi32, "CryptReleaseContext",_ hProv as ulong,_ 0 as long,_ CryptReleaseContext as long End Function
|
|
|
Post by Mark Dunham on Apr 12, 2019 12:53:52 GMT -5
Some interesting ideas here on password protection and validating inputs. BUT, a caution, anyone can list BASIC bas file, if provided, and it is not that difficult to read the text string for the password from a tkn file either. And NO, I won't show you how! It may be more practical to obfuscate your code ( misdirect hackers) or make it self-delete if three tries fail. Examples on my website... Obfuscation and self-deletion can still be worked around. Would storing the password in an array make it more secure? Of course in live version the password variable will be called something totally misleading like "BoxWidth" or "Banana" you get the point. I like the idea of deleting the password on failed attempts but also would want to make sure we have a recovery system in place as well. Wouldn't help too much, as you'd still have to compare the input against the password on file. Once you know what you're comparing against, it's easy to figure out what data it actually is. The best thing to do is to protect the password itself. And the best way to do that is to use the same techniques always recommend for password storage: DON'T store the password. Store a unique encoded form that cannot be reverse-engineered. In other words, a hash. Use something like below, and only save the hash of your chosen password in your program. Then, regenerate the hash when you want to check it, and compare it to what you've saved. (The correct password in this example is just the word "test".) print GetSHA256Hash$("test")
passwordHash$ = "9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08" Input "Enter password. >";pass$
inpHash$ = GetSHA256Hash$(pass$)
if inpHash$ <> passwordHash$ then print "Password invalid!" else print "Correct password!" End if
'===================================== ' HELPER FUNCTIONS '=====================================
Sub InitCrypto Open "crypt32.dll" for DLL as #crypt32 open "advapi32.dll" for DLL as #cryptadvapi32
Global CRYPT.STRING.BASE64HEADER CRYPT.STRING.BASE64HEADER = 0
Global CRYPT.STRING.BASE64 CRYPT.STRING.BASE64 = 1
Global CRYPT.STRING.BASE64REQUESTHEADER CRYPT.STRING.BASE64REQUESTHEADER = 3
Global CRYPT.STRING.HEX CRYPT.STRING.HEX = 4
Global CRYPT.STRING.HEXASCII CRYPT.STRING.HEXASCII = 5
Global MS.ENH.RSA.AES.PROV$ MS.ENH.RSA.AES.PROV$ = "Microsoft Enhanced RSA and AES Cryptographic Provider"
Global CALG.AES.256 CALG.AES.256 = hexdec("6610")
Global CALG.RSA.SIGN CALG.RSA.SIGN = hexdec("2400")
Global CALG.RSA.KEYX CALG.RSA.KEYX = hexdec("a400")
Global CALG.SHA.256 CALG.SHA.256 = hexdec("800c")
Global PROV.RSA.AES PROV.RSA.AES = 24
Global HP.HASHSIZE HP.HASHSIZE = 4
Global HP.HASHVAL HP.HASHVAL = 2
Global ERROR.MORE.DATA ERROR.MORE.DATA = 234
Global CRYPT.EXPORTABLE CRYPT.EXPORTABLE = 1
Global SIMPLEBLOB SIMPLEBLOB = 1
Global PUBLICKEYBLOB PUBLICKEYBLOB = 6
Global PRIVATEKEYBLOB PRIVATEKEYBLOB = 7
Global PLAINTEXTKEYBLOB PLAINTEXTKEYBLOB = 8
Global AES.BLOCK.SIZE AES.BLOCK.SIZE = 16
Global AT.KEYEXCHANGE AT.KEYEXCHANGE = 1
Global AT.SIGNATURE AT.SIGNATURE = 2
Global RSA2048BIT.KEY RSA2048BIT.KEY = hexdec("08000000")
Global CRYPT.VERIFYCONTEXT CRYPT.VERIFYCONTEXT = hexdec("F0000000") End Sub
Sub EndCrypto Close #crypt32 close #cryptadvapi32 End Sub
Function GetLastError() CallDLL #kernel32, "GetLastError",_ GetLastError as long End Function
Function GetRSAAESContext() hProv = 0 a = CryptAcquireContext(hProv, "", MS.ENH.RSA.AES.PROV$, PROV.RSA.AES, CRYPT.VERIFYCONTEXT) If a = 0 then GetRSAAESContext = 0 Else GetRSAAESContext = hProv End If End Function
Function GetSHA256Hash$(pData$) Call InitCrypto
hProv = GetRSAAESContext() if hProv = 0 then goto [exit]
DeriveAES256Key = 0 hHash = 0
noKey = 0 'SHA256 is not a keyed algorithm, so we pass 0 noFlags = 0 'We are not using any flags for this hash if ( CryptCreateHash(hProv, CALG.SHA.256, noKey, noFlags, hHash) = 0) then 'Hash creation failed. goto [exit] end if
lenData = len(pData$)
if ( CryptHashData(hHash, pData$, lenData, noFlags) = 0 ) then 'Hash data failed. goto [DHexit] end if
'Now we need to retrieve the hash. hashSize = 0 if ( CryptGetHashSize(hHash, hashSize) = 0 ) then goto [DHexit] end if
hashBufLen = hashSize hashBuf$ = space$(hashBufLen) if ( CryptGetHashValue(hHash, hashBuf$, hashBufLen) = 0 ) then goto [DHexit] end if
for x = 1 to hashBufLen GetSHA256Hash$ = GetSHA256Hash$ + right$("00" + dechex$(asc(mid$(hashBuf$, x, 1))), 2) next
[DHexit] 'Clear memory for hash when we're done with it a = CryptDestroyHash(hHash) a = CryptReleaseContext(hProv)
[exit] Call EndCrypto End Function
Function CryptAcquireContext(byref hProv, pContainer$, pProvider$, dwProvType, dwFlags) struct a, hProv as ulong
a.hProv.struct = hProv
if pContainer$ = "" then CallDLL #cryptadvapi32, "CryptAcquireContextA",_ a as struct,_ _NULL as ulong,_ pProvider$ as ptr,_ dwProvType as long,_ dwFlags as long,_ CryptAcquireContext as long else CallDLL #cryptadvapi32, "CryptAcquireContextA",_ a as struct,_ pContainer$ as ptr,_ pProvider$ as ptr,_ dwProvType as long,_ dwFlags as long,_ CryptAcquireContext as long end if
hProv = a.hProv.struct End Function
Function CryptCreateHash(hProv, algId, hKey, dwFlags, byref pHash) struct a, pHash as ulong
CallDLL #cryptadvapi32, "CryptCreateHash",_ hProv as ulong,_ algId as long,_ hKey as ulong,_ dwFlags as long,_ a as struct,_ CryptCreateHash as long
pHash = a.pHash.struct End Function
Function CryptDestroyHash(hHash) CallDLL #cryptadvapi32, "CryptDestroyHash",_ hHash as ulong,_ CryptDestroyHash as long End Function
Function CryptHashData(hHash, pData$, dataLen, dwFlags) CallDLL #cryptadvapi32, "CryptHashData",_ hHash as ulong,_ pData$ as ptr,_ dataLen as long,_ dwFlags as long,_ CryptHashData as long End Function
Function CryptGetHashSize(hHash, byref bSize) struct a, bSize as long
struct b, size as long
b.size.struct = len(a.struct)
CallDLL #cryptadvapi32, "CryptGetHashParam",_ hHash as ulong,_ HP.HASHSIZE as long,_ a as struct,_ b as struct,_ 0 as long,_ CryptGetHashSize as long
bSize = a.bSize.struct End Function
Function CryptGetHashValue(hHash, byref pData$, byref pDataLen) struct a, pDataLen as long a.pDataLen.struct = pDataLen
CallDLL #cryptadvapi32, "CryptGetHashParam",_ hHash as ulong,_ HP.HASHVAL as long,_ pData$ as ptr,_ a as struct,_ 0 as long,_ CryptGetHashValue as long
pDataLen = a.pDataLen.struct End Function
Function CryptReleaseContext(hProv) CallDLL #cryptadvapi32, "CryptReleaseContext",_ hProv as ulong,_ 0 as long,_ CryptReleaseContext as long End Function Chris thanks for the input I will look at incorporating that into my simple example. It leads me to reading more about passwords and password protection which I have never really done before.
|
|
|
Post by tenochtitlanuk on Apr 12, 2019 14:45:50 GMT -5
Thanks Chris for your comments and code. Like Mark I enjoy playing with code for passwording. It's all a matter of staying ahead of the 'opposition'!
|
|