Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
API error with VfpEncryption71.fll
Message
General information
Forum:
Visual FoxPro
Category:
Third party products
Environment versions
Visual FoxPro:
VFP 8 SP1
OS:
Windows XP SP2
Database:
Visual FoxPro
Application:
Desktop
Miscellaneous
Thread ID:
01412793
Message ID:
01413700
Views:
160
>I understand what you are saying, but I had no idea that the return from the Decrypt/Encrypt function was returning binary data. I always assumed it was a string and did not know about the CHR(32)

In retrospect binary was a poor choice of words. The return value's data type is indeed character and not binary, I meant that the FLL is returning the ASCII equivalent of the bytes and thus 00100000 is returned as CHR(32).


>However my use of Alltrim would strip CHR(32) off either/both end/s, causing an error.
>So what you suggest would be to parse the encrypted string, convert each chr to hex and insert the HEX string into the field and vice versa for decryption?

The encoding was offered as one possible solution, in which case I would use STRCONV(MyCipherText, 15) to perform the conversion. The drawbacks to this approach is that each ASCII character is then represented by 2 hexidecimal digits which doubles the field length required and you'll take a performance hit having to encode/decode each time you wish to encrypt and decrypt a given field. A better approach given your particular example (AES 256 - block cipher with a fixed block size) would be to ensure that the plaintext entered never exceeds a specific block size multiple and then simply truncate the plaintext and ciphertext at that multiple. For the example you've sent me, you could use 32 bytes and it would work slick as a whistle. Simply modify your replacement statement when decrypting to the following...
REPLACE pieces WITH decrypt(LEFT(pieces,32),cSecretKey, 2),;
ofx WITH decrypt(LEFT(ofx,32),cSecretKey, 2),;
stringx WITH SUBSTR(decrypt(LEFT(stringx,32),cSecretKey, 2),4),;
toopen WITH SUBSTR(decrypt(LEFT(toopen,32),cSecretKey, 2),4)
... and when encrypting you would use...
IF ALLTRIM(ofx) = "COMPANY"
	REPLACE pieces WITH encrypt(LEFT(pieces,32),cSecretKey, 2),;
	ofx WITH encrypt(LEFT(ofx,32),cSecretKey, 2),;
	stringx WITH encrypt(LEFT(stringx,32),cSecretKey, 2)
ELSE
	REPLACE ofx WITH LEFT(pieces,3)+IIF(status=.T.,"ALLOW","DISALLOW")
	REPLACE stringx WITH LEFT(ALLTRIM(pieces),3)+ALLTRIM(stringx)
	REPLACE toopen WITH RIGHT(ALLTRIM(pieces),3)+ALLTRIM(toopen)
	
	REPLACE pieces WITH encrypt(LEFT(pieces,32),cSecretKey, 2),;
	ofx WITH encrypt(LEFT(ofx,32),cSecretKey, 2),;
	stringx WITH encrypt(LEFT(stringx,32),cSecretKey, 2),;
	toopen WITH encrypt(LEFT(toopen,32),cSecretKey, 2)
ENDIF
>The strings I usually enter are like this:
>
>Pieces                                  toopen                                 stringx                     ofx
>--------------------------------------------------------------------------------------------------------
>Zest Health Clubs                  UBSCOMPANY                     ZESMENU            ZESALLOW 
>
In order to reproduce the CHR(32) bug in your current version try entering "_2P" in Pieces and "E05GG0W" in toOpen (Item and Module columns in the grid respectively). This will produce ciphertext that will fail do to your use of ALLTRIM(). Then use the replace statements I provided above and it will never fail.



>The reason I am doing concatenation of these strings is that the encrypt FLL always returns the same string for a similar passed string so if I try to encrypt "ALLOW" on its own, the pattern could be obvious when viewing the encrypted string as the return value is always the same for "Allow"

Good thinking. Random characters would be even better, but i like the way you think.


>So while I understand how my using ALLTRIM() could strip off CHR(32), given that the encrypted string returned is always the same, I cannot see how the same string, will decrypt properly sometimes and when a few more records are added after it, it will throw an error.

I do not see how this can happen, but would be more than willing to take a look at it if you can provide a repro of the problem. The example you sent me only reproduces the CHR(32)/ALLTRIM problem. I did note that the record positions can change when they are read back in due to the order by on toOpen. Is it possible that you are mistaking which record is failing and it is simply one of the newly added records that moved up in the cursor due to its value in toOpen?


>Besides, as I see it, (I may be wrong) the function of the Encrypt/decrypt is to return an appropriate string back to me irrespective of what string I pass it. So even if I strip off the CHR(32)'s it should still return a string, although the string will be garbage. Am I right about this? If so then why does it just throw an error instead of just returning garbage?

It throws an error because you are handing a 32 byte block cipher a length of ciphertext that isn't a multiple of 32. As I said in my earlier post, I do believe the FLL should do a better job of handling this exception. In this particular case, I think that a an error stating what the problem is would be the best solution since it's trappable. I could certainly pad the ciphertext to a multiple of the block size in order to avoid the exception (which would give you 'garbage' back), but that doesn't seem like a decision that the FLL should be making for the developer using it. If i simply throw a specific error for this condition, then the developer could decide what to do at that point. In any event, I agree that the FLL should provide better error handling/reporting capabilities.


>I can send you the table and code if you will be good enough to look at it.
>
>Thanks
>
>Bernard


Thank you for taking the time to send me the files via email. Please let me know whether using the replace statements I have provided in this post solve the problem for you. I believe they will. One final note is that your fields need only be 32 characters in length... 50 is 18 bytes more than are needed. If you wish to have the user be able to enter 50 characters then modify the fields to use 64 characters. The upshot of using a block size multiple for your character fields is that you can get rid of the LEFT() function from the replacement statements and simply encrypt/decrypt the fields giving you a performance boost.

Let me know if there is anything else I can do to help or any other questions you have regarding the vfpencryption71.fll.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform