You’ll need to choose a combination of up/down/left/right characters (up to 10) to act as your encryption key. Type that in at startup. Then boot up a console and connect a screen session to your Arduboy. Your passwords will be entered via the Serial connection.
# just an example - your /dev/tty.usbmodem port will probably be different
screen /dev/tty.usbmodemHIDP1 9600
Choose an empty (or existing) password slot using up/down, then press “A” button, this will put you in “create password” mode. You should see prompts in the console. The entries are stored – encrypted – in EEPROM. N.B. I didn’t create or study the encryption cipher (see https://github.com/gioblu/Cape), and at a minimum the length of the password is stored in clear text, so don’t put your launch codes in here, but should be sufficient for storing most passwords.
Once your password is set, use “B” button to have Arduboy type your password.
@ChrisS I thought you might find this interesting!
Another heads up: I spent some time yesterday analysing how secure this is.
(Disclaimer: I’m not a cyber security expert.)
A key length of 10 only provides 1,048,576 different private key possibilities, which can be calculated in around 0.3 to 0.4 seconds with an un-optimised algorithm running on a single thread on an i7 CPU.
(Including the other lengths, 1 to 9 bytes, only takes it up to 1,398,100 possibilities.)
Verifying which one is correct would take longer, but it would still probably only take a few hours depending on the verification method.
It is currently marred by three problems:
The salt is unusued. (Specifically the salt is 0, which makes it effectively nonexistant since x ^ 0 = x. *)
The “encrypting” is done with Cape’s hash function rather than its encryption function. Its hash function is quite straightforward and easy to brute force.
The private key is using a whole byte to store one of 4 values, which effectively makes the key act as if it were 1/4 of its actual length. If the 4 values were condensed into 2 bits, a 10 byte key could allow for 1,208,925,819,614,629,174,706,176 possibilities for a 10 byte key (pow(256, 10) instead of pow(4, 10), even more including 1 to 9 byte keys).
* 0 is the identity element of the abelian group (N, ^) where N is the set of (positive) binary integers and ^ is the xor operation. Group theory is weird, but useful.
Great analysis – I’m humbled! I knew things weren’t very secure, didn’t realize the situation was quite that weak.
I’ll take a look at using encrypt/decrypt instead of hash, I only chose hash because it was easier and I was in a rush, but what’s the point if a brute force breaks everything that quickly.
Sadly the only thing that can be done about the password letters is to encourage a longer length - or, I suppose, use the Serial interface to accept the unlock password from the terminal, allowing any printable character (still only 95 characters, not the 255 that could fit in a char).
I wasn’t going to make a big deal out of it because originally I was running on gut feeling and my mediocre maths skills, but when I got the test result I felt compelled to bring it up.
Truth be told I’m not entirely convinced Cape is a particularly strong encryption anyway, I’d like to analyse encrypt and decrypt when I get chance.
In all fairness encryption is a very hard thing to get right, which is why people tend to stick to algorithms that have been proven to be more robust. (Even then, people can only prove which attacks do or don’t work, they can’t prove an encryption is unbreakable.)
I was referring to the private key rather than the passwords.
You don’t have to map a single button press to an entire byte.
Four buttons could be mapped to two bits, thus using a whole byte instead of (effectively) one quarter of it.
The user would have to enter 4 times as many button presses to manage the whole 10 byte key, but that decision alone would make the system much, much harder to brute force (‘orders of magnitude’ as they say).
If the passwords are currently also restricted to consisting of variations of a, b, c and d (I don’t know if they are, I found the code a bit hard to follow) then you could probably use a similar technique to open up a wider range of available passwords for the user.
For example, combining 3 button presses into a 6-bit value (between 0 and 63), then using that as an offset into the valid set of ascii characters.
(Or you could try something like base64 or hexadecimal encoding.)
(Let me know if you want a copy of the code I used for testing by the way. It’s a bit messy but it does the job.)
The a/b/c/d is only used to encrypt/decrypt the passwords, the stored passwords are entered via the Serial link and they can be any (printable) character.
Having up/down/left/right create individual chars is an interesting approach; you’d have to enter a much longer sequence. I think it would be more intuitive to have an on-screen graphical password entering tool; I’ll play with this…
Post that testing code in a github gist or something, I’d love to check it out!
That’s what I’d originally assumed.
Technically any value can be sent over serial, but if it’s intended to be used with a console then it’s fair to assume only printable characters will be used.
I’d recommend doing it with a hexadecimal system.
E.g. print the value on screen in hexadecimal, have up and down increment and decrement the selected nibble and have left and right change the selected nibble.
It’s not very pretty, and it only calculates all the possible decrypted values, it still needs a human to look over the output or some mechanism to output the passwords, but here it is.
It’s in C# because I find C# the easiest language to use for throwing together quick one-shot programs.
(I very nearly wrote it in Haskell, but realised I didn’t know how to accurately test the speed of a Haskell program.)
If you need anything explained, don’t hesitate to ask, I tend to use Linq functions quite heavily when dealing with data processing.
The salt is unused and set to 0 in the default configuration, it is a choice of the user to select a salt value and change it during cape usage (for example to keep the same key but have an higher protection)
Each key character can be chosen between 0-255 value of a byte
Another thing you have not considered is the presence of the initialization vector and that to have a higher protection and higher the time needed to brute force this it is simply needed to use a longer private key.
I am aware. I was suggesting the salt be used by the password manager, because a salt of 0 makes the salt effectively nonexistant because 0 is xor’s identity element.
I was talking about @colinta’s code.
Currently instead of using the full 0-255 byte range, it’s only using the ascii characters ‘a’-‘d’, as seen here:
Which effectively makes the 80-bit private key (10 bytes) equivalent to a 20-bit key since only 4 of the 256 possible values are used (i.e. it’s like using 2 bits instead of the full 8 bits, cutting the effective length to 1/4).
That’s linking to the code for encrypt.
I haven’t yet looked into encrypt or decrypt enough to make any judgements, (and I probably won’t be any time soon because I have other things to be getting on with), but this password manager is using neither, it’s using the symmetric hash function:
which I have looked into and have proven isn’t enitrely suitable (on its own) for encryption.
CIao Pharap I agree with you also about the hash function, which has been designed to be quickly executed and to provide a really basic cypher, absolutely not suggested to hide passwords , I would use encrypt/decrypt with IV for that instead, with probably a private key as long as the password is.
Now have found the link to the repo this discussion is related to, I am sorry again
Hey @gioblu, I think you misunderstood Pharap - he was looking at my code, which only had the option of a/b/c/d (I mapped up/down/left/right to these letters), so it is MY code that was insecure. Plus I wasn’t using the salt.
AND I was using the hash function instead of encrypt/decrypt, which was not as secure!
@Pharap btw I’ve got new “password” code, it uses the arrow keys to bisect the screen in x and y directions, allowing you to choose two numbers (0-127 and 0-63) at a time. It’s pretty quick to enter 10 or more numbers that way.
Ooops @gioblu and @Pharap I see that you have already been chatting! Well check out the new code, I think it’s much better. @gioblu am I using the salt correctly, it doesn’t need to be hidden, does it?