Recent

Author Topic: Blowfish procedures to encrypt (working) and decrypt (not working)  (Read 22654 times)

robert83a1

  • New Member
  • *
  • Posts: 25
Hi all,
 I am trying to create a procedure that encrypts my passwords using blowfish and then using another procedure decrypts....

 I wrote the following sample program, but for some reason I can't get it decrypted using the decrypt procedure... it works using the DoItAll button which encrypts and decrypts in one run...(but that is not the way)

 
Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  BlowFish;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    mysalt : string;
  end;

const
  chars = 'qwertyuiopasdfghjklzxcvbnm`1234567890-=[];~!@#$%^&*()_+{}:"<>?QWERTYUIOPASDFGHJKLZXCVBNM';
  key = '53285GFDJSLKFJSDLJ*#fefjsdljlk3284-3284-3285632:"<?>{}BXCV#@$GFDgf#@$%#@^H"L"Lgfd#@%#@%K#%#@?:_├ë├ü┼É├Ü┼æ├║├⌐├í├╝├│├╢├ñ├╝+├ƒ┬┤0├û├ä├£';

var
  Form1: TForm1;

procedure Encrypt(const input:string ; out storesalt,crypted : string);
procedure Decrypt(const input,salt: string; out password : string);

implementation

{$R *.lfm}

{ TForm1 }
procedure Decrypt(const input,salt: string; out password : string);
var
    de: TBlowFishDeCryptStream;
    s1: TStringStream;
    temp : string;
begin
    // decrypt
    { 4 }
    s1 := TStringStream.Create(input);

    { 5 }
    de := TBlowFishDeCryptStream.Create(salt+key+salt,s1);
    { 6 }

    temp := de.ReadAnsiString;

    password:=temp;

    de.Free;

    s1.Free;
end;

procedure Encrypt(const input:string ; out storesalt,crypted : string);
var
    en: TBlowFishEncryptStream;
    s1: TStringStream;
    value,temp,salt: String;
    i : integer;
begin
  // we make some random salt here
  randomize;
  for i:=0 to length(chars) do
      begin
        salt:=salt+chars[random(length(chars))];
      end;

  // encrypt
  { 1 }
  value := input;
  { 2 }
  s1 := TStringStream.Create('');
  en := TBlowFishEncryptStream.Create(salt+key+salt,s1);
  { 3 }

  en.WriteAnsiString(value);
  en.Free;

  crypted:=s1.DataString;
  storesalt:=salt;

  s1.Free
end;{Encrypt}

procedure TForm1.Button1Click(Sender: TObject);
const
  chars = 'qwertyuiopasdfghjklzxcvbnm`1234567890-=[];~!@#$%^&*()_+{}:"<>?QWERTYUIOPASDFGHJKLZXCVBNM';
  key = '53285GFDJSLKFJSDLJ*#fefjsdljlk3284-3284-3285632:"<?>{}BXCV#@$GFDgf#@$%#@^H"L"Lgfd#@%#@%K#%#@?:_ÉÁŐÚőúéáüóöäü+ß´0ÖÄÜ';
var
    en: TBlowFishEncryptStream;
    de: TBlowFishDeCryptStream;
    s1,s2: TStringStream;
    value,temp: String;
    salt : string;
    i : integer;
begin
    // we make some random salt here
    randomize;
    for i:=0 to length(chars) do
        begin
          salt:=salt+chars[random(length(chars))];
        end;

    Edit2.Text:=salt;

    // encrypt
    { 1 }
    value := Edit1.Text;
    { 2 }
    s1 := TStringStream.Create('');
    en := TBlowFishEncryptStream.Create(salt+key+salt,s1);
    { 3 }

    en.WriteAnsiString(value);
    en.Free;

    Edit3.Text:=s1.DataString;

    // decrypt
    { 4 }
    s2 := TStringStream.Create(s1.DataString);
    s1.Free;
    { 5 }
    de := TBlowFishDeCryptStream.Create(salt+key+salt,s2);
    { 6 }
    temp := de.ReadAnsiString;

    Edit4.Text:=temp;

    de.Free;
    s2.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var salt,crypted : string;
begin
    Encrypt(Edit1.Text,mysalt,crypted);
    Edit3.Text:=crypted;
    Edit2.Text:=mysalt;
end;

procedure TForm1.Button3Click(Sender: TObject);
var password : string;
begin
    Decrypt(Edit3.Text,mysalt,password);
    Edit4.Text:=password;
end;

end.                     

 I was trying to solve this yesterday but could not do it... can someone please tell me what is possibly wrong with my decrypt procedure, it does not seem to work...

Greetings
Robert

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #1 on: June 04, 2014, 01:38:03 pm »
It can't work because encrypted data are not strings. They are binary data, as for most of the cyphering "kernel" algorithms. But additional code may be used to transform them from and to strings, if it's not already implemented into the concerned classes.

Look at this topic, for instance: http://forum.lazarus.freepascal.org/index.php?topic=20122.0
« Last Edit: June 04, 2014, 01:43:07 pm by ChrisF »

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #2 on: June 04, 2014, 02:19:37 pm »
BTW, I'm not quite sure about you want to do, but if you plan to store passwords to test them later (i.e. user inputs), it's definitively not a secure way to do so.

DON'T use any (symmetric) cyphering algorithm for that. Use instead a hash algorithm (MD5, SHA-1, or even more secure algos like SHA-2/SHA-3 ones), applied on your password + a random salt.

A wikipedia link, as a good starting point to read: http://en.wikipedia.org/wiki/Salt_%28cryptography%29

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #3 on: June 04, 2014, 04:14:35 pm »
Well, you shouldn't use just any kind of hashes+salt either; instead use a well-tested approved set of algorithms/parameters etc. e.g.
https://en.wikipedia.org/wiki/PBKDF2
https://en.wikipedia.org/wiki/Bcrypt
https://en.wikipedia.org/wiki/Scrypt


Also, try using operating system functionality - e.g. authentication using OS username info, determining group membership etc for the same etc.

However, the OP hasn't said what he wants to use blowfish for; you could perfectly well use it to obfuscate (= mildly disguise for casual inspection, no professional grade encryption) slightly sensitive data
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #4 on: June 04, 2014, 04:46:37 pm »
Well, in my idea, "password + a random salt" didn't mean literally "password string" + "salt string", but rather a general result issued from password data and salt data (and yes, I do know the specifications you' re mentioning).

Anyway, even using "password string" + "salt string" (in fact generally "salt string" + "password string") could be consider as quite acceptable for any non critical application (critical in a secure way, I mean).  It has been the case for most Unix systems for years in the past, if you remember.

As for using "only" SHA-1 as a hash algorithm.

If you're using a crypto library (like DCPCrypt, for instance) or have already any other appropriate source code, of course it's more secure to use up-to-date algorithms and specifications (both for "salting" and hashing).

But if you're using only the standard FPC functions, basic salt implementation + SHA1 is an acceptable compromise IMHO.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #5 on: June 04, 2014, 04:52:01 pm »
@ChrisF: agreed... it all depends ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #6 on: June 04, 2014, 07:34:10 pm »
Looks like you take the code from my blog as a base. I haven't checked your code, but I suggest writing a simpler one first by splitting encrypt and decrypt procedures, still using my code without significant changes. I did combine them for the sake of simplicity, and sometimes we miss little details when we improve someone else's code.

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #7 on: June 04, 2014, 07:59:21 pm »
@Leledumbo:  Sorry if don't agree with you...

I still think that storing binary data into strings is a very bad habit (especially with Pascal).

With that, you can encounter tons of unexpected issues, depending of the compiler, the OS, ...

Furthermore, are these "strings" supposed to be stored in a database ? Or in a text or an .ini file ? Or may be just passed to OS APIs or third party DLLs ?

For instance, having only a quick look at robert83a1's code, it seems to me that his main problem is:
Code: [Select]
...
Edit3.Text:=crypted;
...
Decrypt(Edit3.Text, ...
...

Why ? Because of OS APIs, of course.

Your blog sample is working because there are no operations with the encrypted string between your encryption step and your decryption step. Oh and BTW, even with your own blog sample have you really tested if decrypted string = initial string ? Like this, I mean (strict string equality) : WriteLn('Equality='+BoolToStr(temp=value));

It's working: great. Just make a test with another one, please. Let's say, for instance : value := 'this is another string';

Is it still working ? I guess it shouldn't (i.e. length(temp) <> length(value)). Why ? Because Blowfish uses 64-bit block size.
« Last Edit: June 04, 2014, 08:05:15 pm by ChrisF »

robert83a1

  • New Member
  • *
  • Posts: 25
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #8 on: June 04, 2014, 11:10:02 pm »
Wow, this sure caused a lot of replies, thank you for all the feedback...

 Realizing that my ways of doing this was wrong, I switched over to MD5 hash with random salt... I store in database per user, Hashed password , and random
generated salt...

 And when user wants to login I compare the input password + stored salt result to the crypted password stored in the database.

Greetings
Robert

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #9 on: June 05, 2014, 12:06:42 am »
Take a closer look on the following http://throwingfire.com/storing-passwords-securely/. This is only one of the articles on the subject (which I just fished out of google). In short do not use sha1, md5 or nay other cryptographic hash algorithm to store passwords they are not design for that there are 2 so far algorithms for password storage and those are bcrypt and scrypt. There is an implementation for bcrypt in delphi/lazarus but I do not have the links accessible at this time so you would have to search for them.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #10 on: June 05, 2014, 02:06:18 am »
@robert83a1: That's the correct approach, indeed.

@taazz: This has already be discussed briefly here (search for the first BigChimp' post in this topic).

Once again, you don't "use a sledgehammer to crack a nut". It depends of the critical level of your application, your time, your knowledge into cryptos (especially the ways to correctly implement them), the source code that it's available to you, and so on...

Are you talking about this one (i.e. bcrypt - not tested-) ?
http://stackoverflow.com/questions/9710205/is-there-a-bcrypt-implementation-available-for-delphi

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #11 on: June 05, 2014, 08:43:50 am »
@robert83a1: That's the correct approach, indeed.

@taazz: This has already be discussed briefly here (search for the first BigChimp' post in this topic).

Once again, you don't "use a sledgehammer to crack a nut". It depends of the critical level of your application, your time, your knowledge into cryptos (especially the ways to correctly implement them), the source code that it's available to you, and so on...

Well after this comment I should ignore this thread but given the benefit of a doubt I'll post one last message.

I have seen BigChimp's post I didn't see a post to an article that explains the reasons so I simple posted one. IF that was too much I apologize.

Are you talking about this one (i.e. bcrypt - not tested-) ?
http://stackoverflow.com/questions/9710205/is-there-a-bcrypt-implementation-available-for-delphi

yes that is one of them the second is the page of a programmer with a German looking name. But I can't find it right now to post it.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #12 on: June 05, 2014, 08:56:22 am »
taazz, I for one have no problem with your post.

It may very well be a good idea to just always use the sledgehammer. As long as you do evaluate the rest of your security/attack surface, at least then there's less need to think about passwords except in cases where a sledgehammer isn't sufficient either. There's so many pitfalls in rolling your own crypto that it's probably worth it to just use the sledgehammer (if you know that's good).

@robert83a1: if your users are in e.g. a Windows Active Directory domain, have you thought of just using their windows username to authenticate? That way, you rely on operating system security and there's no need to implement your own password scheme...
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #13 on: June 05, 2014, 01:37:28 pm »
@Lazz: Sorry if you've felt offended with my answer. I can assure you that it was absolutely not my intend, as I strongly dislike any "aggressive" discussion.

Simply, when reading your post it wasn't clear to me that you've read BigChimp's post before posting yourself.


As you may have understood by now, I disagree with using "heaving" crypto functions for most of the standard applications.

For instance, for a basic application checking first use+password from a database to grant him access to this application and unless using obfuscating techniques, removing the check (i.e. patching the program in a Windows environment) is usually just a matter of minutes.

What I mean is that security is a whole, and that's this whole is just as strong as its weakest link. And using strong cryptographic techniques may give the false impression that the environment is quite secured.

Anyway, I can perfectly understand that some people disagree with me; that's just "normal" and necessary discussions.

Sorry again...
.


taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Blowfish procedures to encrypt (working) and decrypt (not working)
« Reply #14 on: June 05, 2014, 01:45:27 pm »
What I mean is that security is a whole, and that's this whole is just as strong as its weakest link. And using strong cryptographic techniques may give the false impression that the environment is quite secured.

So making the saved password a weak link is ok as long as the rest of the system is as week as the passwords. That is a unique perspective on the problem I must admit.

Me on the other hand I strive for the best on all the spectrum of cryptography. It is the only way to make sure that the saved passwords is not the weakest link on the chain. The only think that will make me use something less secure is cost and time constraints and that will be corrected in time between releases.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018