lannerkr / joplin-plugin-lannerkr-EncDec

0 stars 0 forks source link

Password is used as supplied? #2

Open nizamov opened 1 month ago

nizamov commented 1 month ago

As far as I can understand the code, the supplied password is used as it is encoding/decoding. So it is extremely weak with a short passwords. I suggest to use some hashing function to generate a long pseudorandom string from the user password. Thus, any supplied password (even short/weak) will be extended to a long string. This would be much more secure.

Excuse me, if I get it wrong.

With best regards, SN

lannerkr commented 1 month ago

first of all, thank you for your concern. I'm very new in coding.. and not familiar with security .... would you help me to understand why short password is weak? (the password is repeated until the length of it becomes the length of plain string.)

nizamov commented 1 month ago

(the password is repeated until the length of it becomes the length of plain string.)

This is exactly what I mean. Imagine the user has 1 alphanumeric symbol as a password. Then you XOR a string with a constant. It is trivial to recover the string. And with a longer password, it is only slightly better - because the password symbols are used as they are - as alphanumeric symbols. These use only a certain subset of a byte. They are effectively 5-6 bits and leave a lot of the original structure of the encoding string untouched. And this password is used repeatedly. So if you encode a sufficiently long string (or many short strings) with such a password, it can be statistically analysed and the password can be recovered without brute force. Even for obfuscation purposes it is quite weak.

So what you need to make it more secure is to convert the original password into a string that: 1) consists of all char values (spanning the entire byte range 0-255), not just its limited subset (ascii alphanumeric chars) 2) is long enough that repetitions can be ignored. At best, it should be as long as the string to be encoded. In practice it is more likely to be 256/512 bit - i.e. 16/32 bytes.

You can hash the password using any reasonable function. And use the hash of the password (which is now a long pseudorandom string) to XOR the string being protected. This can only be cracked by brute forcing.

By the way - it would also be nice to have a checksum of the string in the result as well - so you can prove that the string was correctly decoded, so the password supplied was correct.

Unfortunately I do not use JS/TS and can not help with a patch.

lannerkr commented 1 month ago

thank you for your kind explanation. so the length of password is not the main point, XOR algorithm with plain password is the weak point. your suggestion is to make simple XOR algorithm more secure. for now, I need to study how to use hash function in JS/TS ...

in addition, about the checksum you mention. sould I make checksum with plain string and plain password? ( honestly I don't exactly konw about the checksum ... ) after make cheksum, sould the checksum be appended at the end of encoded data?

nizamov commented 1 month ago

Here is a simple hash function in pure JS: https://stackoverflow.com/a/52171480

it gives 53 bits, so can be truncated to 6 bytes. Something similarly strong as a random alphanumeric passwords with 8 symbols. In my opinion it is sufficient for obfuscation/encoding.

I guess, that you can use this function as well for checksum and store/encode/decode it correspondingly .

Something like:

hash=crb53(password).tobytes()[0:5] crc=crb53(string).tobytes()[0:5] encoded = xor(hash, string + crc)


and by decoding check similarily:


decoded = xor(hash, encoded) decstring= decoded[:-5] enchash = decoded[-5:] dechash = crb53(decstring).tobytes()[0:5]

if enchash<>dechash: "hash mismatch, wrong password"


hope this helps