Encyrpting data (like a password)
Encyrpting data (like a password)
Hello all,
I am storing passwords in a database and I would like to encrypt them with just a key of some kind. I have been through the methods and I don't really get them. I need ascii output. I need to be able to encyrpt the password then decypt it later. Both functions.
The passwords are sometimes longer than 8 characters too. Any suggestions? I am looking for the simplest solution. I just need something basic to obsure them in case the database winds up in the wrong hands.
Thanks.
DB
I am storing passwords in a database and I would like to encrypt them with just a key of some kind. I have been through the methods and I don't really get them. I need ascii output. I need to be able to encyrpt the password then decypt it later. Both functions.
The passwords are sometimes longer than 8 characters too. Any suggestions? I am looking for the simplest solution. I just need something basic to obsure them in case the database winds up in the wrong hands.
Thanks.
DB
- DB
Re: Encyrpting data (like a password)
The correct way of doing it is to generate a hash code (i.e. SHA1Fingerprint()) from the password + "salt" (salt being your own random set of characters), and then store that. This way, there is no chance of decrypting the password - the hash is irreversable.
Then on the client you take the password, generate the hash + "salt" and pass that up to the server to compare with what is on the database!
If you require ascii transmission, then also use the Base64 functions to do just that.
Note that you will never be able to recover a password, only replace it with a new one.
Then on the client you take the password, generate the hash + "salt" and pass that up to the server to compare with what is on the database!
If you require ascii transmission, then also use the Base64 functions to do just that.
Note that you will never be able to recover a password, only replace it with a new one.
Re: Encyrpting data (like a password)
Actually I am storing the passwords so that the system logs you on and this is not comparing two hashes. I need to be able to reverse the hash so that the system can send the password to the system it is calling. In other words, I have a tool that allows you to pick a system and it logs you one providing user name and password. So the passwords in the database need to be encrypted and then decrypted for use.
Is there an easy way to do that?
Thanks.
DB
Is there an easy way to do that?
Thanks.
DB
- DB
Re: Encyrpting data (like a password)
Sure, it'll never be completely safe though.
The simplest method is to XOR the string with a key. See this tip here:
http://www.purebasic.fr/english/viewtop ... 12&t=46613
A more secure, though more complex encryption is blowfish:
http://www.purebasic.fr/english/viewtop ... 03#p346403
The simplest method is to XOR the string with a key. See this tip here:
http://www.purebasic.fr/english/viewtop ... 12&t=46613
A more secure, though more complex encryption is blowfish:
http://www.purebasic.fr/english/viewtop ... 03#p346403
- ultralazor
- Enthusiast
- Posts: 186
- Joined: Sun Jun 27, 2010 9:00 am
Re: Encyrpting data (like a password)
keygen off typed pass for some block cipher like aes or twofish, if result equals typed then it's correct..public key connection to prevent MITM via self-signed ssl or cgi rsa..
RSA has export laws though even though most governments have the computing power to brute it in days..
keygen off typed pass is 'proper' though
RSA has export laws though even though most governments have the computing power to brute it in days..
keygen off typed pass is 'proper' though
so many ideas so little time..
Re: Encyrpting data (like a password)
PB has AES functions built in... these should be fine for this. The only catch is their output (and decryption input) is binary data in memory buffers, not normal strings. But like Foz said, you can use the Base64 functions also built in, to convert between binary buffers and decently compact strings. In fact, I would just write "wrapper" procedures that take string inputs and handle the decode / encode / buffer / encrypt / decrypt together.
Re: Encyrpting data (like a password)
I will check it out. It does not have to be all that secure, just obscured. The database is protected by security also.
I was looking for something like,
password = ecyrypt(pw,key)
password = decrypt(pw,key)
Thanks.
DB
I was looking for something like,
password = ecyrypt(pw,key)
password = decrypt(pw,key)
Thanks.
DB
- DB
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Encyrpting data (like a password)
purebuilt, give this a try (password max length: 32 characters):
It's actually reasonably strong, simple as it is. If the user puts more than 32 characters for the password, no error will happen but only the first 32 will count.
Code: Select all
Procedure$ EncryptPassword(password$, key$)
Protected passin$ = LSet(password$, 32, Chr(32)) ; Pad the password with spaces to make 32 characters
Protected keyin$ = LSet(key$, 16, Chr(32)) ; key for 128bit encryption needs length=16
Protected *encodedbinary = AllocateMemory(32) ; 32 bytes for encrypted binary result, see 2 lines down
Protected *encodedtext = AllocateMemory(64) ; Destination for Base64Encoder must be 33% larger- we double it
AESEncoder(@passin$, *encodedbinary, 32, @keyin$, 128, 0, #PB_Cipher_ECB) ; We don't encrypt the trailing zero so 32 bytes is enough
Base64Encoder(*encodedbinary, 32, *encodedtext, 64) ; Convert encrypted binary data to ascii for return
ProcedureReturn PeekS(*encodedtext) ; Return the completed ascii result
EndProcedure
Procedure$ DecryptPassword(password$, key$)
Protected keyin$ = LSet(key$, 16, Chr(32)) ; key for 128bit decryption needs length=16
Protected *encodedbinary = AllocateMemory(33) ; 32 bytes for data + one safety byte
Protected *decodedtext = AllocateMemory(33) ; 32 bytes for characters + one byte for terminating zero
Base64Decoder(@password$, Len(password$), *encodedbinary, 32) ; Convert the ascii encoded password back to binary
AESDecoder(*encodedbinary, *decodedtext, 32, @keyin$, 128, 0, #PB_Cipher_ECB) ; Convert the encrypted password back to original
ProcedureReturn Trim(PeekS(*decodedtext, 32)) ; Remove any trailing spaces and return result
EndProcedure
this$ = EncryptPassword("Holy Smoke, Batman! ", "somekey")
that$ = DecryptPassword(this$, "somekey")
Debug "Encrypted password: "+this$
Debug "Decrypted password: "+that$
BERESHEIT
Re: Encyrpting data (like a password)
@NetMaestro
Many, many thanks !
I've been using these encryption functions, in a similar way, for a long time, but it never occured to me to do...
That combination (and its inverse) makes coding so much simpler. I've just learned something important here.
Great. Thank you for sharing that code.
Many, many thanks !
I've been using these encryption functions, in a similar way, for a long time, but it never occured to me to do...
Code: Select all
[...]
AESEncoder(@passin$, *encodedbinary, 32, @keyin$, 128, 0, #PB_Cipher_ECB) ; ...
Base64Encoder(*encodedbinary, 32, *encodedtext, 64) ; Convert encrypted binary data to ascii for return
[...]
Great. Thank you for sharing that code.
PB Forums : Proof positive that 2 heads (or more...) are better than one 

-
- Enthusiast
- Posts: 536
- Joined: Mon Feb 16, 2009 10:42 am
- Location: sweden
- Contact:
Re: Encyrpting data (like a password)
If you are going to transfer this over a public network, it could be smart to put some extra "salt" on the steak..
Put in something like the date today somewhere... So you know it changes every day.
Put in something like the date today somewhere... So you know it changes every day.
- ultralazor
- Enthusiast
- Posts: 186
- Joined: Sun Jun 27, 2010 9:00 am
Re: Encyrpting data (like a password)
You use meta data and encrypt with the contained password, then check for meta data by decrypting with typed password. Using a cipher like AES it can only be brute forced..
so many ideas so little time..
Re: Encyrpting data (like a password)
Once again netmaestro, one of your fine contributions provides a perfect solution.
I realize I'm a bit late to the party, but just now had the need for something like this.
cheers
I realize I'm a bit late to the party, but just now had the need for something like this.
cheers
-
- Enthusiast
- Posts: 160
- Joined: Wed May 20, 2020 5:19 pm
- Location: The 3rd planet in the Solar System
- Contact:
Re: Encyrpting data (like a password)
This code doesn't work anymore:(netmaestro wrote: Fri Jul 01, 2011 5:19 pm purebuilt, give this a try (password max length: 32 characters):It's actually reasonably strong, simple as it is. If the user puts more than 32 characters for the password, no error will happen but only the first 32 will count.Code: Select all
Procedure$ EncryptPassword(password$, key$) Protected passin$ = LSet(password$, 32, Chr(32)) ; Pad the password with spaces to make 32 characters Protected keyin$ = LSet(key$, 16, Chr(32)) ; key for 128bit encryption needs length=16 Protected *encodedbinary = AllocateMemory(32) ; 32 bytes for encrypted binary result, see 2 lines down Protected *encodedtext = AllocateMemory(64) ; Destination for Base64Encoder must be 33% larger- we double it AESEncoder(@passin$, *encodedbinary, 32, @keyin$, 128, 0, #PB_Cipher_ECB) ; We don't encrypt the trailing zero so 32 bytes is enough Base64Encoder(*encodedbinary, 32, *encodedtext, 64) ; Convert encrypted binary data to ascii for return ProcedureReturn PeekS(*encodedtext) ; Return the completed ascii result EndProcedure Procedure$ DecryptPassword(password$, key$) Protected keyin$ = LSet(key$, 16, Chr(32)) ; key for 128bit decryption needs length=16 Protected *encodedbinary = AllocateMemory(33) ; 32 bytes for data + one safety byte Protected *decodedtext = AllocateMemory(33) ; 32 bytes for characters + one byte for terminating zero Base64Decoder(@password$, Len(password$), *encodedbinary, 32) ; Convert the ascii encoded password back to binary AESDecoder(*encodedbinary, *decodedtext, 32, @keyin$, 128, 0, #PB_Cipher_ECB) ; Convert the encrypted password back to original ProcedureReturn Trim(PeekS(*decodedtext, 32)) ; Remove any trailing spaces and return result EndProcedure this$ = EncryptPassword("Holy Smoke, Batman! ", "somekey") that$ = DecryptPassword(this$, "somekey") Debug "Encrypted password: "+this$ Debug "Decrypted password: "+that$
[14:25:24] [COMPILER] Line 7: Base64Encoder(): Incorrect number of parameters.
Looks like Base64Decoder() and Base64Encoder() were changed.
Mac Studio M1Max, PB 6.12 Arm64 and x64.
Macbook Air M2, PB 6.12 Arm64 and x64.
Windows 10, PB 6.12 x64 and x86.
Macbook Air M2, PB 6.12 Arm64 and x64.
Windows 10, PB 6.12 x64 and x86.
- NicTheQuick
- Addict
- Posts: 1519
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: Encyrpting data (like a password)
When en/decrypting the initialization vector can be used as salt. Before encryption it can be generated using CryptRandomData() and then stored besides the encryted data. Here's a simple example that's meant for strings:jesperbrannmark wrote: Fri Nov 18, 2011 9:01 pm If you are going to transfer this over a public network, it could be smart to put some extra "salt" on the steak..
Put in something like the date today somewhere... So you know it changes every day.
Code: Select all
EnableExplicit
UseSHA2Fingerprint()
UseCRC32Fingerprint()
Structure EncryptedData
iv.a[16]
bits.w
iterations.w
inputSize.l
crc32.l
*data.Byte[0]
EndStructure
Procedure.s EncryptString(string.s, passphrase.s, bits.i = 192, iterations.i = 100)
; Create cryptographic secure inititialization vector
Protected *iv = AllocateMemory(16)
If Not OpenCryptRandom()
DebuggerError("OpenCryptRandom failed.")
ProcedureReturn ""
EndIf
CryptRandomData(*iv, 16)
CloseCryptRandom()
; Derive encryption key from passphrase
Protected *key = AllocateMemory(bits / 8)
If Not DeriveCipherKey(passphrase, Base64Encoder(*iv, 16), iterations, *key, bits, #PB_Cipher_SHA2, 512)
DebuggerError("DeriveCipherKey failed.")
FreeMemory(*iv)
FreeMemory(*key)
ProcedureReturn ""
EndIf
; Pad string if needed
Protected inputSize.i = StringByteLength(string, #PB_UTF8)
If inputSize < 16
string + Space(16 - inputSize)
EndIf
Protected *input = UTF8(string)
Protected inputSizePadded.i = MemorySize(*input) - 1 ; ignore terminating null byte
Protected *output.EncryptedData = AllocateMemory(SizeOf(EncryptedData) + inputSizePadded)
If Not AESEncoder(*input, *output + SizeOf(EncryptedData), inputSizePadded, *key, bits, *iv, #PB_Cipher_CBC)
DebuggerError("AESEncoder failed")
FreeMemory(*iv)
FreeMemory(*key)
FreeMemory(*input)
FreeMemory(*output)
ProcedureReturn ""
EndIf
With *output
CopyMemory(*iv, @\iv, 16)
\inputSize = inputSize
\bits = bits
\iterations = iterations
\crc32 = Val("$" + Fingerprint(*input, inputSizePadded, #PB_Cipher_CRC32))
EndWith
Protected result.s = Base64Encoder(*output, inputSizePadded + SizeOf(EncryptedData))
FreeMemory(*iv)
FreeMemory(*key)
FreeMemory(*input)
FreeMemory(*output)
ProcedureReturn result
EndProcedure
Procedure.s DecryptString(encryptedString.s, passphrase.s)
; Expect the decoded data to be 20% less
Protected expectedInputSize.i = Len(encryptedString) * 4 / 5
Protected *input.EncryptedData = AllocateMemory(expectedInputSize)
Protected realInputSize.i = Base64Decoder(encryptedString, *input, expectedInputSize)
; Check encrypted data size for validity
If realInputSize < SizeOf(EncryptedData) + 16
DebuggerError("encryptedString seems to be too short.")
FreeMemory(*input)
ProcedureReturn ""
EndIf
Protected inputSizePadded.i = realInputSize - SizeOf(EncryptedData)
; Derive encryption key from passphrase
Protected *key = AllocateMemory(*input\bits / 8)
If Not DeriveCipherKey(passphrase, Base64Encoder(@*input\iv, 16), *input\iterations, *key, *input\bits, #PB_Cipher_SHA2, 512)
DebuggerError("DeriveCipherKey failed.")
FreeMemory(*input)
FreeMemory(*key)
ProcedureReturn ""
EndIf
Protected *output = AllocateMemory(inputSizePadded)
If Not AESDecoder(*input + SizeOf(EncryptedData), *output, inputSizePadded, *key, *input\bits, @*input\iv, #PB_Cipher_CBC)
DebuggerError("AESDecoder failed.")
FreeMemory(*output)
FreeMemory(*input)
ProcedureReturn ""
EndIf
FreeMemory(*key)
Protected crc32.l = Val("$" + Fingerprint(*output, inputSizePadded, #PB_Cipher_CRC32))
If crc32 <> *input\crc32
FreeMemory(*output)
FreeMemory(*input)
ProcedureReturn "[WRONG PASSPHRASE]"
EndIf
Protected result.s = PeekS(*output, *input\inputSize, #PB_UTF8 | #PB_ByteLength)
FreeMemory(*output)
FreeMemory(*input)
ProcedureReturn result
EndProcedure
Define encrypted.s = EncryptString("Hello World", "my passphrase", 256)
Debug encrypted
Debug DecryptString(encrypted, "wrong passphrase")
Debug DecryptString(encrypted, "my passphrase")
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.