Programming/C

getpass() 함수

moxie2ks 2025. 4. 20. 18:01
728x90
반응형

개요

getpass() 함수는 UNIX/Linux 운영체제에서 제공하는 시스템 함수로, 사용자로부터 비밀번호를 안전하게 입력받는 데 사용된다. 이 함수의 주요 특징은 사용자가 비밀번호를 입력할 때 화면에 입력 내용이 표시되지 않아 보안성을 높인다는 점이다. 터미널 환경에서 비밀번호나 민감한 정보를 입력받을 때 유용하게 활용될 수 있으며, C 프로그래밍에서 사용자 인증 기능을 구현할 때 자주 사용된다.

설명

getpass() 함수는 unistd.h 헤더 파일에 선언되어 있으며, 사용자에게 비밀번호 입력을 요청하고 그 결과를 문자열 포인터로 반환한다. 함수의 원형은 다음과 같다:

char *getpass(const char *prompt);

매개변수 prompt는 사용자에게 표시할 메시지로, 일반적으로 "Enter password:" 같은 문자열이 사용된다. 함수는 사용자가 입력한 비밀번호를 가리키는 문자열 포인터를 반환하며, 입력 오류가 발생할 경우 NULL을 반환한다.

이 함수는 터미널의 에코 기능(입력한 문자를 화면에 표시하는 기능)을 일시적으로 비활성화하여 입력하는 문자가 화면에 표시되지 않도록 한다. 사용자가 엔터 키를 누르면 입력이 완료되고, 터미널은 다시 정상 모드로 돌아간다.

주의할 점은 getpass() 함수가 POSIX 표준에서는 더 이상 권장되지 않는(deprecated) 함수이며, 일부 현대 시스템에서는 사용할 수 없을 수도 있다는 것이다. 또한 Windows 시스템에서는 기본적으로 제공되지 않는다.

특징

  1. 보안성 강화: 입력 시 화면에 문자가 표시되지 않아 타인에게 비밀번호가 노출되는 것을 방지한다.
  2. 플랫폼 제한: 주로 UNIX/Linux 계열 운영체제에서 사용 가능하며, Windows에서는 기본적으로 제공되지 않는다.
  3. 정적 버퍼 사용: 대부분의 구현에서 정적 버퍼를 사용하므로 동시에 여러 번 호출하면 이전 결과가 덮어써질 수 있다.
  4. 최대 길이 제한: 일반적으로 비밀번호 입력에 최대 길이 제한이 있으며, 이를 초과하는 입력은 잘리게 된다.
  5. 메모리 관리 필요: 비밀번호 처리 후에는 보안을 위해 메모리를 명시적으로 지우고 해제하는 것이 중요하다.
  6. 표준 입출력 사용: 함수는 표준 입출력 스트림을 사용하므로, 리다이렉션된 입력에서는 제대로 작동하지 않을 수 있다.
  7. 더 이상 권장되지 않음: POSIX 표준에서는 getpass() 함수가 더 이상 권장되지 않으며, 대신 readpassphrase() 또는 기타 대체 함수 사용을 권장한다.

예시

다음은 getpass() 함수를 사용하여 비밀번호를 입력받고 처리하는 간단한 예제이다:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAX_PASSWORD_LENGTH 20

int main()
{
    char* password = getpass("Enter your password: ");
    
    // 비밀번호가 NULL인 경우
    if (password == NULL)
    {
        printf("Password input error\n");
        return 1;
    }
    
    // 비밀번호 길이 확인
    if (strlen(password) > MAX_PASSWORD_LENGTH)
    {
        printf("Password can be up to %d characters long\n", MAX_PASSWORD_LENGTH);
        return 1;
    }
    
    // 비밀번호 사용 예시 (실제로는 보안상 출력하지 않는 것이 좋음)
    printf("Entered password: %s\n", password);
    
    // 메모리 청소 및 해제
    memset(password, 0, strlen(password));
    free(password);
    
    return 0;
}

이 코드의 주요 단계는 다음과 같다:

  1. getpass() 함수를 호출하여 사용자로부터 비밀번호를 입력받는다.
  2. 반환된 비밀번호가 NULL인지 확인하여 입력 오류를 처리한다.
  3. 비밀번호 길이가 설정한 최대 길이를 초과하는지 확인한다.
  4. 입력된 비밀번호를 사용한다 (예시에서는 단순히 출력).
  5. 보안을 위해 비밀번호가 저장된 메모리를 0으로 초기화한 후 메모리를 해제한다.

여기서 중요한 점은 비밀번호를 사용한 후에 memset() 함수를 통해 메모리 내용을 지우는 것이다. 이는 메모리 덤프나 스와핑으로 인해 비밀번호가 유출되는 것을 방지하기 위함이다.

결론

getpass() 함수는 UNIX/Linux 환경에서 사용자로부터 비밀번호를 안전하게 입력받기 위한 간단하고 효과적인 방법을 제공한다. 화면에 입력 내용을 표시하지 않음으로써 기본적인 보안을 제공하며, 사용하기 쉬운 인터페이스를 가지고 있다.

그러나 이 함수는 몇 가지 제한사항을 가지고 있다. 플랫폼 의존적이며, 더 이상 POSIX 표준에서 권장되지 않는다. 또한 정적 버퍼를 사용하므로 동시 호출 시 문제가 발생할 수 있으며, 메모리 관리에 주의해야 한다.

현대적인 애플리케이션에서는 getpass() 대신 readpassphrase(), OpenSSL의 EVP_read_pw_string() 또는 libsodium 같은 보안 라이브러리에서 제공하는 함수를 사용하는 것이 권장된다. 이러한 대안 함수들은 더 나은 보안 기능과 플랫폼 독립성을 제공한다.

비밀번호를 처리할 때는 항상 메모리 보안에 신경 써야 하며, 사용 후 메모리를 지우고, 평문 비밀번호가 디스크에 저장되거나 네트워크를 통해 전송되지 않도록 주의해야 한다.

참고문헌

  1. Linux Programmer's Manual - getpass(3): https://man7.org/linux/man-pages/man3/getpass.3.html
  2. The Open Group Base Specifications - getpass(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpass.html
  3. GNU C Library Manual - Terminal Input: https://www.gnu.org/software/libc/manual/html_node/Terminal-Input.html

 

728x90
반응형