2

I mostly want whatever help & suggestions you can give me about what I should avoid & what I should think about when making this.

I'm a reasonable programmer & I want to make my own program to hold passwords as an exercise.

Why not use any of the already existing password managers?

  1. I want to make one myself.
  2. I don't really trust them since I can't know what their code is doing to my passwords (like maybe it's storing them on a central server?... NO!)

I'm not aiming for Bank-level security, but it I will try to make it as secure as possible, but it should at least be an obvious upgrade for people that store passwords in unencrypted text files (aim low and avoid disappointment).

I'm using a "language" for mobile programming called Automate "unfortunately" that means that the program will be open source, so I think it's impossible to make it completely secure because anyone can see & modify their local version of the code (but they need both the code & someone else's save-file to compromise the security, and realistically then it's already game over for any security program).

Using Automate means that I don't have access to fancy libraries & stuff, but has to rely on very basic stuff like variables, lists, dictionaries, loops, if-statements & some built-in functions (here is a list of all available functions).

Some function examples: converting text to binary, convert a utf-8 text to sha1 (160 bit) or md5 (128 bit) hash, and I can do as many re-encodings of the text as i want, and I can switch the string to be another format, something like this:

utf-8 --> sha1 --> hex -->md5 --> binary --> sha1 again

I can also do character manipulation, so I can take a string, extract each letter and eg. add some ammount to that char's unicode-value, so I can do something like:

string value_1 = "abc";
string value_2 = "def";

// assuming equal length strings for simplicity.
for( int index= 0; index < value_1.length(); index++ ){ 
    string encoded = char( value_1[ index ] + value_2[ index ] ); // e=(a+d) at index 0
}
print( encoded ); // outputs: egi

I know that "security through obscurity" is a bad idea (that's why I ask here) but what else can I do?

What is the "best" way to encode a text so it can be stored somewhat securely in a text file and later be de-coded so the text can be read (preferably only by the owner)?

What other tips & suggestions do you have?

schroeder
  • 125,553
  • 55
  • 289
  • 326
Sebastian Norr
  • 169
  • 1
  • 1
  • 8
  • 9
    Possible duplicate of [Why shouldn't we roll our own?](https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own) – Joe Dec 01 '18 at 23:12
  • 4
    There are open source password managers such as KeePass – Joe Dec 01 '18 at 23:13
  • That possible "duplicate" is a good starting point, but I realize that it's almost impossible to make something uncheckable, so that's why I'm not aiming for bank-security, but merely trying to be better than un-encrypted passwords. – Sebastian Norr Dec 01 '18 at 23:21
  • 10
    The problem I see with this is that you want to use your password manager to secure your passwords. For educational purposes, this project is great, but for actually using it to secure your passwords, you're probably better off sticking to the widely used password managers – Joe Dec 01 '18 at 23:23
  • 1
    Yeah, that's for sure that real password managers is more secure. Do you have a suggestion for a password manager for Android? – Sebastian Norr Dec 01 '18 at 23:27
  • 7
    **Don't roll your own crypto!** Use an existing password manager. – forest Dec 02 '18 at 07:17

3 Answers3

22

Don't. You show a lack of understanding of the topic.

I don't really trust them since I can't know what their code is doing to my passwords (like maybe it's storing them on a central server?... NO!)

Read the source. For instance Keepass is Open Source. You can verify how it works, and if it transmits anything.

I'm not aiming for Bank-level security, but it I will try to make it as secure as possible, but it should at least be an obvious upgrade for people that store passwords in unencrypted text files (aim low and avoid disappointment).

False sense of security may be worse than no security. If I know it's a clear text file, I will treat it as such. If I believe it to be securely encrypted - but it's in fact not - I may end up compromising it.

I'm using a "language" for mobile programming called Automate "unfortunately" that means that the program will be open source, so I think it's impossible to make it completely secure because anyone can see & modify their local version of the code (but they need both the code & someone else's save-file to compromise the security, and realistically then it's already game over for any security program).

You should read about Kerchoffs principle. In short, the only secret of your scheme should be the encryption key. Assume that any attacker knows exactly how the encryption works.

No matter what language you use, it's possible to figure out how the app works. With Java it's trivial, with C somewhat harder.

Using Automate means that I don't have access to fancy libraries & stuff, but has to rely on very basic stuff like variables, lists, dictionaries, loops, if-statements & some built-in functions (here is a list of all available functions).

If you first do this, build it on established crypto libraries. The chances of breaking what looks like solid encryption trough some silly mistake is huge, and history is littered with broken crypto.

Also remember Schneier's law:

Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break.

forest
  • 65,613
  • 20
  • 208
  • 262
vidarlo
  • 14,890
  • 2
  • 43
  • 56
17

Disclosure: I am the Chief Defender Against the Dark arts at 1Password.

I am going to discourage you from trying at this point. As others have pointed out, your basic failure to understand key concepts (at this point in your learning) means that you aren't in a position to face some of the harder questions in the design of a password manager. I do not mean this as an insult; there is no shame in not knowing certain things.

Use an existing system

If your goal is to have a password manager that you can trust, you are better off using something built by people who know more and who have produced a system that has been subject to public scrutiny. Rolling your own is not going to give you something more secure than many of the systems (open source or commercial) that are available to you today. A number of your security concerns reflect a lack of knowledge in what makes certain systems secure.

If, however, your goal is to build your own for the sake of building your own, read on. And do the following in sequence.

First: Learn some cryptographic basics

First you will need to understand encryption much better. There are on-line courses in introduction to cryptography that are very good. Books that I would recommend to someone at your starting point would be Serious Cryptography and Understanding Cryptography. These books do not teach you enough to be able to start to make the kinds of cryptographic design choices that you need in building a secure password manager, as they don't go deep enough into many of the nuts and bolts decisions that need to be made. But you need to start from somewhere.

Second: Study the design of existing password managers

As mentioned by others KeePass is well-respected and open source, and presumably many of the security design decisions are well-documented (though I haven't looked.) Also note that the data format for KeePass 1.x was designed nearly two decades ago, and although it was well-ahead of its time, you should look at KeePass 2.x for anything you are building today.

Instead of pointing you to 1Password's current security design document (OK, I did just point you there), which involve sharing features that go beyond your needs, I would recommend that you take a look at our OPVault data format design, introduced in 2012. It's been superseded, but it is probably closest to the kind of thing that you need and is far simpler.

Another, simpler, open source password manager is pass. It has a wonderfully simple design, and passes off the encryption to PGP and the synching to git. (A cost of that simplicity is that a great deal of sensitive meta-data remains unencrypted.) You might find it valuable to seek a design in which your program merely employs a well-vetted file encryption tool such as GnuPG/PGP.

Studying these aren't going to be of much use to you until you've developed a better understanding of the very basics of cryptography first. So do take these steps in order. Don't try to model off of things that you don't understand; doing so would only lead to more confusion.

Third: Give it a first experimental try

A lot of people, including those with a sufficient understanding of cryptography and secure coding practices, under-estimate the difficulty in getting a password manager right. However, you should give it a try once you have finished the first two steps.

It's relatively easy (though still harder than one might think) to develop a password manager for data that will live only on one machine. But once synchronizing data across multiple devices becomes desired property, it impacts almost every other aspect of the design. This is not a reason not to try (once you have developed the basic knowledge and skill). But don't expect to develop something that would be safe and usable by another other than its developer without doing an enormous amount of work.

So be prepared to throw away this first attempt. It's purpose was to help you better understand the problems faced in developing a safe password manager.

You also should understand that your software development language choice should be driven by the task and not by whatever language you happen to know. Automate does not appear to be an appropriate tool for the job.

Fourth: Research password manager security

There is a growing academic literature on the security properties of different password managers. There are always a few papers on password managers presented at Usenix Security or ACM CCS. But you will have to acquire the skill of reading academic papers.

You will find through this process that although in some cases, there are password managers that can be said to be more secure than others, but for the most respected ones you will find that they have made different security trade-offs. One of many examples of such a security tradeoff is browser integration. Web browsers are hostile environments and inter-process communication is hard to do right. And so password managers with browser integration (like 1Password) have a broader attack surface than those that don't (like KeePass). But at the same time, password managers that don't have browser integration don't product users from phishing attacks (Naturally, I think that we've made the right decision for 1Password, but I can fully respect those who make the opposite choice.)

There are other choices in the design of a password manager that I cannot respect. But I will let your research into them inform you of those.

Even if you don't want to build a password manager that is up there with the most respected ones, you should try to develop an understanding of the difficult choices that go into their design.

Finally: Try again

Welcome to the world of password manager development! Technically we would be in competition, but there are so many people who need to use a password manager who don't even know they exist, that we are all trying to expand the market. I am happy to see another well-designed password manager being offered, but something that is just snake oil and built by people who don't have a deep understanding of some of the problems not only hurts the people who use that system, but it also tarnishes the reputation of password managers in general.

Jeffrey Goldberg
  • 6,420
  • 17
  • 21
8

What is the "best" way to encode a text so it can be stored somewhat securely in a text file and later be de-coded so the text can be read (preferably only by the owner)

This is literally exactly what "encryption" is. The best way to do this is to use a secure cryptographic cipher (a function that takes as input a key and some plain-text data and emits an incomprehensible "ciphertext", or that takes a key and some ciphertext and emits the original plain text). The key (at least, the one used for decryption; in some ciphers you use one key for encryption and a paired but different one for decryption) must be kept secret and must not be predictable by an attacker, but most ciphers (if used correctly) can encrypt and decrypt data far, far longer than their key. For example, I have a 2TB (2000000000000-byte) hard disk encrypted using a 256-bit (32-byte) key.

The question of what cipher is "best" depends on a lot of things, but right now the most widely-trusted cipher is called AES (Advanced Encryption Standard). AES by itself can only encrypt small blocks of data (exactly 16 bytes), so it is combined with a block cipher mode of operation and sometimes a padding that lets you re-use the same key with a (nearly) unlimited number of blocks and with data that isn't an integer multiple of the block size. In this way, I can have some secret data (such as a password file) of essentially arbitrary length, and it is totally unreadable to anybody who doesn't have the right 16- or 32-byte key (which in practice can be derived from a password, though most real-world passwords are far more predictable than a proper encryption key so this does make it weaker)


Any decent password manager (including the multiple available commercial and/or open-source ones) use a "master password" or "master key" to protect the stored passwords. This master secret is used to encrypt and decrypt an encryption key (which is totally randomly generated and never stored in plain text, but is stored in encrypted form along with the encrypted passwords), and the encryption key is used to actually encrypt and decrypt the passwords (which, again, are never stored in plain text). The master can either be a key that is stored in some device (like a Yubikey or flashdrive that must be entered before decrypting the passwords), or a password itself that is turned into a cryptographic key by running it through a key-derivation function (essentially a very computationally expensive salted cryptographic hash function).

The reason for this additional layer of indirection (master key wrapping the encryption key which in turn wraps the passwords, rather than just using the master key to wrap the passwords) is so that you can change the master or have multiple master secrets (say, a password and also a recovery key stored on a hardware token) without needing to re-encrypt anything except the encryption key. This also makes it easier to handle password sharing between users (where one user wants to allow another user to see some of their passwords, but not all), if you ever desired to add that feature.

Unfortunately, Automate doesn't support any cryptographic ciphers (and the hash functions it supports are old and deprecated, although you can build a KDF out of those if you have to). Short of re-implementing something like Blowfish or AES using Automate - which you definitely should not do - that means the language is simply not suitable for any app that needs to handle sensitive data.


You seem to have a few false beliefs about security which I'm going to try to clear up here.

that means that the program will be open source, so I think it's impossible to make it completely secure because anyone can see & modify their local version of the code

There are lots of extremely secure open-source tools for storing secret data. A few examples: Gnu Privacy Guard (GPG), TrueCrypt/VeraCrypt, OpenSSL, numerous email clients with support for the OpenPGP and/or S/MIME standards like Thunderbird, etc. The key difference between all of these programs and your idea is that they all use actual encryption.

they need both the code & someone else's save-file to compromise the security, and realistically then it's already game over for any security program

This is very, very false. A crucial requirement of good encryption is that even if the attacker has the full ciphertext (encrypted data, such as your password save file, and any data typically stored along with it such as a message authentication code and the initialization vector for the encryption) and knows the full details of the algorithm used to encrypt it (such as AES-256 in CBC mode with that known IV and using PKCS5 padding, as implemented in a particular version of the open-source "OpenSSL" tool), the attacker still should not be able to decrypt the data without a brute-force attack on the key, which can be made long enough that such an attack is totally impractical (we're talking "using every processor in existence on earth, you still wouldn't finish before the heat death of the universe" levels of impractical, here). That is what people mean when they say "obscurity is not security"; if your system is secure only so long as the attacker doesn't know exactly how it works, it actually just isn't secure.

I'm not aiming for Bank-level security

Aim higher. Banks often don't actually use very good cryptography (or security in general), by modern standards. It would be harder to get into my password manager's vault than into my bank account, because my bank doesn't permit the use of passwords that are as strong as my password manager does, and the numbers needed to extract money from my account (account number + routing number, or card number + ZIP code + CVV or PIN) are probably easier to guess or find than even the bank account password (still not truly easy, but probably easier).

I don't really trust them since I can't know what their code is doing to my passwords

Even password managers that aren't 100% open-source should still enable you to see what they actually do with the passwords. An example is LastPass, which is commercial software but is offered as browser extensions. Browser extensions are written in JavaScript and are not compiled, so you can read the source code yourself and see exactly what it does (and you can also use your browser's developer tools to debug the extension while it works and monitor what network traffic it generates or receives). Obviously, you personally might not want to do this, but you could, and people have; the idea is that enough people do this that if they try to pull anything sketchy, it would get caught and announced publicly, and then nobody would use it anymore.

like maybe it's storing them on a central server?... NO!

Some security people definitely agree with you that they don't want their password vault going to any device they don't control (such as a password manager company's server). However, I don't think you have a good grasp of the actual risks. Done right (and remember, you can verify that it's done right), the password manager company can never decrypt your vault, so even though they hold onto it they cannot peek inside. As mentioned above, even though they have the vault (the ciphertext) and obviously know exactly how it was encrypted (because it was their code that did it), they cannot decipher the contents without the encryption key, and well-designed password managers never store or transmit the encryption key (or any material used to derive it). There is still some risk, because they can try to steal or guess your master key somehow without you knowing that it's happening (for example, by trying to guess your password using an "offline" attack), which they cannot (usefully) do if they don't have the ciphertext (the vault), but it's probably a lot less risk than you thought.

CBHacking
  • 42,359
  • 3
  • 76
  • 107