I am looking for a very simple way to encrypt a password so that when it is
written to an inifile that it is not recognisable. Please be aware I am not
looking for an industrial strength algorythm, just a bit of string
manipulation. Has anyone got any code snippets they would be willing to
share?
Thanks
Jon
I assume that you intend storing the 'number' rather than the password
- ie: something that could never be decrypted to the original string
Something like :
Private Sub Command1_Click()
Dim L9%, N&, PW$, Q%
PW$ = Text1.Text
' ---
N = 140956 ' some fixed 'seed'
For L9 = 1 To Len(PW$)
Q = Asc(Mid$(PW$, L9, 1))
N = (N + Q) * 2
Next
N = N Mod 1000000 ' max 6 digits
' ---
Label1.Caption = Str$(N)
End Sub
I am not saying that this is particularly brilliant, but I reckon
you'll get the general idea
It's not. Amusing, though. The reason why is left as an exercise
for the writer.
MD5 (which this isn't) is an example of a so-called cryptographic
hash, which has the additional property of a given hash value being
hard to reproduce. That protects against people who can see your
hash table and set their own password.
Groetjes,
Maarten Wiltink
Wrong NG
What you need is a CRC
- the algorithm and Delphi source is at :
the page to look for is CRC32
If you muck around with the string first, then it would be very hard
for someone unsophisticated to crack it
> I assume that you intend storing the 'number' rather than the password
> - ie: something that could never be decrypted to the original string
Well I will need to decrypt it within the program obviously, but it should
marginally difficult to get the password from whatever is written to the
inifile.
> Something like :
Isn't this VB? I have never used it. I was looking for a Deslphi example.
> Private Sub Command1_Click()
> Dim L9%, N&, PW$, Q%
>
> PW$ = Text1.Text
> ' ---
> N = 140956 ' some fixed 'seed'
> For L9 = 1 To Len(PW$)
> Q = Asc(Mid$(PW$, L9, 1))
> N = (N + Q) * 2
> Next
It looks like you are getting the ascii value for each character? In Delphi
I guess it would be something like...
Q := StrToInt(Ord(PW$[L9]));
> N = N Mod 1000000 ' max 6 digits
Ok I get what you're doing, and I like it, but how whould you convert that
back again?
Jon
> It's not. Amusing, though. The reason why is left as an exercise
> for the writer.
At least he offered some a suggestion. As i said I was not looking for a
cipher worthy of Bletchly Park.
> Aaargh !!!!
> Wrong NG
I did wonder. :-)
> What you need is a CRC
> - the algorithm and Delphi source is at :
> www.jerryfrench.co.uk
> the page to look for is CRC32
I'll take a look. Thanks.
I know you said that. You also said
>Well I will need to decrypt it within the program obviously, but it should
>be marginally difficult to get the password from [the hash]
...Which is why I suggested a cryptographic hash. Because you should be
looking for a "good enough" cipher, and what you have in mind isn't.
Don't rely on the secrecy of the encryption algorithm. It needs only be
broken once.
Don't decrypt passwords. Compare the hashes instead.
Groetjes,
Maarten Wiltink
> Don't rely on the secrecy of the encryption algorithm. It needs only
> be broken once.
I agree, but the level of technical competancy of the prospected users is
extremely low, and the sensivity of the data is not an issue. The password
is simply to stop the inadvertant executuion of a process.
> Don't decrypt passwords. Compare the hashes instead.
If you can offer me any examples of how I might accomplish this, I would be
greatful.
Jon
On Wed, 6 Aug 2003 09:51:25 +0000 (UTC), Jon Hunt <j...@nospam.com>
wrote:
>ere...@nowhere.com (J French) wrote in
Sorry about that - I genuinely thought that you were a VB Newbie
- so I gave the most 'practical' answer
- in a Delphi NG I would have immediately sent you to CRC32
The thing is, as Maarten has also said, you don't decrypt it back into
a string - actually you don't really want to
When the User enters their password, then you run the algorithm on
whatever they entered, and if it comes up with the right Number, then
the chances are 99% that they entered the right password.
Personally I would use the CRC32 algorithm, it matches the one used by
PKZIP which is a recommendation
If you mangle the password a bit, and use an odd 'seed' for the
algorithm, it would be murder to crack
Also CRCs are useful things to have in the armoury ...
> Sorry about that - I genuinely thought that you were a VB Newbie
No, just a newbie. :-)
> - so I gave the most 'practical' answer
> - in a Delphi NG I would have immediately sent you to CRC32
> The thing is, as Maarten has also said, you don't decrypt it back into
> a string - actually you don't really want to
> When the User enters their password, then you run the algorithm on
> whatever they entered, and if it comes up with the right Number, then
> the chances are 99% that they entered the right password.
I see.
> Personally I would use the CRC32 algorithm, it matches the one used by
> PKZIP which is a recommendation
> If you mangle the password a bit, and use an odd 'seed' for the
> algorithm, it would be murder to crack
> Also CRCs are useful things to have in the armoury ...
It seems I will have to study the code as I'm a little lost at first
glance. I thank you for your help.
It might not be so easy tomorrow. Also, some people like to use
only a single password for everything. Their problem of course,
but you know... It needs only be broken once.
>> Don't decrypt passwords. Compare the hashes instead.
>
>If you can offer me any examples of how I might accomplish this, I would
be
>greatful.
When enrolling, a password is entered. A hash is computed and stored.
When verifying, a password is entered. A hash is computed and compared
to the one stored during enrolment. Really, there's no more to it than
that.
Groetjes,
Maarten Wiltink
> When enrolling, a password is entered. A hash is computed and stored.
> When verifying, a password is entered. A hash is computed and compared
> to the one stored during enrolment. Really, there's no more to it than
> that.
This much I can understand. What is beyond me, is the "A hash is computed"
part. A small sentance, but to one who is still atemmpting to learn, a big
job.
Jon
You know how a function works, right? Parameters go in, a return
value comes out.
function JerrysHash(const Text: String): Integer;
var i: Integer;
begin
Result:=140956;
for i:=1 to Length(Text)
do begin
Result:=Result+Ord(Text[i]);
Result:=Result*2;
end
Result:=Result mod 1000000;
end;
Note that this is a _really_, _really_ bad hash function for this
purpose (no offense, Jerry).
To prove this, I will make up the hash value 643987 on the spot by
banging randomly on my keyboard and construct a password that gives
that hash value.
643987 decimal = 1001 1011 0000 0110 1011 binary
Counting from zero, the i'th letter in the password comes out i
bits from the right in this value.
The seed value is
140956 decimal = 10 0010 0110 1001 1100 binary
and this value is shifted left by one bit for every letter in the
password. That leaves
503031 decimal = 111 1010 1100 1111 0111 binary
as the contribution of the letters. That contribution is shifted
left by one bit for every letter before it in the password; since
letters stay under values of 128 they can reach seven bits and I
need twelve letters. I can't make that; I'm going to need that
modulo 1.000.000.
643987
643987
643987
643987
643987
643987
643987
643987
643987
<snip>
>function JerrysHash(const Text: String): Integer;
>var i: Integer;
>begin
> Result:=140956;
>
> for i:=1 to Length(Text)
> do begin
> Result:=Result+Ord(Text[i]);
> Result:=Result*2;
> end
>
> Result:=Result mod 1000000;
>end;
>
>Note that this is a _really_, _really_ bad hash function for this
>purpose (no offense, Jerry).
<snip>
<blank line>
To be fair, it was just a pointer in a direction
- a *good* hashing algorithm is hard to code in VB
- admittedly I got my NGs mixed up .....
> You know how a function works, right? Parameters go in, a return
> value comes out.
Yes.
[cut]
Right I think I understand now. Perhaps I need to study the CRC32 source
that was given to me.
Thanks.
Jon
Some days, Ctrl-Enter is _not_ a convenient key combination.
> ... I will make up the hash value 643987 on the spot by
>banging randomly on my keyboard and construct a password that gives
>that hash value.
>
>643987 decimal = 1001 1011 0000 0110 1011 binary
>
>Counting from zero, the i'th letter in the password comes out i
>bits from the right in this value.
Correction! It's the i'th letter from the right that does. This
is not the first time I've made this mistake. Also, counting
starts at one due to the order of the adding and the multiplying.
>The seed value is
>
>140956 decimal = 10 0010 0110 1001 1100 binary
>
>and this value is shifted left by one bit for every letter in the
>password. That leaves
>
>503031 decimal = 111 1010 1100 1111 0111 binary
>
>as the contribution of the letters. That contribution is shifted
>left by one bit for every letter before it in the password; since
>letters stay under values of 128 they can reach seven bits and I
>need twelve letters. I can't make that; I'm going to need that
>modulo 1.000.000.
I'd like a number that starts with 10001 binary so as many bits as
possible are eliminated and I can choose a short password.
4643987 = 100 0110 1101 1100 1001 0011
8643987 = 1000 0011 1110 0101 1001 0011
17643987 = 1 0000 1101 0011 1001 1101 0011
18643987 = 1 0001 1100 0111 1100 0001 0011
This does not look particularly hopeful. I'll change my strategy
and decide to use a 32-letter password. That way, the seed is
counted out for sure. Again,
The first letter in that 32-letter password is going to come in
with 32 trailing zeroes (because Result is multiplied by 2 once
for every letter following it, and once for itself, too).
I'll note at this point that this hash value can never be generated
because it's odd. So I'll just set the final bit to zero and ignore
this. Hash values that can't occur aren't very useful anyway.
643986 decimal = 00000000 00001001 10110000 01101010 binary
Now, every letter adds in at eight bit positions, barring carries.
I don't want carries, that just makes it harder; in fact, I don't
want those eight positions. I want one bit to think about per letter.
I'll start with this password:
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@".
Every letter supplies a single bit, so its hash should be
01000000 -------- -------- -------- --------
-0100000 0------- -------- -------- --------
--010000 00------ -------- -------- --------
.
.
.
-------- -------- -------- -----010 00000---
-------- -------- -------- ------01 000000--
-------- -------- -------- -------0 1000000-
____________________________________________ +
-------- 11111111 11111111 11111111 10000000
in 32-bit arithmetic. (Dashes are either leading or trailing
zeroes, not don't cares.)
I'll get rid of all those ones first by adding another 128.
This is most conveniently done by adding 32 to the second-to-last
character (which is multiplied by 2 twice), making it a backtick.
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`@"
Now I have a hash of all zeroes. All I need to do is add a
few ones in the right position, like this:
00000000000010011011000001101010
"@@@@@@@@@@@@@A@@AA@AA@@@@@AA@A`A"
It's right, too. I checked.
Note especially that the last bit of adding single bits to a
known starting value can get you a password for any hash value
instantly.
CRCs are slightly more complicated than this, but as easily
cracked by somebody who knows what he's doing.
Groetjes,
Maarten Wiltink
>In article <3f30c299...@news.btclick.com>, ere...@nowhere.com
>says...
>
>8>< /snip
>-> Something like :
>->
>-> Private Sub Command1_Click()
>-> Dim L9%, N&, PW$, Q%
>8>< /snip
>
>Heretic! ;-)
Short sighted git !
- don't rub it in (please)
Actually,
"...this class [CRC32] should NOT be used for security purposes. The CRC32
algorithm can easily be brute forced in minutes. For security applications
use MD5, SHA1..."
(from http://www.codeproject.com/csharp/CRC32_DotNet.asp)
Although I realise you're not looking for a proper cryptographic hash
algorithm, I would suggest that you rather use either MD5 or SHA1. You don't
have to be a rocket scientist to use either of these algorithms, and they
are just as easy as CRC32. Either pick one of the free implementations
floating around, make a few calls to the Windows CryptoAPI (yes your OS
implements them too), or use some 3rd party components (see below...)
I would also recommend adding a short random salt value (8 random bytes is
standard for MD5) to the password before hashing it. Why? There are several
apps that have large tables of passwords and their hashes. By simply
scanning the list of hashes they can find the original password in a matter
of seconds. Adding a bit of salt will make this attack much harder. You may
also repeat the hash (i.e. hash the hash) for a few iterations (up to 100
iterations is sometimes used).
Record the final hash value plus the original salt in your ini file (you can
concatenate them - they both have fixed lengths). It is a good idea to hex
or base-64 encode what you store so that it is human-readable.
So:
salt = randomstring(8);
hash := MD5(password + salt);
for i := 2 to num_iterations do
hash := MD5(hash);
result := hash + salt; // store this
Simple, eh?
--
Paul Urban
Software Engineer
Korbitec R&D
Prof's Crypto Components (Delphi and C++ Builder):
http://www.profscomponents.com/
:: Right I think I understand now. Perhaps I need to study the CRC32
:: source that was given to me.
::
You can also get lockbox from https://sourceforge.net/projects/tplockbox/
which has MD5 hashing and a lot more.
Jaap
<snip>
>
>"...this class [CRC32] should NOT be used for security purposes. The CRC32
>algorithm can easily be brute forced in minutes. For security applications
>use MD5, SHA1..."
The essence of a CRC algorithm is that it should come up with as near
unique 'number' as possible.
What you feed in determines what comes out.
However what you feed in can be 'mangled', so unless the cracker has a
very warped mind it is unlikely that he will 'feed in' the right data
One can also do 'intermediate mangling' as one feeds the data in
The only limitation that I can see with a 32 bit CRC, is that it is 32
bit - of course it could just as well be a number of 32 bit numbers
mashed around
BTW any App that actually stores the password anywhere is just asking
for trouble. As is any App that is open to 'brute force' attacks.
A really devious programmer would also disguise the full Hash ...
Comments below...
"J French" <ere...@nowhere.com> wrote in message
news:3f31ed6...@news.btclick.com...
> On Wed, 6 Aug 2003 21:08:25 +0200, "Paul Urban"
> <pa...@nospam.korbitec.xyz.com> wrote:
>
> <snip>
> >
> >"...this class [CRC32] should NOT be used for security purposes. The
CRC32
> >algorithm can easily be brute forced in minutes. For security
applications
> >use MD5, SHA1..."
>
> The essence of a CRC algorithm is that it should come up with as near
> unique 'number' as possible.
>
> What you feed in determines what comes out.
And any *random* changes in the data should cause the CRC to change. Anyone
can invent a 2-bit checksum, which may be adequate for detecting data
corruption, but not very resistant to brute-forcing!
> However what you feed in can be 'mangled', so unless the cracker has a
> very warped mind it is unlikely that he will 'feed in' the right data
Remember, a determined cracker *could* easily write a little script to do
the work for him. It all depends on how valuable the thing is that you're
trying to protect.
> One can also do 'intermediate mangling' as one feeds the data in
One point about intermediate mangling is that it has to be done carefully,
or you might actually reduce the number of possible hashes/checksums and
actually make it easier to attack.
> The only limitation that I can see with a 32 bit CRC, is that it is 32
> bit - of course it could just as well be a number of 32 bit numbers
> mashed around
In this case the size is probably the biggest problem. It is orders and
orders of magnitude easier to find a password that will hash to the same
value for CRC32 than MD5. In other cases, where a hash is being used to
defeat deliberate tampering with data, the fact that CRC32 is not really
designed to be irreversible is important.
> BTW any App that actually stores the password anywhere is just asking
> for trouble. As is any App that is open to 'brute force' attacks.
Agreed, but sometimes it is unavoidable.
> A really devious programmer would also disguise the full Hash ...
Yes, that would make it a little harder.
> >(from http://www.codeproject.com/csharp/CRC32_DotNet.asp)
> >
> >Although I realise you're not looking for a proper cryptographic hash
> >algorithm, I would suggest that you rather use either MD5 or SHA1. You
don't
> >have to be a rocket scientist to use either of these algorithms, and they
> >are just as easy as CRC32.
[snip]
<hisssssssss!> :)
Cheers,
Nicholas Sherlock