# Practical BCrypt plus XOR encryption for small messages

This is a practical solution available and potentially useful to everyone, so please give some leeway not banning this question. Details are at the end, but here is the question:

How secure is the following encryption approach?

In few words, it uses BCrypt to hash passwords. BCrypt is then used repeatedly on the result of prior hashing, and all the hashes are concatenated to make a Key as long as the Message itself. The encryption is a simple Key XOR Message. Details are below:

Note. BCrypt salt is hard coded and is removed from the resulting hash, when applying BCrypt function.

Encryption

• Message = Any Ascii128 text

• Pass1, Pass2, Pass3, Pass4, Pass5 = Ascii128 based 5 password fields

• Password = Pass1 XOR Pass2 XOR Pass3 XOR Pass4 XOR Pass5

• Checksum = {

1. ShortMessage = Message
2. Repeat while ShortMessage is longer than 50 chars,

ShortMessage is cut in half, and the halves XOR to get new ShortMessage

3. ChecksumBase = fromBase64toAscii128(BCrypt(ShortMessage XOR Password))
4. Checksum = ChecksumBase.substring(1 to 4)}
• Key = {

1. LongKey = BCrypt(Password + Checksum)
2. CurrentKey = LongKey + Checksum
3. Repeat while LongKey.length < Message.length :

CurrentKey = BCrypt(CurrentKey)
LongKey = CurrentKey + LongKey

4. Key = fromBase64toAscii128(LongKey) }
• SecureCode = Checksum + (Message XOR Key)

• SafeMessage = fromAscii128toBase32(SecureCode)

Decryption

• SecureCode = fromBase32toAscii128(SafeMessage)

• CheckSum = SecureCode.substring(1 to 4)

• Password = see in Encryption

• Key = see in Encryption

• Message = SecureCode.substring(from 5) XOR Key

• CalculatedCheckSum = see in Encryption

• Integrity check = recovered CheckSum must match CalculatedCheckSum

Please, rate the safety of the approach on a scale from "kids safe" to "unbreakable", as quite a few people use the program, and want to know how secret their secrets are.

There is a link from the project's page to this question, so your answers will be a validation of the project for better or for worse.

The program can be run here. It is on GitHub and cannot be maliciously altered without a public record of the change. (There are no plans for change as this would compromise current user base).

If someone would care to take a look at the JavaScript, to ensure it does what is declared and put a comment in here, this would be awesome.

• How long are the password fields? Why are they split into 5 when they just get combined into 1 in a way that doesn't protect against anything? The checksum is not a secure MAC. Truncating the Bcrypt output makes it far easier to attack. Bcrypt is slow. That's good in a KDF, but bad in a stream cipher (which this tries to be). Hard-coding the salt is a terrible plan. At first glance this seems extremely amateurish, and likely not much better than "kids safe". If you want to use Bcrypt, use it do derive a key for ChaCha20+Poly1305. Don't design your own algorithm. Nov 10, 2017 at 21:03
• BCrypt takes, I believe, up to 60 chars, so the rest of the password will be ignored. The split in 5 is a practical usage (not encryption) option, when a person can enter 5 different, regularly used passwords, and have a combined protection. Yes, the check sum is only 4 * 128 integer, but under the circumstances it might be sufficient. Usually it is a very short message. Yes, the attacker knows the salt, and this is a part of the question, why is it bad (besides sounding bad)? Nov 10, 2017 at 21:34
• The overall goal was not to have the strongest and fastest encryption, the goal was to run on any platform something what can opened, looked at, and understood (verified). I did not design algorithms, which are BCrypt and XOR. I designed a solution to a particular problem, and want a second opinion if the well known methods are employed securely. Thanks for your comments. Nov 10, 2017 at 21:45
• You used the primitives in a combination to create a new algorithm. Just using Bcrypt doesn't mean you're not designing an algorithm. Nov 10, 2017 at 23:26

No that is not secure.

If someone knows the first part of the message (27 characters I think), they can extract the first part of the LongKey and regenerate the rest of it, WITHOUT THE PASSWORD.

The so called checksum is not cryptographic, not even as robust as CRC32, if you have a 100 character message with the first and 2nd half the same, the checksum is 0. You can also swap message halves without changing the checksum. And worst of all, the checksum is both unencrypted and gives away information about the plaintext, assisting in a plaintext recovery effort.

Trying to use the checksum like a salt as part of the bcrypt input is ineffective, and if the password is long enough, is ignored, making all of LongKey first blocks identical, allowing immediate breakage of all messages that used the same passwords.

The passwords being XOR'd together makes the combined password length only as long as the longest one, and might help prevent a dictionary attack but does not increase entropy like concatenation would.

If you want me to rate from "kids safe" to "unbreakable", you might have gotten it up to "kids safe" if almost every step of the way wasnt done incorrectly.

• Comments are not for extended discussion; this conversation has been moved to chat. Dec 17, 2017 at 13:38