Secure Password Input in C++

How do I handle password input where characters should not be displayed?

Handling password input securely, where characters are not displayed as they're typed, is an important feature for many applications.

In C++, this isn't as straightforward as in some other languages, but we can achieve it using platform-specific functions. Let's explore how to do this on both Windows and Unix-like systems (Linux, macOS).

Windows Implementation

For Windows, we'll use the _getch() function from <conio.h>:

#include <iostream>
#include <string>
#include <conio.h>  // Windows-specific header

std::string getPassword(){
  std::string password;
  char ch;

  // Read until Enter is pressed
  while ((ch = _getch()) != '\r') {
    // Handle backspace
    if (ch == '\b') {
      if (!password.empty()) {
        std::cout << "\b \b";
        password.pop_back();
      }
    } else {
      password += ch;
      std::cout << '*';
    }
  }
  std::cout << '\n';
  return password;
}

int main(){
  std::cout << "Enter password: ";
  std::string password = getPassword();
  std::cout << "Password entered: " << password;
}

This Windows implementation uses _getch() to read characters without echoing them to the console. We print an asterisk for each character entered to provide visual feedback.

Enter password: ******
Password entered: secret

Unix-like Systems Implementation

For Unix-like systems, we'll use the termios.h header to modify terminal attributes:

#include <iostream>
#include <string>
#include <termios.h>
#include <unistd.h>

std::string getPassword(){
  std::string password;
  termios oldt;
  tcgetattr(STDIN_FILENO, &oldt);
  termios newt = oldt;
  newt.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);

  char ch;
  while ((ch = getchar()) != '\n') {
    if (ch == 127) {
      // Handle backspace
      if (!password.empty()) {
        std::cout << "\b \b";
        password.pop_back();
      }
    } else {
      password += ch;
      std::cout << '*';
    }
  }
  std::cout << '\n';

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  return password;
}

int main(){
  std::cout << "Enter password: ";
  std::string password = getPassword();
  std::cout << "Password entered: " << password;
}
Enter password: ******
Password entered: secret

In this Unix-like system implementation, we temporarily disable echo in the terminal, read characters one by one, and restore the original terminal settings afterwards.

Cross-platform Solution

To create a cross-platform solution, you can use conditional compilation:

#include <iostream>
#include <string>

#ifdef _WIN32
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
#endif

std::string getPassword(){
  std::string password;

#ifdef _WIN32
  // Windows implementation
  char ch;
  while ((ch = _getch()) != '\r') {
    if (ch == '\b') {
      if (!password.empty()) {
        std::cout << "\b \b";
        password.pop_back();
      }
    } else {
      password += ch;
      std::cout << '*';
    }
  }
#else
  // Unix-like implementation
  termios oldt;
  tcgetattr(STDIN_FILENO, &oldt);
  termios newt = oldt;
  newt.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);

  char ch;
  while ((ch = getchar()) != '\n') {
    if (ch == 127) {
      if (!password.empty()) {
        std::cout << "\b \b";
        password.pop_back();
      }
    } else {
      password += ch;
      std::cout << '*';
    }
  }

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#endif

  std::cout << '\n';
  return password;
}

int main(){
  std::cout << "Enter password: ";
  std::string password = getPassword();
  std::cout << "Password entered: " << password;
}
Enter password: ******
Password entered: secret

This cross-platform solution uses conditional compilation to choose the appropriate implementation based on the target platform.

Remember, while these methods hide password input from the screen, they don't provide complete security. For production systems, consider using secure password hashing algorithms and avoid storing plaintext passwords.

User Input in the Terminal

This lesson introduces the fundamentals of capturing user input, using std::cin and std::getline()

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Changing Console Input Color in C++
Can I change the color or formatting of the input prompt in the console?
Formatting Console Output in C++
How can I format console output to create more visually appealing displays?
Handling Arrow Key Input in C++
Is it possible to get arrow key input in C++ for navigation purposes?
Validating User Input in C++
How can I validate user input to ensure it's the correct data type?
Multiple Inputs on a Single Line in C++
Is it possible to input multiple values in a single line using std::cin?
Handling Spaces in User Input
How do I handle spaces in user input when using std::cin?
std::cin vs std::getline() in C++
What's the difference between using std::cin >> and std::getline()?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant