Password Manager (Get Crackin challenge)

Hey all,

This thread is documenting my struggles with @Atomic_Charge's GET CRACKIN' challenge.

As I mentioned in my post there, I'm going to be creating a password manager because I'm frustrated with the state of current password managers. If they were easier, I'm sure more people would use them. That's my goal here. I'm going to build something that's so seamlessly intergrated with major browsers and other systems that it's almost easier for people to use it.

Currently the project is not complete and not near working prototype stage.

If anyone has a working knowledge of data security in this context, let me know. I'm in need of someone who may know a few things about keeping this secure.

Day 1: framing the GUI and building the data store


I've never really touched GTK+ before, so this is a very new area for me. I'm sitting here with coders block, so I've decided to get lunch. I'm going to put the github link up after I get some more code in the repo, but for now, I feel more comfortable keeping it secret.

Currently I'm thinking I'll use a custom class to handle storing the account data, preferences and other information that will be held in a database. I've decided on the cryptography.fernet module to encrypt the entire store as AES_CBC.

I'm thinking about using secondary encryption on the passwords so that a memory cloning attack can make it more difficult to get the data. that would require a bit more work though. In order to do that, I'd need to make sure that we store a secondary key in the data store and use that to decrypt the password from an account. That would also require making sure we pass by reference so we can securely wipe the memory address that stores the data. Pass by refernce at a cursory glance, looks overly complex compared to C. I guess it's time to get started on the data store decide how best to implement the Fernet encryption.

I've got the data store partially framed. I'm going to be using custom-written classes to handle storing the data, as opposed to something that's available. Hopefully this will allow easier fuzzy searching of the data. I had a not so good day writing code, so I decided to go bowling with friends around 16:30. Hopefully tomorrow will be more productive. I have to meet a client at 12:00, but when that's through, I'll be writing code for the rest of the day. I've got my fresh air for the week, so hopefully, I'll be set to work tomorrow. I've also cycled in air from outdoors through my work room a couple times today.

Day 2: Finishing the data store and frustrating encryption


So, where to begin. I'm not quite finished today, as there are a few things I'd like to add in to the data store before I call it done, but I'm pretty confident that the storage and retrieval part of the data store is complete and stable. I guess time will tell for sure.

I've got encryption working as well. I've spent a good 4 hours working on this and it's bothering me that I didn't know enough to get this stupid stuff working quickly. Essentially, I was struggling with getting strings converted to binary format. This is accomplished by calling str.encode('utf-8') which will return a format that the cryptography module will accept.

The in-memory database, while most data is decrypted, keeps the password encrypted until it's needed. This will add another layer of security, by reducing the chances of a password being stored in plaintext in memory. I'm not sure how well this will work in practice, since the attacker may have the password, salt and number of iterations the KDF module uses. Even though, that can make getting into a database easy, if an attacker can pull data out of your system memory, I'd argue that you've already lost. This is why I always recommend shutting down instead of going into sleep mode or hibernating.

I've also got the storage and retrieval of the database working. Essentially, what a .kmdb file will look something like this:

{
    'version': 1, #database version, just in case we run into compatibility issues, we can run upgrade methods against the database.
    'secure': 'AES encrypted cyphertext, although, it may be early to call this data secure.....',
    'config': {'iterations': 1000000, #default iterations
               'key_type'  : 'SHA256', #algorithm to hash the password, that gives the key for the fernet module to encrypt data.
               'salt'      : 'b'\\\xe8\xc5\x8ei\xebd\xe6\xba\xbcM<\xdc7[\xa7' #example salt for key.
              }
}

So essentially, we're going to be having three items that are not securely stored. key type, iterations of sha256 and salt. Again, I'm not too familiar with cryptography, so I'm not sure if we are able to encrypt that data. If someone can chime in and tell me what requirements there are, I'd be grateful.

I'm doing a few tests currently to double-check the sanity of the storage method, but once it's done, we should have smooth sailing and I can move on to the (arguably) more frustrating aspects, GUI.

Day 3: Files and Groups


Today I spent quite a while learning about how GTK popup windows and Entry classes work. I'm happy to say I'm getting very close to a functional prototype. The thing that's holding me back mostly is that there are a few aspects of the program that don't quite feel right. Adding and removing account groups isn't all that smooth right now, but I may have that sorted shortly. I've not even begun to work on editing account groups, but that can't be too difficult.

I haven't got the front-end to work with actual Accounts yet, short of showing a simple ListBox of them. That's okay though, I'd have to say it's been only about 15-20 hours and 1127 lines, so if I consider that, it's not bad. I'd say I'm going to have another 20 or so hours to get a stable build. I'm not sure what we should call stable, but I'll definitely call it 1.0.

I'm also going to eventually build a Firefox and Chrome plugin to interface with the program. I'm still hashing out (pun intended) how I'm going to securely implement this, but my first thoughts are to add a section in the "secure" part of the database where we can store private/public keys that the browser plugins can use to communicate to a Unix socket and transfer data as needed to and from keymaster's database. These key pairs will be automatically configured, but the user will need to manually verify each plugin the first time it connects, to prevent malicious code from attempting to connect to the API.

I'm not sure how people feel about storing sensitive data in python, but I'm definitely interested in finding out, so please let me know what you're all thinking on this.

I'm starting to cut it close to the deadline for Get Crackin' but I'm not letting up. I've been a bit busy this week, and next week I'm going to probably be working nearly 70 hours, which doesn't bode well for the deadline, but I'll definitely be submitting the project regardless. I also plan to maintain and iterate on the project for the foreseeable future. So unless I kill myself on my bike, this project will stay alive.

I don't expect browser plugins to make it into this month's challenge, as I've never built one before, but I plan on using the next challenge to either iterate on this project or build something else.

Alright, long update. This was a productive day.

Day 4: Account details and more


Today I spent a good amount of time getting the account details working. It's obviously not very pretty yet, as can be seen from this post, but I'm not a UI engineer. If anyone has input, please do tell me. I keep thinking something isn't quite right on the details pane (right side of the window). It's just not doin' it for me on the visual aspect.

I also made an attempt at building a password generator, but that isn't working quite like I wanted it to, so I've held off on implementing it in front-end. It's definitely in the backend, but you'll see why it won't do if you look at the code.

I've added a lot of code to widgets.py, as I'm starting to code more modularly. It's really helping me speed things along, although, it's not 100% modular yet. I'll add that to my todo list as "pre 1.0". I also realized that the password binary conversion isn't proper, so I'll have to change that up asap. I'm using a method that doesn't quite cover all cases when I should just use str.encode('utf-8'). That's probably what I'm working on tomorrow.

This project has started to be less about the whole Get Crackin' challenge an more about keeping my mind sharp. Regardless of the place I am in in life, I tend to get depressed. This has given me a good distraction from that. I suppose when you're busy, you don't have time to be depressed.

I'm still having problems with FileChooserDialog, so if anyone has any suggestions, that would be awesome.

This update is brought to you by Tostitos and Ballast Point.

Day 5: Account CRUD, Group Icons, Finalizing Files


Today was a hell of a day. I'm extremely satisfied with my progress. I'm not quite through with what I'm doing, but I've got responsibilities that I've been putting off, so I may be calling it quits for the day.

Today I got account CRUD working. You can now create, edit and delete accounts from the account details pane. That took a while, and there is still more to do with the account details aspect of it, there are a few things that just don't want to render at all. (I'm looking at you, Gtk.TextView) Anyways, I'm at the point where I'm happy with my program, minus a few little things, that over the next week, I should be able to iron out.

Addressing files; yesterday I mentioned I was having issues with FileChooserDialog. I have successfully made it my bitch and achieved glory by getting it to operate in a manner that I'm happy with. At this point, we have a system for loading databases, saving databases and creating a new database. I can't imagine we'd need much more, except maybe a save as...

I've created a dialog for configuring a new database. I don't currently have away to edit the settings, but that is one of the small things that just needs to be fixed. For now, it allows you to enter a password, (twice, with correctness verification), set the number of rotations on the key we do and enable markdown support for notes, which is 100% not supported currently, and probably won't make it into V1.0, so I may remove that checkbox.

In addition to the account details, I'm doing a little work on the group add dialog. I am going through the gtk icon browser as I type this, looking for good icons to include in the default set of icons for the system. The idea is you click the plus icon to add a group, you set a group name, and you choose an icon. If you don't choose an icon, you'll be using the (as of now) default system-lock-screen-symbolic icon, to help prevent crashing the beautiful program that is.

I still need to work on the group-rename, and group-remove. I want to make sure that if there are accounts within the group, it warns you that you will lose all the accounts within that group upon removal. Ideally, we'd have a configuration where it just removes it and gives the option to "undo" the action, but I'm just trying to get the system working, then I'll work on making everything nice.

I think it's safe to say, that short of a few (essential) features, I have a working prototype, so at any time, I'm able to submit it as "complete" but that would only discourage me from working on it, so I want to get it further along.

Now to be responsible.

Day 6ish: Preparing for end of Get Crackin'


Today was frustrating. I spent way longer that I should have trying to figure out how to get a mysterymeat menu, (the icon between search and your user icon on the forum) working in the method I wanted, and it's still not perfect. :/ I just clearly don't know GTK+ well enough. I'm at the point where the system is almost ready. I've got editable preferences that save, password generation, but no auto-type. That's the plan for tomorrow. Hopefully I won't have a migraine tomorrow. I'll be posting some images in a post below after posting this.

I'm having issues with parts of the account details pane, but I'm working on that currently. Ideally, I can pound out the issues there and I can call it finished.

I'd like to make a few additional modifications to certain features of the password field of the account details pane, but that may happen after I submit.

I think I'm nearly complete on the GTK side of the application. My next stages are to start building an API for a UNIX socket and start building browser plugins, which will be another first for me.

All in all, I've learned a hell of a lot about GTK and definitely like it better than web browsers for building a user interface. It's just so much more robust and nice. I mean, For every object I want, I extend the GTK class of the closest thing to what I'm building and make my modifications. There isn't really an equivalent to that in web development until you get into Angular and other frameworks. I guess I can add front-end development to my resume now...

Short update today. This update made late by Nvidia cards.


I'm not used to writing like this, so bear with me while I get in the habit of it. Also, much of this text is going to be written when I am too tired or distracted to work on the actual code, so I'll be in a less coherent state. You have been warned.

While I won't be able to update this daily, I plan on updating it regularly. Ideally, there will be three or four updates per week.

Some people asked for pics, so..... here, happy now?

7 Likes

Why RSA? Why not just use symmetric encryption like AES256?

2 Likes

Here I am being a doofus. I was thinking AES, and typing RSA. Clearly I was tired.

1 Like

Ah, haha

I'm getting mildly frustrated with all the damn acronyms.

Anyways, here's a link to the cryptography library I'm using.

Ah, I've never done anything with cryptography with python before so I had not heard of that library. I don't really know enough about cryptography to judge whether it's secure or not but it seems like a popular library. Apparently there is also a python module for GPG.

From my short audit of the code, it looks secure. I can't say how much so, but I'm implementing it through a wrapper class, so I will be able to change it out very easily if needed.

python module for GPG.

Of course there is. There's a python module for everything. Thanks for that!

import antigravity

3 Likes

Day 2 update posted. If anyone's got any insight on whether or not any of the data that's not encrypted can be encryped, I'd be happy to pass it to the encrypted side.

Here goes, Github link. I know the code probably sucks, but I'm very new to python-gobject, so hopefully, this will teach me to be good enough.

I'll be posting an update soon, as I've made some progress, but I'm not quite done for today. I've probably go another 2 or 3 good hours in me today.

Damn, I need some food.

1 Like

An update has arrived, I was working on the file management and graphical aspect of the program today.

It's coming along nicely.

1 Like

You got some screenies?

Incoming screenies. I'm running into some issues with database creation, as explained on this thread. If you're in the know with python and GTK+, Help would be appreciated!

When you load in, it looks like this.

Database open dialog box

Dialogs that keep your password safe!

once the DB is loaded, this is what we get.

So, I had to hack the database to get the accounts in there for now, but I'm working on the account widgets today. See the problem is that there are so many things that need to be done and the more work I do, the more I find out that needs to be done. My todo list has gotten twice as long and there are no additional features that I've added.

Ideally, I'll have CRUD done for accounts themselves today, but I can't guarantee that 100%.

2 Likes

Quick peek at what I'm working on right now. This is obviously a work in progress, so feel free to give me feedback!

This is still WIP, but I'm confident that it's progressing nicely. I'm probably going to call it for the night, as I've put a good 7 hours into it today.

Fuckkk this really makes me wish I could find my "chat program" I made in high school so my friends I wasn't allowed to talk to could message me without violating the blocks(cause it was hosted locally ;))

This was actually really awesome at the time even though it was shit design, it was entirely encrypted at the time it loaded in the browser, so unless you had access to the RAM/browser memory then you were SOL.

Secret sauce btw(probably not secure in all reality), was that upon account creation we generated a public key based around password + salt and another value(I forget exactly). The password was client-side SHA256 in the case of a man-in-the-middle with SSL, then bcrypt + secondary salt in the database(and only used for authentication when sent to the server), the salts were plaintext in the DB, and the public key was plaintext in the DB. Workflow below.

  1. User fills out fields to create account.
  2. Upon submit button click the fields are validated to be filled out, matching, and follow all required policies. A salt is created for the public and private key. The password + salt is turned into a SHA256 value via Javascript. This password + salt is also used to generate a public and private key, the private key immediately being destroyed from RAM as soon as the public key is created. This information is sent to the server in JSON format. A salt is generated on the server-end and the SHA256 value is concatenated with the salt and then a bcrypt value is created. All values are stored in the database.

Upon login the salts are grabbed from the DB, the first one being used to create the SHA256 hash which is then sent to the server and bcrypted to authenticate. The private key is generated at the same time, and is stored only in local memory, destroyed immediately upon exiting the tab, authentication failure, or the session ending/logout.

When a user sends a message, the DB is queried and the public key of the recipient and the sender are obtained. Two copies of the message are created, one encrypted in Javascript by with the sender's public key, the other with the receivers. This data, along with who the receipient and sender are are stored in the database.

When a chat history is opened, the DB is queried and all messages that are tagged as encrypted for that user in that chat ranging back for x messages(x being the chat history length) are received by the web browser. The messages are decrypted in JavaScript and then put into the chatbox in the correct order. Any message that fail to decrypt send an error log to the server and report an error to the user.

I didn't have sockets to allow live-chat, a page refresh was necessary, but this was really cool at the time when I was in school and banned from other students. Hopefully this sparked something.

I've pretty much got the encryption down, but thanks for the share. I'm definitely interested in seeing how others implement security, since lots of it is closed source.

It makes sense to be closed source, of course, as it makes it hard to view source and see easily implementable bugs, but at the same time if whitehats find those bugs they can fix it fast.

I wrote my own (tiny) little password manager which generates passwords procedurally rather than storing them on disk.

https://github.com/ArthurRasmusson/PPG

If anyone is willing to have a look and give me their honest opinion I'd love some feedback or to hear if other people have thought of implementing a password manager this way. :)

If anyone likes the idea and wants to join in on the development I love the idea of collaberating on free open source stuff.

I'd be happy to have a look when I get a minute today.

Edit: @MyNewLamborghini interesting implementation. I like it, but I'm not too familiar with cs, so I may not be too much help.

Although, it looks like you've got a lot of extra imports.

Are you using md5 to generate the password? That's a unique method, if I've ever seen one.

Day 5 update posted. More screens either tonight or tomorrow.

Ya, I'm using md5 and base64. I need to hash the users input using md5 because it shortens the user's seed key string to 32 characters. If I were to just put it through base64 the length of the output could be very long depending on the user's input.

As far as I know MD5 is non-reversible.

I'd like to implement a feature to read a file from off an encrypted usb (perhaps using veracrypt for encryption) where the user could store an extremely long string which could be read into the program as the seed instead of having the user enter the seed manually at runtime. Assuming that running the seed through base64 and md5 is indeed a secure method of generating passwords where the end result isn't actually reversible to the original seed then this should prove a really effect method of managing passwords since nothing would ever be stored on disk and even if a cracker was to get a password dump from some service like twitter or something all of your passwords would be totally different.

I also think it simplifies things for the end user because rather than having to think up a new password for every service which you store in your password manager you would just input your seed key and then type the name of the service to get a password for that service.