C++ simple password-protected console appSecurely handling a password protected applicationSimple...
What do you call the infoboxes with text and sometimes images on the side of a page we find in textbooks?
Proof of Lemma: Every integer can be written as a product of primes
Why are on-board computers allowed to change controls without notifying the pilots?
Why isn't KTEX's runway designation 10/28 instead of 9/27?
Why does this part of the Space Shuttle launch pad seem to be floating in air?
Perfect riffle shuffles
The One-Electron Universe postulate is true - what simple change can I make to change the whole universe?
Why are all the doors on Ferenginar (the Ferengi home world) far shorter than the average Ferengi?
Can I rely on these GitHub repository files?
How do ultrasonic sensors differentiate between transmitted and received signals?
Adding empty element to declared container without declaring type of element
How can a jailer prevent the Forge Cleric's Artisan's Blessing from being used?
Can a Bard use an arcane focus?
Latex for-and in equation
Lightning Web Component - do I need to track changes for every single input field in a form
A workplace installs custom certificates on personal devices, can this be used to decrypt HTTPS traffic?
"lassen" in meaning "sich fassen"
Can somebody explain Brexit in a few child-proof sentences?
Greatest common substring
Partial sums of primes
How can I raise concerns with a new DM about XP splitting?
Simple recursive Sudoku solver
Did US corporations pay demonstrators in the German demonstrations against article 13?
Freedom of speech and where it applies
C++ simple password-protected console app
Securely handling a password protected applicationSimple mathematical console applicationBasic password authentication system appPassword protected Joomla administrator folder with PythonSimple password encryption / decryptionConsole based password generatorConsole random password generatorSimple login and authentication appQuadratic Functions Calculator/Table (Simple console app)Forgot password / Reset password
$begingroup$
I have been reading about passwords and hashing algorithms and what not and decided to write a program.
Overview: The user should be prompted to create a password the first time the program is executed. They should enter a key and confirm it. If they have executed the program previously, then they should just enter the password to gain access.
I determine if the user has run the program by checking if key.txt exists. Is there a more preferred method?
I tried to streamline some code with the two bool functions. Any other suggestions for cleaner or more concise code?
#include <iostream>
#include <fstream>
#include <string>
#include "sha256.h"
using namespace std;
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
if (inFile) {
keyExists = true;
}
return keyExists;
}
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
int main() {
if (keyExists()) {
string key;
string storedKey;
cout << "Please enter key: ";
getline(cin, key);
SHA256 sha256;
ifstream inFile("key.txt");
getline(inFile, storedKey);
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
}
else {
string key;
string confirmKey;
cout << "Please create a key: ";
getline(cin, key);
cout << "Confirm key: ";
getline(cin, confirmKey);
if (isMatch(key, confirmKey)) {
SHA256 sha256;
ofstream outFile("key.txt");
outFile << sha256(key);
}
else {
cout << "Keys do not match!n";
}
}
return 0;
}
Many thanks to Stephan Brumme for the awesome hashing algorithm code! This was very easy to implement.
c++ authentication
New contributor
$endgroup$
add a comment |
$begingroup$
I have been reading about passwords and hashing algorithms and what not and decided to write a program.
Overview: The user should be prompted to create a password the first time the program is executed. They should enter a key and confirm it. If they have executed the program previously, then they should just enter the password to gain access.
I determine if the user has run the program by checking if key.txt exists. Is there a more preferred method?
I tried to streamline some code with the two bool functions. Any other suggestions for cleaner or more concise code?
#include <iostream>
#include <fstream>
#include <string>
#include "sha256.h"
using namespace std;
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
if (inFile) {
keyExists = true;
}
return keyExists;
}
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
int main() {
if (keyExists()) {
string key;
string storedKey;
cout << "Please enter key: ";
getline(cin, key);
SHA256 sha256;
ifstream inFile("key.txt");
getline(inFile, storedKey);
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
}
else {
string key;
string confirmKey;
cout << "Please create a key: ";
getline(cin, key);
cout << "Confirm key: ";
getline(cin, confirmKey);
if (isMatch(key, confirmKey)) {
SHA256 sha256;
ofstream outFile("key.txt");
outFile << sha256(key);
}
else {
cout << "Keys do not match!n";
}
}
return 0;
}
Many thanks to Stephan Brumme for the awesome hashing algorithm code! This was very easy to implement.
c++ authentication
New contributor
$endgroup$
2
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
I have been reading about passwords and hashing algorithms and what not and decided to write a program.
Overview: The user should be prompted to create a password the first time the program is executed. They should enter a key and confirm it. If they have executed the program previously, then they should just enter the password to gain access.
I determine if the user has run the program by checking if key.txt exists. Is there a more preferred method?
I tried to streamline some code with the two bool functions. Any other suggestions for cleaner or more concise code?
#include <iostream>
#include <fstream>
#include <string>
#include "sha256.h"
using namespace std;
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
if (inFile) {
keyExists = true;
}
return keyExists;
}
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
int main() {
if (keyExists()) {
string key;
string storedKey;
cout << "Please enter key: ";
getline(cin, key);
SHA256 sha256;
ifstream inFile("key.txt");
getline(inFile, storedKey);
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
}
else {
string key;
string confirmKey;
cout << "Please create a key: ";
getline(cin, key);
cout << "Confirm key: ";
getline(cin, confirmKey);
if (isMatch(key, confirmKey)) {
SHA256 sha256;
ofstream outFile("key.txt");
outFile << sha256(key);
}
else {
cout << "Keys do not match!n";
}
}
return 0;
}
Many thanks to Stephan Brumme for the awesome hashing algorithm code! This was very easy to implement.
c++ authentication
New contributor
$endgroup$
I have been reading about passwords and hashing algorithms and what not and decided to write a program.
Overview: The user should be prompted to create a password the first time the program is executed. They should enter a key and confirm it. If they have executed the program previously, then they should just enter the password to gain access.
I determine if the user has run the program by checking if key.txt exists. Is there a more preferred method?
I tried to streamline some code with the two bool functions. Any other suggestions for cleaner or more concise code?
#include <iostream>
#include <fstream>
#include <string>
#include "sha256.h"
using namespace std;
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
if (inFile) {
keyExists = true;
}
return keyExists;
}
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
int main() {
if (keyExists()) {
string key;
string storedKey;
cout << "Please enter key: ";
getline(cin, key);
SHA256 sha256;
ifstream inFile("key.txt");
getline(inFile, storedKey);
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
}
else {
string key;
string confirmKey;
cout << "Please create a key: ";
getline(cin, key);
cout << "Confirm key: ";
getline(cin, confirmKey);
if (isMatch(key, confirmKey)) {
SHA256 sha256;
ofstream outFile("key.txt");
outFile << sha256(key);
}
else {
cout << "Keys do not match!n";
}
}
return 0;
}
Many thanks to Stephan Brumme for the awesome hashing algorithm code! This was very easy to implement.
c++ authentication
c++ authentication
New contributor
New contributor
edited yesterday
200_success
130k17155419
130k17155419
New contributor
asked yesterday
okkv1747vmokkv1747vm
443
443
New contributor
New contributor
2
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
2
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago
2
2
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
3 Answers
3
active
oldest
votes
$begingroup$
Using namespace std
isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing withstd::
, you'll get used to it in no time.Your function
keyExists
can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. Sois_first_use
, oris_first_visit
as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:
Original version
bool keyExists() {
bool keyExists = false; // the homonymy is a bad idea
ifstream inFile("key.txt");
if (inFile) {
keyExists = true; //
}
return keyExists;
}
first trimming
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
keyExists = inFile; // because streams can be converted to bool as you know
return keyExists;
}
second trimming
bool keyExists() {
ifstream inFile("key.txt");
return inFile; // you specified the return type, so the conversion will occur
}
third trimming
bool keyExists() {
return ifstream("key.txt"); // no need for a named object
}
So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.
- Your function
isMatch
suffers from the same issue.
original version
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
suggested implementation
bool isMatch(const string& key, const string& confirmKey) { // pass it by reference to avoid a potentially costly copy
return key == confirmKey; // no need to store that in a `bool` before returning it
}
Then again I'm not sure it needs a function of its own...
- What's a valid key?
It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?
$endgroup$
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
1.
Do not use
using namespace std;
Instead you can use
using std::cout;
using std::getline();
using std::ifstream;
using std::ofstream;
using std::cin;
using std::string;
Here is a link to why we should avoid using namespace <name>;
type of statements
2.
In the function bool keyExists();
your bool variable is not necessary you can directly return the output of expression inside if condition. Same can be done in the other bool function, if you worry about readability then you may add a comment line after the return statement stating the intent behind the return value.
Also you can define both bool functions as inline.
New contributor
$endgroup$
1
$begingroup$
You missedstd::getline()
,std::ifstream
,std::ofstream
,std::cin
andstd::string
.
$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
add a comment |
$begingroup$
Another thing to keep in mind when doing security focused applications is reverse engineering.
Using that, a potential attacker can simply analyze your compiled program and then binary patch it to circumvent any security measures you have put in place.
Of course in your case this is rather trivial because the source code is available. However even without the original source it can be possible to do so for example by looking for certain tell-tale strings.
Running your program gives some great hints about program flow via the strings Access Denied!
and Access Granted!
respectively. If one were to analyze your program it would be easy to find references to above strings to pinpoint the location in your code that needs to be patched.
Ultimately your program comes down to this part:
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
Which when disassembled could look something like this:
Notice how you can see part of your if
statement, namely the condition test and then a jump (JNZ) as well as the message Access Denied!
. if you follow the jump you will get to this part:
Which just happens to be the "protected" part of your program. The attacker now only has to "patch" the jump to always jump to the right location of your program regardless of user input.
In order to protect against this you can read up on obfuscating programs and making them harder to "crack".
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
okkv1747vm is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216133%2fc-simple-password-protected-console-app%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Using namespace std
isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing withstd::
, you'll get used to it in no time.Your function
keyExists
can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. Sois_first_use
, oris_first_visit
as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:
Original version
bool keyExists() {
bool keyExists = false; // the homonymy is a bad idea
ifstream inFile("key.txt");
if (inFile) {
keyExists = true; //
}
return keyExists;
}
first trimming
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
keyExists = inFile; // because streams can be converted to bool as you know
return keyExists;
}
second trimming
bool keyExists() {
ifstream inFile("key.txt");
return inFile; // you specified the return type, so the conversion will occur
}
third trimming
bool keyExists() {
return ifstream("key.txt"); // no need for a named object
}
So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.
- Your function
isMatch
suffers from the same issue.
original version
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
suggested implementation
bool isMatch(const string& key, const string& confirmKey) { // pass it by reference to avoid a potentially costly copy
return key == confirmKey; // no need to store that in a `bool` before returning it
}
Then again I'm not sure it needs a function of its own...
- What's a valid key?
It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?
$endgroup$
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
Using namespace std
isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing withstd::
, you'll get used to it in no time.Your function
keyExists
can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. Sois_first_use
, oris_first_visit
as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:
Original version
bool keyExists() {
bool keyExists = false; // the homonymy is a bad idea
ifstream inFile("key.txt");
if (inFile) {
keyExists = true; //
}
return keyExists;
}
first trimming
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
keyExists = inFile; // because streams can be converted to bool as you know
return keyExists;
}
second trimming
bool keyExists() {
ifstream inFile("key.txt");
return inFile; // you specified the return type, so the conversion will occur
}
third trimming
bool keyExists() {
return ifstream("key.txt"); // no need for a named object
}
So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.
- Your function
isMatch
suffers from the same issue.
original version
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
suggested implementation
bool isMatch(const string& key, const string& confirmKey) { // pass it by reference to avoid a potentially costly copy
return key == confirmKey; // no need to store that in a `bool` before returning it
}
Then again I'm not sure it needs a function of its own...
- What's a valid key?
It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?
$endgroup$
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
Using namespace std
isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing withstd::
, you'll get used to it in no time.Your function
keyExists
can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. Sois_first_use
, oris_first_visit
as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:
Original version
bool keyExists() {
bool keyExists = false; // the homonymy is a bad idea
ifstream inFile("key.txt");
if (inFile) {
keyExists = true; //
}
return keyExists;
}
first trimming
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
keyExists = inFile; // because streams can be converted to bool as you know
return keyExists;
}
second trimming
bool keyExists() {
ifstream inFile("key.txt");
return inFile; // you specified the return type, so the conversion will occur
}
third trimming
bool keyExists() {
return ifstream("key.txt"); // no need for a named object
}
So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.
- Your function
isMatch
suffers from the same issue.
original version
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
suggested implementation
bool isMatch(const string& key, const string& confirmKey) { // pass it by reference to avoid a potentially costly copy
return key == confirmKey; // no need to store that in a `bool` before returning it
}
Then again I'm not sure it needs a function of its own...
- What's a valid key?
It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?
$endgroup$
Using namespace std
isn't a good practice in header files, where your program should at least partially reside, because you introduce potential name conflicts. So don't do that, and prefix the names you're importing withstd::
, you'll get used to it in no time.Your function
keyExists
can be improved upon. First, its name is not the best you could have found, because it suggests you're looking for the existence of a particular key, whereas what you really want to know if the program has been launched before. Sois_first_use
, oris_first_visit
as an analogy to a website, would tell more. Besides, it doesn't have to be that verbose:
Original version
bool keyExists() {
bool keyExists = false; // the homonymy is a bad idea
ifstream inFile("key.txt");
if (inFile) {
keyExists = true; //
}
return keyExists;
}
first trimming
bool keyExists() {
bool keyExists = false;
ifstream inFile("key.txt");
keyExists = inFile; // because streams can be converted to bool as you know
return keyExists;
}
second trimming
bool keyExists() {
ifstream inFile("key.txt");
return inFile; // you specified the return type, so the conversion will occur
}
third trimming
bool keyExists() {
return ifstream("key.txt"); // no need for a named object
}
So do you really need a function? It depends. If you want to let your program evolve from here, it's a good idea to keep the function, and implement a more viable test at a later point without disturbing the rest of your code. Otherwise it isn't worth the burden of finding a name for it.
- Your function
isMatch
suffers from the same issue.
original version
bool isMatch(string key, string confirmKey) {
bool match = false;
if (key == confirmKey) {
match = true;
}
return match;
}
suggested implementation
bool isMatch(const string& key, const string& confirmKey) { // pass it by reference to avoid a potentially costly copy
return key == confirmKey; // no need to store that in a `bool` before returning it
}
Then again I'm not sure it needs a function of its own...
- What's a valid key?
It might be a design choice, but it's very rare to allow for tabs, spaces and such inside a password. Is this really what you want? Is it compatible with every way to store passwords that you can think of? How would you constrain the choice of a password?
answered 14 hours ago
papagagapapagaga
4,652321
4,652321
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
I'd say it's very rare to prohibit tabs, spaces or any other characters within passwords; did you mistype something there?
$endgroup$
– Toby Speight
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@TobySpeight: not at all, just a honest mistake
$endgroup$
– papagaga
14 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
$begingroup$
@papagaga Thanks you for your input! However, I get the following error when when trying to implement you suggestions: "No suitable conversion function from std::ifstream to bool."
$endgroup$
– okkv1747vm
9 hours ago
add a comment |
$begingroup$
1.
Do not use
using namespace std;
Instead you can use
using std::cout;
using std::getline();
using std::ifstream;
using std::ofstream;
using std::cin;
using std::string;
Here is a link to why we should avoid using namespace <name>;
type of statements
2.
In the function bool keyExists();
your bool variable is not necessary you can directly return the output of expression inside if condition. Same can be done in the other bool function, if you worry about readability then you may add a comment line after the return statement stating the intent behind the return value.
Also you can define both bool functions as inline.
New contributor
$endgroup$
1
$begingroup$
You missedstd::getline()
,std::ifstream
,std::ofstream
,std::cin
andstd::string
.
$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
add a comment |
$begingroup$
1.
Do not use
using namespace std;
Instead you can use
using std::cout;
using std::getline();
using std::ifstream;
using std::ofstream;
using std::cin;
using std::string;
Here is a link to why we should avoid using namespace <name>;
type of statements
2.
In the function bool keyExists();
your bool variable is not necessary you can directly return the output of expression inside if condition. Same can be done in the other bool function, if you worry about readability then you may add a comment line after the return statement stating the intent behind the return value.
Also you can define both bool functions as inline.
New contributor
$endgroup$
1
$begingroup$
You missedstd::getline()
,std::ifstream
,std::ofstream
,std::cin
andstd::string
.
$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
add a comment |
$begingroup$
1.
Do not use
using namespace std;
Instead you can use
using std::cout;
using std::getline();
using std::ifstream;
using std::ofstream;
using std::cin;
using std::string;
Here is a link to why we should avoid using namespace <name>;
type of statements
2.
In the function bool keyExists();
your bool variable is not necessary you can directly return the output of expression inside if condition. Same can be done in the other bool function, if you worry about readability then you may add a comment line after the return statement stating the intent behind the return value.
Also you can define both bool functions as inline.
New contributor
$endgroup$
1.
Do not use
using namespace std;
Instead you can use
using std::cout;
using std::getline();
using std::ifstream;
using std::ofstream;
using std::cin;
using std::string;
Here is a link to why we should avoid using namespace <name>;
type of statements
2.
In the function bool keyExists();
your bool variable is not necessary you can directly return the output of expression inside if condition. Same can be done in the other bool function, if you worry about readability then you may add a comment line after the return statement stating the intent behind the return value.
Also you can define both bool functions as inline.
New contributor
edited 16 hours ago
New contributor
answered 21 hours ago
Mukul KumarMukul Kumar
1113
1113
New contributor
New contributor
1
$begingroup$
You missedstd::getline()
,std::ifstream
,std::ofstream
,std::cin
andstd::string
.
$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
add a comment |
1
$begingroup$
You missedstd::getline()
,std::ifstream
,std::ofstream
,std::cin
andstd::string
.
$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
1
1
$begingroup$
You missed
std::getline()
, std::ifstream
, std::ofstream
, std::cin
and std::string
.$endgroup$
– Toby Speight
17 hours ago
$begingroup$
You missed
std::getline()
, std::ifstream
, std::ofstream
, std::cin
and std::string
.$endgroup$
– Toby Speight
17 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
$begingroup$
@TobySpeight I am sorry for that, I will edit my answer. I tried to answer using my phone and so there were some restrictions with format and the amount of content I could put in.
$endgroup$
– Mukul Kumar
16 hours ago
add a comment |
$begingroup$
Another thing to keep in mind when doing security focused applications is reverse engineering.
Using that, a potential attacker can simply analyze your compiled program and then binary patch it to circumvent any security measures you have put in place.
Of course in your case this is rather trivial because the source code is available. However even without the original source it can be possible to do so for example by looking for certain tell-tale strings.
Running your program gives some great hints about program flow via the strings Access Denied!
and Access Granted!
respectively. If one were to analyze your program it would be easy to find references to above strings to pinpoint the location in your code that needs to be patched.
Ultimately your program comes down to this part:
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
Which when disassembled could look something like this:
Notice how you can see part of your if
statement, namely the condition test and then a jump (JNZ) as well as the message Access Denied!
. if you follow the jump you will get to this part:
Which just happens to be the "protected" part of your program. The attacker now only has to "patch" the jump to always jump to the right location of your program regardless of user input.
In order to protect against this you can read up on obfuscating programs and making them harder to "crack".
$endgroup$
add a comment |
$begingroup$
Another thing to keep in mind when doing security focused applications is reverse engineering.
Using that, a potential attacker can simply analyze your compiled program and then binary patch it to circumvent any security measures you have put in place.
Of course in your case this is rather trivial because the source code is available. However even without the original source it can be possible to do so for example by looking for certain tell-tale strings.
Running your program gives some great hints about program flow via the strings Access Denied!
and Access Granted!
respectively. If one were to analyze your program it would be easy to find references to above strings to pinpoint the location in your code that needs to be patched.
Ultimately your program comes down to this part:
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
Which when disassembled could look something like this:
Notice how you can see part of your if
statement, namely the condition test and then a jump (JNZ) as well as the message Access Denied!
. if you follow the jump you will get to this part:
Which just happens to be the "protected" part of your program. The attacker now only has to "patch" the jump to always jump to the right location of your program regardless of user input.
In order to protect against this you can read up on obfuscating programs and making them harder to "crack".
$endgroup$
add a comment |
$begingroup$
Another thing to keep in mind when doing security focused applications is reverse engineering.
Using that, a potential attacker can simply analyze your compiled program and then binary patch it to circumvent any security measures you have put in place.
Of course in your case this is rather trivial because the source code is available. However even without the original source it can be possible to do so for example by looking for certain tell-tale strings.
Running your program gives some great hints about program flow via the strings Access Denied!
and Access Granted!
respectively. If one were to analyze your program it would be easy to find references to above strings to pinpoint the location in your code that needs to be patched.
Ultimately your program comes down to this part:
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
Which when disassembled could look something like this:
Notice how you can see part of your if
statement, namely the condition test and then a jump (JNZ) as well as the message Access Denied!
. if you follow the jump you will get to this part:
Which just happens to be the "protected" part of your program. The attacker now only has to "patch" the jump to always jump to the right location of your program regardless of user input.
In order to protect against this you can read up on obfuscating programs and making them harder to "crack".
$endgroup$
Another thing to keep in mind when doing security focused applications is reverse engineering.
Using that, a potential attacker can simply analyze your compiled program and then binary patch it to circumvent any security measures you have put in place.
Of course in your case this is rather trivial because the source code is available. However even without the original source it can be possible to do so for example by looking for certain tell-tale strings.
Running your program gives some great hints about program flow via the strings Access Denied!
and Access Granted!
respectively. If one were to analyze your program it would be easy to find references to above strings to pinpoint the location in your code that needs to be patched.
Ultimately your program comes down to this part:
if (isMatch(sha256(key), storedKey)) {
cout << "Acces Granted!n";
}
else {
cout << "Access Denied!n";
}
Which when disassembled could look something like this:
Notice how you can see part of your if
statement, namely the condition test and then a jump (JNZ) as well as the message Access Denied!
. if you follow the jump you will get to this part:
Which just happens to be the "protected" part of your program. The attacker now only has to "patch" the jump to always jump to the right location of your program regardless of user input.
In order to protect against this you can read up on obfuscating programs and making them harder to "crack".
answered 6 hours ago
yuriyuri
3,66921034
3,66921034
add a comment |
add a comment |
okkv1747vm is a new contributor. Be nice, and check out our Code of Conduct.
okkv1747vm is a new contributor. Be nice, and check out our Code of Conduct.
okkv1747vm is a new contributor. Be nice, and check out our Code of Conduct.
okkv1747vm is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216133%2fc-simple-password-protected-console-app%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
$begingroup$
I realize that this is just a test program to play with cryptography, hashing, and security. As a further exercise, could you think of ways this can be hacked and their mitigation?
$endgroup$
– TomG
20 hours ago
$begingroup$
Well, I guess it could be brute forced. To mitigate that I should set a max number of attempts before lockout. There is also a possibility of a collision. However, from my understanding sha256 is fairly robust in this regard. Salting the hash could mitigate many factors.
$endgroup$
– okkv1747vm
11 hours ago
$begingroup$
how about if I swap out the key.txt with I file of my own?
$endgroup$
– TomG
9 hours ago
$begingroup$
@TomG Wow. Good point. I wouldn't know what to do in that scenario..
$endgroup$
– okkv1747vm
9 hours ago