Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Visual FoxPro Encryption and Hashing 8

Status
Not open for further replies.

craigsboyd

IS-IT--Management
Nov 9, 2002
2,839
US
I've created a free FLL that gives Visual FoxPro developers access to the following:

Encryption Ciphers:
Blowfish
AES (Rijndael)

Hash Functions:
SHA1
SHA256
SHA384
SHA512
MD5
RIPEMD128
RIPEMD160

You can find out how to use the new functions and download the FLL from the following blog entries:

Visual FoxPro and Blowfish
Visual FoxPro and AES Encryption
Visual FoxPro and Hash Functions

You can also see a real world example for using the MD5 hash function to create software lincenses/serials for your own applications at the following link:
Visual FoxPro Random License/Serial Generator

There's lots of great content for Visual FoxPro developers being posted on blogs these days. A number of the bloggers are regulars here, over on the UT, and on the Fox Wikis. If you aren't an avid blog reader, you might think about it. I learn something new almost every day out here on Tek-Tips, and the same goes for the Visual FoxPro related blogs. If you aren't sure what some of the really good Visual FoxPro blogs are, you can refer to my blog roll (a list of links on the right-hand side of my blog). This will give you some idea of what's out there anyways.


boyd.gif

SweetPotato Software Website
My Blog
 
Thanks Craig,
After I read the title of the post I want to redirect the answer to yuor BLOG :). Thanks again for you works.

Borislav Borissov
 
Excellent work Craig,

Last year I posted a thread about having problems working with the Crypto API and you convinced me to spend my time looking for other solutions. I spent a little time trying to implement Blowfish as a Native VFP class but gave up and had a colleague implement Schneier's code as a C DLL which we now use. We have used Cryptor in the past and while it's a good product and simple to use I like having a tool that we own the code for.

Thanks again for pointing me in a better direction and keep up the great work. It's people like you, and the many other regulars here, that make this a terrific forum!

Ralph Kolva
 
bborissov,

LOL. You're welcome.

rkolva,

You're welcome and glad to hear you found something that works for you. I'll be publishing the source to this FLL as well in the near future (it allows others to collaborate and build off of it, and it also allows everyone to see that there aren't any backdoors and such built into the program which is a valid security concern with proprietary closed source offerings).

In the end, as much as I love VFP, some things are better done in C/C++ and then just access the functions/objects via an FLL, DLL, or COM. Algorithms such as hashing and encryption are definitely one of those things.

As for Crypto... my opinion is the same. I've seen some articles on it and such, and I always wonder the authors have ever successfully used it with a ditributed application. Way too many gotchas and headaches for me. If Crypto works best for someone, more power to them, but as for me... I won't use it until they've addressed some of the major issues.

To All,

I just finished implementing a couple of critical bug fixes, adding a new encryption algorithm (TEA), and simplifying the functions used to call the encryption algorithms. They are simply Encrypt() and Decrypt() now but still give you access to all of the different algorithms in the FLL. I felt this was more in-line with the simple Hash() function (and much more maintainable moving forward). I won't change the function signatures again - what I have now is scalable.

The download for the newest VFP Encryption FLL is in my latest blog entry.

I've also started work on functions to directly encrypt and decrypt files using the FLL. This should be done sometime soon, still a couple of bugs that I haven't squashed yet, so they're not ready for primetime: EncryptFile() and DecryptFile()

boyd.gif

SweetPotato Software Website
My Blog
 
Hi Craig,

another star from me.

This may be a little paranoid, but you should add precautions against DLL/FLL injection. So unlikely it may be, if someone replaces the FLL with his own version, he could spy passwords etc. sent to the fll. A way to prevent this would be, to check if MD5(filetostr("vfpencryption.fll")) is the original MD5 hash of that fll, before using the fll.

You may even check the fll with itself. Then I'd recommend to check 2 hashes and file length of the fll with the original hashes and file length and I'd say there is no way to build a second fll that comes back with the same three values, therefore no fll injection possible.

It would be good to provide that MD5 hash with the download, too, so one could detect if the download is correct.

Replace MD5 by anything you like, eg SHA512, but MD5 is the usual hash used as a download signature.

Bye, Olaf.
 
Excellent suggestions Olaf. I'll work them in to one of the upcoming versions of this FLL. I've just finished the EncryptFile and DecryptFile functions and fixed another couple bugs. I will be posting a new version of the FLL with a blog entry on it's use shortly.

boyd.gif

SweetPotato Software Website
My Blog
 
just to be very clear on that point: As I said
You may even check the fll with itself.

I meant, that the user of the FLL could determine the hashes over the FLL with the FLL hash functions, although that seems a bad way if you expect the FLL to be some other FLL imitating the original and additionally sending passwords passed to the encrption functions via email to a hacker.

So this could be Foxpro code for integrity check of the FLL:
Code:
#Define cnOriginallength 123456 && the original length
#Define cnOriginalMD5 "abcdefabcdef1234" && original MD5
#Define cnOriginalSHA512 "abcdefabcdef1234" && ...
#Define cnOriginalMD5OfYourString "0123456789abcdef"

lcVFPEncryptionFile = LOCFILE("vfpencryption.fll")
SET LIBRARY TO (lcVFPEncryptionFile)

lcVFPEncryptionFile = FileToStr(lcVFPEncryptionFile)

if Len(lcVFPEncryptionFile) = cnOriginallength;
   and StrConv(Hash(lcVFPEncryptionFile,5),15) == cnOriginalMD5;
   and StrConv(Hash(lcVFPEncryptionFile,4),15) == cnOriginalSHA512;
   and StrConv(Hash("Somestringknowtoyou",5),15) == cnOriginalMD5OfYourString;
   * okay
   llUseFLL = .t.
else 
   * dirty FLL, don't use!
   llUseFLL = .f.
   Release Library vfpencryption
endif

If the dirty FLL would be smart, it would just be a wrapper to the original FLL, doing it's dirty work of password spying additional to being a wrapper to the originals functions. But even then it would need to have the same file length to not be detected.

Hmm, that may still be a risk you would only detect when the length of the original FLL changed. Maybe it's much simpler when including the FLL in the EXE, extracting it at runtime and locking it to prevent changes of the file at runtime.

Bye, Olaf.
 
>>But even then it would need to have the same file length to not be detected.

Not possible - detection would still occur. If the FLL was changed in anyway, the hash would change. Having the same length doesn't defeat this.

boyd.gif

SweetPotato Software Website
My Blog
 
>> If the FLL was changed in anyway, the hash would change. Having the same length doesn't defeat this.

However, if the FLL were changed, then it may be smart enough to return the correct hash for the original FLL when it recognizes that it is processing itself.

Perhaps a simple way around this is to use the FLL to hash an arbitrary string appended with the FLL... it would be much more difficult (but not impossible) for a "dirty" fll to identify that circumstance. (It would have to search every string being hashed for the first few bytes of itself.. then it would have to be able to "continue" hashing including the arbitrary string along with the original... This seems like it would be very difficult, but not impossible. Putting the arbitrary string at the beginning would make it nearly impossible... putting it somewhere in the middle would probably make it impossible.)

Even better, encrypt the FLL (using the FLL and your own encryption keys), then hash the encrypted FLL, so that a "dirty" FLL couldn't recognize itself.

- Bill

Get the best answers to your questions -- See FAQ481-4875.
 
Hi Bill,

I think Craig is right, even if the dirty FLL would wrap the original functions it would receive itself as string and hash that false string, but as you said it's possible to detect itself and then pass the original FLL to the original FLL instead.

If you use the encrypted FLL, how would you decrypt it without an already decrypted FLL you'd need to do a decrpyt? If you encrypt the original FLL with the FLL, then do a hash on that, your idea of the dirty FLL replacing itself with the correct version would still hold true.

Well, at least it's rather difficult to create such a dirty FLL, as we may think of even other tests, maybe use another MD5 checksum routine, so checking the FLL with another DLL or even native foxpro code. I think extracting the FLL out of the EXE and only using that fresh extracted FLL would be very safe.

Bye, Olaf.
 
Hi Bill,

... and your idea of adding an arbitrary string to the FLL is also very good. I'd say you may only append that string to the end of the FLL to have it still working. The security hole is so small, I'd suspect a hacker would now try to find a bigger one to slip through.

Bye, Olaf.
 
If you use the encrypted FLL, how would you decrypt it without an already decrypted FLL

I can see how I wasn't clear: I was thinking further about detecting a "dirty" FLL using hashing... not actually encrypting the FLL that is being used. So, I meant for the executing application to first encrypt the FLL, then hand the encrypted FLL to the hash function, and compare the hash to a stored value that had been generated on the legitimate developer's computer during the application build process.

Since the stored value was created with the appropriate private key, the "dirty" fll wouldn't recognize it.

...I just realized that a flaw in this is that the dirty FLL would be able to recognize when it was being used to encrypt itself before hashing, and therefore be able to get around this issue.

It seems that an arbitrary (and secret) transformation (but not an encryption) on the FLL being checked before generating the hash would be very reliable (unless the maker of the "dirty" fll were to re-fox the application and discover this transformation...)


- Bill

Get the best answers to your questions -- See FAQ481-4875.
 
Hi again,

the thing is, that the original FLL needn't even be exchanged to do DLL injection. API monitor is a tool making useful use of a technique, where you can detect calls to DLLs. (see It will not exchange the system DLLs and nevertheless can log, what calls have been done. It's a nice tool for analyzing what's going on behind the scenes, eg in foxpro.

And this is a littel more info about the DLL or code injection: and anotherone:

I fear there is little protection against this, as this works from outside the original FLL not modifying it.

Bye, Olaf.
 
While the concerns and points made above are valid, I have a somewhat different chief concern. My concern is that the Visual FoxPro developers using the FLL would make the private key(s) they are using easy to detect. By either hardcoding the key, saving the key on disk somewhere, or having it reside in a variable or object's property for a period of time. This will effectively render the increased security the ciphers provide null and void.

I would hope that when a developer utilizes this FLL in their Visual FoxPro application that they would create a function (or better yet a set of functions) that would be used to return the key when needed. If done correctly this would make attacks using certain reverse engineering techniques much less likely to succeed.

I believe given aspects of Visual FoxPro, that the above is most likely the weakest link in the chain. There is a fairly good article by Christof on protecting the key in your code better that was put out sometime ago by FoxPro Advisor (free to read if you have the time)...



boyd.gif

SweetPotato Software Website
My Blog
 
Hi Craig,

Also valid points. As I said: I think the suggested validation on the FLL is secure enough and so:

myself said:
The security hole is so small, I'd suspect a hacker would now try to find a bigger one to slip through.

Your concern may be one of those bigger holes. I see Christof once a month here in Hamburg, so I knew that one. It's quite smart to produce a key or password with such a set of functions. But if the code is reverse engineered, you don't have to understand how it works and what it does but only call it yourself. This only protects against a search for clear text strings or strings that could be a key or password included in your EXE.

I'd suggest to add a parameter to Christof's GetPW() Method. That way you'd not only need to reverse engineer this function and the functions called, but also find where it is called with which value passed. And you can have several passwords generated by that set of functions.

Again, this makes that security hole very small, but doesn't close it fully. Nevertheless a good point.

Bye, Olaf.
 
CraigsBoyd has made a another valuable contribution with this .FLL... My star in recognition for that!

Still, I am looking for a stream cipher rather than a block cipher in order to encrypt the contents of a field that may be filled completely with a string.


Regards,

Kenneth Tamayo
San Juan, Puerto Rico - USA
 
I am using VFP 7.0 and I am trying to load the vfpencryption.fll and it says that the file is 'invalid'

Does it only work with some versions of VFP?

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top