Storing passwords without saving them
Hello. About two years ago on Habrahabr I from some commentary got acquainted with an interesting way of storing passwords without saving them. The phrase looks strange, but I could not more accurately describe the nature of this program. The method consists in the fact that in order to obtain a password for a specific account on a particular site, it is necessary to drive a line “glued” from the master password, site address, and login on the site into a hash function.
keyword + sitename + login
In this line, keyword is the master password used to “store” passwords for all sites. Next is the website address, then login. Having driven this line into the hash function, we get the output of the character string, which can be fully or partially used as the password for this account on this site. The keyword at the beginning of the line makes it impossible to find out the password if the site address and login are known. The result of the hash function is more than enough for a password. But password strength still leaves much to be desired. Each character of such a password can take only one 16 values, since the result of the hash function is a string of numbers in hexadecimal notation.
I tried to fix this flaw. Next, I’ll tell you how.
The result of the hash function is a hexadecimal string, consists of the hexadecimal characters “0123456789ABCDEF”.
For example, from the line “keyword + sitename + login” after running through the hash function sha256, a hash is obtained:
Each character is half a byte (notebook). The combination of two adjacent characters can take 256 values, since it is a symbolic representation of a byte. The program processes the hash string in groups of two characters.
The program translates each group into a numerical representation. The result is a number from 0 to 255. There are more than enough values to encode one password character. In the program for generating the password, I used lowercase and uppercase Latin characters and numbers, a total of 63 possible characters. Next, I will call the set of possible password characters the alphabet. The alphabet can be made as you wish, depending on whether a complex password is needed, or a simple one. To do this, you just need to change one line of the program. The program is written in C ++.
Next, the program finds the remainder of dividing the byte by the number of characters in the alphabet (63). The remainder of dividing by 63 can take values from 0 to 62. This remainder will be the index of the character in the string alphabet.
I post the part of the program that is responsible for processing the hash. At the end of the article there is a link to the full source code of the program.
Using the program is easy. Enter the master password, website address, login. Press enter. All the necessary information (website address, login) can be stored in the head or written down somewhere. This information is not secret. But the master password will have to be remembered.
For example, we enter the line in the console:
keyword + sitename + login
Press enter, we get the password:
nEWWzxS7bwDW7lxyNI8f7mC4M4zEckYI The
password consists of 32 characters and looks quite reliable
Now I’ll talk about a small minus of this method of turning a byte into one of the 72 characters of the alphabet. The downside is that when using the remainder of division as the index of a character in the alphabet, part of the alphabet with indices from 0 to 255% 63 is more likely to get into the password. For clarity, I’ll give an example of dividing a “toy” 3-bit number by 3. A 3-bit number can take values from 0 to 7. I have designated the percentage by the operation of finding the remainder of the division. There will be no higher mathematics, sorry.
We see that the deuce as a result of finding the remainder of the division occurs less frequently than zero and one. A similar situation will be with dividing the byte by the number of characters in the alphabet. This problem can be solved by using the remainder of the division not bytes, but words (i.e. two bytes). Then getting all the characters in the password will become more equally probable. However, the password length will be reduced by half, i.e. becomes equal to 16 characters. Such a password will in some cases be considered too short. This problem can be solved by re-running the hash through the hash function. We see that this minus is quite fixable.
I wanted to talk about this program on the hub and read the comments. It was interesting to deal with this program, because the idea is quite simple and promising, but could not be found on the Internet. If you know programs similar to the above, please write the name in the comments. Also, please do not kick too hard for the fact that the program has no presentation. The program should be considered as a training.
The link to the archive contains the compiled program and source: Everything is distributed under the GPL license. =)
rusfolder.com/31528284
keyword + sitename + login
In this line, keyword is the master password used to “store” passwords for all sites. Next is the website address, then login. Having driven this line into the hash function, we get the output of the character string, which can be fully or partially used as the password for this account on this site. The keyword at the beginning of the line makes it impossible to find out the password if the site address and login are known. The result of the hash function is more than enough for a password. But password strength still leaves much to be desired. Each character of such a password can take only one 16 values, since the result of the hash function is a string of numbers in hexadecimal notation.
I tried to fix this flaw. Next, I’ll tell you how.
How the program works
The result of the hash function is a hexadecimal string, consists of the hexadecimal characters “0123456789ABCDEF”.
For example, from the line “keyword + sitename + login” after running through the hash function sha256, a hash is obtained:
dc6463dfd7d86d06db49ea63061c9a8bf6a7ff17fe23b5bd3dfbd7a25d1b6769
Each character is half a byte (notebook). The combination of two adjacent characters can take 256 values, since it is a symbolic representation of a byte. The program processes the hash string in groups of two characters.
dc 64 63 df d7 d8 6d 06 db 49 ea 63 06 1c 9a 8b f6 a7 ff 17 fe 23 b5 bd 3d fb d7 a2 5d 1b 67 69
The program translates each group into a numerical representation. The result is a number from 0 to 255. There are more than enough values to encode one password character. In the program for generating the password, I used lowercase and uppercase Latin characters and numbers, a total of 63 possible characters. Next, I will call the set of possible password characters the alphabet. The alphabet can be made as you wish, depending on whether a complex password is needed, or a simple one. To do this, you just need to change one line of the program. The program is written in C ++.
const string alphabet="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
Next, the program finds the remainder of dividing the byte by the number of characters in the alphabet (63). The remainder of dividing by 63 can take values from 0 to 62. This remainder will be the index of the character in the string alphabet.
I post the part of the program that is responsible for processing the hash. At the end of the article there is a link to the full source code of the program.
#include
#include
#include
#include
#include "sha256.h"
void convert(string strIn, string &strOut)
{
const string alphabet="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
const string hex="0123456789abcdef";
unsigned char str[32];
for(int i=0; i< 32; i++) {
str[i]=hex.find_first_of(strIn.at(i*2))*16+hex.find_first_of(strIn.at(i*2+1));
strOut.at(i)=alphabet.at(str[i] % alphabet.length());
}
}
int main() {
SHA256* yourInstanceName = new SHA256();
std::string digest;
string strIn, strOut="00000000000000000000000000000000";
while(true) {
cin >> strIn;
convert(yourInstanceName->hash(strIn), strOut);
cout << strOut << endl<< endl;
}
return 0;
}
How to use the program
Using the program is easy. Enter the master password, website address, login. Press enter. All the necessary information (website address, login) can be stored in the head or written down somewhere. This information is not secret. But the master password will have to be remembered.
For example, we enter the line in the console:
keyword + sitename + login
Press enter, we get the password:
nEWWzxS7bwDW7lxyNI8f7mC4M4zEckYI The
password consists of 32 characters and looks quite reliable
Program Benefits
- The password database, as is the case with programs similar to KeePass, is missing. So you don’t need to backup password databases.
- The password database cannot be stolen or hacked because it does not exist.
- The implementation of the program is very simple.
- Cross-platform, as only standard C ++ libraries are used.
Cons of the program
- At this stage, the program is console, it is difficult to copy the password from it.
- It is necessary to remember or write down the website address and login to it.
- Changing passwords is problematic.
Now I’ll talk about a small minus of this method of turning a byte into one of the 72 characters of the alphabet. The downside is that when using the remainder of division as the index of a character in the alphabet, part of the alphabet with indices from 0 to 255% 63 is more likely to get into the password. For clarity, I’ll give an example of dividing a “toy” 3-bit number by 3. A 3-bit number can take values from 0 to 7. I have designated the percentage by the operation of finding the remainder of the division. There will be no higher mathematics, sorry.
0% 3 = 0 | 3% 3 = 0 | 6% 3 = 0 |
1% 3 = 1 | 4% 3 = 1 | 7% 3 = 1 |
2% 3 = 2 | 5% 3 = 2 |
We see that the deuce as a result of finding the remainder of the division occurs less frequently than zero and one. A similar situation will be with dividing the byte by the number of characters in the alphabet. This problem can be solved by using the remainder of the division not bytes, but words (i.e. two bytes). Then getting all the characters in the password will become more equally probable. However, the password length will be reduced by half, i.e. becomes equal to 16 characters. Such a password will in some cases be considered too short. This problem can be solved by re-running the hash through the hash function. We see that this minus is quite fixable.
Conclusion
I wanted to talk about this program on the hub and read the comments. It was interesting to deal with this program, because the idea is quite simple and promising, but could not be found on the Internet. If you know programs similar to the above, please write the name in the comments. Also, please do not kick too hard for the fact that the program has no presentation. The program should be considered as a training.
The link to the archive contains the compiled program and source: Everything is distributed under the GPL license. =)
rusfolder.com/31528284