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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

garbling a name 1

Status
Not open for further replies.

Bryan - Gendev

Programmer
Jan 9, 2011
408
AU
I have been asked to create a program to 'hide' the actual names in a certain field in a VFP table. Thus I would replace the existing string of characters by a new string of random chrs.

thus far I have the code to loop through each chr in the string but I am not able to do the replacement chr by chr. My first attempt is a function thus
Code:
Function garble(oldchar)
LOCAL charnum
LOCAL newchar
LOCAL newcharnum
charnum=INT(ASC(oldchar))
newcharnum = charnum * RAND()
newchar= CHR(newcharnum )
Return newchar
this of course produces a range of characters not all of which are in the range A-Z.
How will I create replacement chrs in the range A-Z?
Many thanks

gendev
 
>If I told you I cesar ciphered a a single letter to "k", you also wouldn't know what letter I encoded

Absolutely, since under those specific circumstances, what you have is a one-time pad ... which is pretty much acknowledged to be an unbreakable encryption

>If I would change the mapping done on the base64 encoding and choose any 64 other characters in a scrambled order

Then it wouldn't be Base64, would it? ;-)

>you don't prove much.

The point was to demonstrate - as you yourself had said at least twice in this thread - that the key was critical. Yes, including the key means that the encryption is only being used to carry out encoding (again, as I thought we'd already agreed), but that does not change the fact that the algorithm is one of encryption.

If we were to accept your argument as being valid, then AES, already mentioned several times in this thread, suffers the same issue. If I know the algorithm (heck it is in the public domain, so I do) and I know the key being used, then for me all AES is effectively doing is simple encoding, since I can very easily move backwards and forwards between plaintext and ciphertext (using that known key the same chunk of plaintext will always deliver the exact same chunk of ciphertext and vice versa, i.e. your set 1 > set 2 stuff, although a block mapping rather than a character/byte mapping). But that really, really doesn't mean that the AES is suddenly not carrying out encryption.

Perhaps what we can say is that, at root, encryption is encoding, but that not all encoding is encryption.

>If you don't cheat and would encrypt "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" for me, the result would give me the decoding constant I need for letters

Here you go: LZúûtcxv8V09MÔÚ7jel@îÎÓùAèÊôaGqgFJ6dÉçRÄ5u-ËXâÂéàrUn
So now you can carry out a classic bit of cryptanalysis, using a known plaintext attack ... :)
 
>Then it wouldn't be Base64, would it?
It would still be doing the same, just mapping to another set of 64 characters. It would still deserve the same name. It wouldn't be compatible. But it still just would be an encoding.

>then AES, already mentioned several times in this thread, suffers the same issue.

No, it doesn't convert the same letters to the same encrypted letter, there is a bigger block of 32Bytes per block and that's garbled in itself, that makes it impossible to build up a decrypting mapping. It's what makes it a different category of an algorithm, not just the password. So AES doesn't have that issue.

And in regard of known plaintext attack: An "encryption" not standing that attack, can't call itself encryption. That's the whole point. If I know a plaintext and know the algorithm and the encoding result, I should still not be able to deduct the key from that, which I can. You gave me at least the part of the ENCRYTPY contain to be able to decrytpt all letters, it worked and resulted in "Scrambled". AES is not flawed in that way at all.

Bye, Olaf.










 
Olaf,

you are so correct!
there is a double ü in constant DECRYPTY!!
Once you start changing something one should take care not to create an other mistake.
I will review both constants and publish, after double checking, the revised.
Sorry for confusion caused.

Regards,
Koen
 
>It would still deserve the same name

No, it wouldn't you know. Base64 is a standard, clearly defined in RFC 4648. If you use a different alphabet map than the one in the standard it is not base64. The standard itself is explicit about this, when discussing an alternative encoding: "This encoding should not be regarded as the same as the "base64" encoding and should not be referred to as only "base64".

(and if you do the research you'll also find that using the algorithm used for base64, but using alternative, secret maps is indeed considered encryption ...)

And perhaps this is where we differ. You appear to prefer to define things to your own requirements - "An 'encryption' not standing that attack, can't call itself encryption", which is pure nonsense. It may end up not being a very good or secure encryption, but it remains encryption nevertheless. Known-plaintext attacks (colloquially known as cribs) were used to break Enigma, for example, during WW2; are you suggesting that Enigma was not encryption?

>AES is not flawed in that way at all
Very true. AES is not susceptible to plaintext attack. Never suggested it was. That wasn't the point I was making. My point was that if you know the key then, given your assertion that "[a]ny code mapping set1->set2 and inversely set2->set1 is not an encryption but simply an encoding", even AES is simply an encoding (a complex encoding, but an encoding nevertheless). This is, of course, inevitable - every plaintext must map to a unique ciphertext, and vice versa (the whole thing would be pointless if they didn't), and in that sense is encoding. But just because it is encoding does not mean that it is not encryption. And hence my statement that encryption is encoding, but that not all encoding is encryption.
 
We're going in circles here, any way you see a mapping as an encryption or not, this thing is only valid to hide names from the eyes of readers and gives a little hurdle to unmangle the "encrypted" names or more general data.

I think I now often enough stressed out the use of strong encryption is demanded by laws, so even if a customer is satisfied by something, you could save yourself from legal trouble coming back at you maybe years later, gendev. OWASP is very strong on this:
OWAP said:
Do not implement an existing cryptographic algorithm on your own, no matter how easy it appears.
This does not even address implementing your own algorithm, just your own implementation of a known algorithm.

For sake of having data in CSV or XML in only printable characters, you can do as XML does with binary data and embed it as base64 encoded, but there is no need to write a "scrambling" only using printed characters.

The original idea to simply generate random letter combinations, not at all influenced by the original name is already much safer, as it doesn't allow any retranslation aside of using the garble.log. If that's a specification you have your way back to the original names by access to this file only. If it really should be used for getting back the original names at a later stage, I'd put it in a DBF rather than a text log file with the three fields recno, name, randomstr. You would only need to store the randomstr, if you want to ensure this is the data you got from this run, otherwise, of course, knowing recno and original name is enough. On the other side, you could simply keep a copy of the original data to revert back to it, such a log is quite illogic, as it's just a verbose description of the original data.

Bye, Olaf.
 

Hi,

According to my tests here are constants where all letters are unique.
Sorry for troubles caused.

#Define DECRYPTY "abcdefghijklmnopqrstuvwxyzABSCDEFGHIJKLMNOPQRSTUVWXYZ1234567890äáàâÄÁÀÂëéèêËÉÈÊïíìîÏÍÌÎöóòôÖÓÒÔüúùûÜÚÙÛÇç@.-&#"
#Define ENCRYPTY "Ï3ÍTUVÂë56éWXYêËQÛÇBÉZaÚ4ÙbÌÎöfghijkó7pq8HIâÄÔáAsCÁ90òMwxyNOPÒRSîúùnorstûÜç@.-&#GÀèJKLôÖz12äDEFcdelmuvàÈÊïíìÓü"

Regards,

Koen
 
You still have errors in there, Koen, check small and large S in both strings.

#Define DECRYPTY "abcdefghijklmnopqr[highlight #FCE94F]s[/highlight]tuvwxyzAB[highlight #729FCF]S[/highlight]CDEFGHIJKLMNOPQR[highlight #729FCF]S[/highlight]TUVWXYZ1234567890äáàâÄÁÀÂëéèêËÉÈÊïíìîÏÍÌÎöóòôÖÓÒÔüúùûÜÚÙÛÇç@.-&#"
#Define ENCRYPTY "Ï3ÍTUVÂë56éWXYêËQÛÇBÉZaÚ4ÙbÌÎöfghijkó7pq8HIâÄÔáA[highlight #FCE94F]s[/highlight]CÁ90òMwxyNOPÒR[highlight #729FCF]S[/highlight]îúùnor[highlight #FCE94F]s[/highlight]tûÜç@.-&#GÀèJKLôÖz12äDEFcdelmuvàÈÊïíìÓü"

It's not hard to construct constatns, which will work, if you cover all CHR(i) for which ISALPHA() returns .T. and add in digits, punctuation and such also printable and wanted character for DECRYPTY, then simply randomly shuffle that string.

Here you have a simple check routine:
[tt]#Define DECRYPTY "abcdefghijklmnopqrstuvwxyzABSCDEFGHIJKLMNOPQRSTUVWXYZ1234567890äáàâÄÁÀÂëéèêËÉÈÊïíìîÏÍÌÎöóòôÖÓÒÔüúùûÜÚÙÛÇç@.-&#"
#Define ENCRYPTY "Ï3ÍTUVÂë56éWXYêËQÛÇBÉZaÚ4ÙbÌÎöfghijkó7pq8HIâÄÔáAsCÁ90òMwxyNOPÒRSîúùnorstûÜç@.-&#GÀèJKLôÖz12äDEFcdelmuvàÈÊïíìÓü"

lcLine1 = DECRYPTY
lcLine2 = ENCRYPTY

IF CharsOnceInString(lcLine1, lcLine2) AND CharsOnceInString(lcLine2, lcLine1)
? "OK"
ENDIF

FUNCTION CharsOnceInString() as Boolean
LPARAMETERS tcChars, tcString

DO While LEN(tcChars)>0 AND LEN(CHRTRAN(tcString,LEFT(tcChars,1),"")) = LEN(tcString)-1
tcChars = SUBSTR(tcChars,2)
ENDDO

IF !EMPTY(tcChars)
? "problematic character "+LEFT(tcChars,1)+" occurs "+TRANSFORM(OCCURS(LEFT(tcChars,1), tcString))+" times in tcString"
ENDIF

RETURN (LEN(tcChars)=0)
ENDFUNC[/tt]

Bye, Olaf.

Edit: Once you remove the upercase S from ABSCDEF in DECRYPTY and one of the small s in ENCRYPTY (doesn't matter which), the two constants are OK.
 
Olaf,

Thanks for showing the bug and thanks for the code to compose.

Changed the constants and performed following check to display 2 identical lines :

code
clea
? "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890äáàâÄÁÀÂëéèêËÉÈÊïíìîÏÍÌÎöóòôÖÓÒÔüúùûÜÚÙÛÇç@.-&#"
lc=scrambling("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890äáàâÄÁÀÂëéèêËÉÈÊïíìîÏÍÌÎöóòôÖÓÒÔüúùûÜÚÙÛÇç@.-&#",.t.)
? scrambling(m.lc,.f.)
endcode


Koen

 
>simply randomly shuffle that string.

Shuffling DECRYPTY is certainly how I generated the ENCRYPTY that I used for my laËÊRôçqG 'challenge'. In fact, I dispensed with a fixed ENCRYPTY; it was generated on the fly using a password to seed the shuffle routine
 
>using a password to seed the shuffle routine

I played with this and had best results using SHA512 to first create a more random seed value from a password. Of course that still makes weak passwords weak passwords, but depending on how you use the seed value for shuffling, you can get very weak shuffles. I first tried to use bytes as "cut" position to split the ENCRYPTY value and join the split string swapped. Doing it this way without frst hasing the passwords you get similar passwords also decrypting the encrypted text(!)

Also only shuffling initially still keeps the ability to demask the whole process with known plaintext.

The nature of what gendev does with automatic "garbling" and "ungarbling" is needing a fixed password or key and that makes it a long term target. Doing it like it's done with password hashs storing a sand or key per record, you give away the necessary data to "ungarble", too.

It's simply a pity gendev still keeps it at using this routine.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top