아이디와 비밀번호 규칙에 대하여

mylime·2024년 8월 1일
1
post-thumbnail



이 포스팅은 2024.08.02에 작성되었습니다.

  • 2024.08.03 아이디 제약조건 조사 추가



서론

이번 프로젝트에서 로그인을 구현하면서 했던 고민을 적어보려고 한다.
이전 프로젝트부터 spring security, jwt를 사용한 로그인을 2~3번정도 구현해봤기 때문에 빠른 개발을 위해 deprecated된 것을 조금 고치는 것 외에는 거의 똑같은 코드를 사용하였다. 그 당시 아이디 생성 규칙과 비밀번호 생성 규칙을 나름 생각하여 구현해놓았는데, 몇 달이 지난 후 재활용하니 해당 규칙을 까먹고있었다. 해당 규칙은 API통신 과정에서 프론트분이 발견을 해주셨다.


내가 구현해놓은 코드를 보니 아이디생성규칙이 다음과 같이 되어 있었다.

private static final String ID_PATTERN = "^[a-zA-Z][a-zA-Z0-9_]{1,20}$";

...

if (username == null || username.length() == 0) {
    throw new IllegalArgumentException("username은 빈칸 불가능");
}

if (!username.matches(ID_PATTERN)) {
    throw new IllegalArgumentException("유효하지 않은 username");
}

if (loginCredentialRepository.findByUsername(username).isPresent()) {
    throw new IllegalArgumentException("중복되는 닉네임");
}

✅null불가능, 중복 불가능
✅숫자로 시작 불가능, 영어 대소문자 가능, 1에서 20자리까지 가능


저 때 왜 저런식으로 구현했는지 기억이 나지 않았다. (숫자로 시작 불가능같은 경우에는 자바 변수명 생성하던 습관이 그대로 담긴 것 같았다) 하지만 최근에 네이버 아이디가 모두 숫자로 되어있는 분 을 봤고, 교육기관 컨설턴트님께서 아이디(이메일)의 경우 대소문자 구분이 없다 고 말씀해주신 게 기억이 났다. (네이버 아이디가 모두 숫자인 건 조금 충격이긴 했다)


그래서 일반적인 서비스들의 아이디 생성 규칙을 확인하고, 어떤 게 좋은 방식인지 찾아보고자 하였다.



예시1 네이버

아직도 숫자로만 구성된 아이디의 충격이 잊혀지지 않는다. 그래서 네이버부터 찾아봤다.


아이디 규칙

✅ 5~20자의 영문 소문자, 숫자, 특수기호( _ ), ( - ) 만 가능
✅ 어떤 기준에 맞지 않으면 "사용할 수 없는 아이디"라는 문구가 나옴


"사용할 수 없는 아이디"라고 나올 때는 중복 아이디라서 안되는건지, 애초에 안되는 아이디 형식인지 알 수 없었다. 그래서 몇 가지 케이스를 시도해보니 다음과 같은 사실은 알 수 있었다.

✅ 숫자"만" 불가능 (3456346 불가능)
✅ 숫자 8개 이상 불가능 (a2354433은 되고, a23541333나 a2354133asdfa3은 안됨)
✅ 영어 한글자만 불가능 (eeeee ~ eeeeeeeeeeeeeeeeeeee 안됨)
✅ ( - )나 ( _ )로 시작 불가능

생각보다 꽤 복잡한 로직이 있어서 어쩔 수 없이 "사용할 수 없는 아이디"라고 통일한 듯하다.
그리고 이제는 숫자만 아이디로 사용할 수 없게 된 것 같다.


비밀번호 규칙

✅ 8~16자의 영문 대/소문자, 숫자, 특수문자 사용



예시2 구글


아이디 규칙

✅ 사용자 이름은 6자에서 30자(영문기준)
✅ 글자(a-z), 숫자(0-9), 마침표(.)가능
✅ 첫 글자는 ASCII 문자(a-z) 또는 숫자만 가능
✅ 마지막 문자 . 불가능
✅ 영어단어 한 글자만 가능

처음에는 아이디 생성에 어떤 규칙이 있는지 알려주지 않지만, 계속 이상한걸(?) 치다보면 하나씩 친절하게 알려주긴 한다. 그리고 구글은 해당 아이디가 이미 사용중이라는 표시도 해준다.


비밀번호 규칙

8자 이상이면 거의 뭐든 되는 것 같다. =========도 되고, ---------도 된다.
대신 aaaaaaaa111111111과 같은 비밀번호를 치면 더 안전한 비밀번호를 입력하라고 나온다.



예시3 깃허브


아이디 규칙

이메일을 쳐야하기 때문에 아이디 제약은 네이버, 구글 등 이메일 서비스 메일이름에 종속된다.


비밀번호 규칙

✅ 숫자와 소문자를 포함하여 15자 이상, 또는 8자 이상이여야한다.
✅ 흔하거나 단순한 비밀번호 안됨

  • 네이버, 구글과 같이 뭐라도 쳐야 비밀번호 제약조건이 보여진다.
  • 특이한 점은, 조금 흔하거나 단순한 비밀번호로 설정해줄 시 다른 웹사이트에서 일반적으로 사용되는 비밀번호 목록에 존재한다고 나온다.



예시4 인프런

아이디는 이메일이라 생략한다.

비밀번호 생성규칙

✅ 영문/숫자/특수문자 중, 2가지 이상 포함
✅ 8자 이상 32자 이하 입력 (공백 제외)
✅ 연속 3자 이상 동일한 문자/숫자 제외

비밀번호를 치기 전 생성규칙을 보여준 첫 예시다!! 보자마자 친절해서 굉장히 감동받았다.

어떤 제약이 부족한지 하나하나 알려준다.



요약

✅ 대부분은 아이디 생성 규칙을 첫 화면에 보여주지 않음
✅ 아이디는 대부분 대문자가 불가능하고, 소문자만 가능 + 지정된 특수문자 사용가능

  • ( . )(구글)이나 ( - ), ( _ )(네이버, 네이트) 등 지정된 특수문자만 사용가능

✅ 비밀번호의 경우 대소문자 모두 사용가능

  • 특수문자에 제약은 딱히 보이지 않았다
  • (좀 엄격한 규칙이 있을 줄 알았는데, 생각보다 그런 건 없었다)

✅ 아이디, 비밀번호 모두 길이 제한 존재(6자나 8자 이상, 16자나 30자, 32자 이하)



아이디에 대문자를 사용하지 않는 이유?

그렇다면 아이디에 대문자를 사용하지 않는 이유는 뭘까?

이 사이트의 댓글을 보면 네이버와 같은 이메일들은 초기에 대소문자 구분이 있었다고 한다. 현재는 소문자만 가능하도록 바뀌었으니 뭔가 큰 이유가 있지 않을까 하는 생각이 들었다. 하지만 구글링을 해봤을 때 확실하고 명확한 이유를 찾을 수 없었다.. 그나마 나오는 키워드는 사용자 편의성, 데이터베이스 저장 시 ci 사용 등이 있었다.


내 생각에는 이메일의 경우 비즈니스와 연관이 깊고, 명확한 사용자를 지정해서 보낼 필요가 있으니 확실하게 구분할 수 있도록 소문자만 사용하게 된 것 같다. 예를 들어 i, I, l, L와 같은 글자는 글자체에 따라 구분이 어려운 경우도 많으니 말이다. (실제로 알아보기 힘들게 IlliIlil 이런 닉네임을 사용하는 경우도 어렵지 않게 볼 수 있다)


+) RFC에서 지정한 이메일 생성규칙도 존재한다. 권장되는 이메일 형식을 정규표현식으로 표현하면 아래와 같다. 더 자세히 알고싶다면 여기를 참고하자!

([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])



🤔이전에 패스워드 생성 조건이 까다로웠던 것 같은데?

예전에 패스워드를 생성할 때 대문자 포함, 특수문자 필수 포함 등 까다로운 조건이 있었던 기억이 난다. 하지만 지금 찾아본 서비스들 중에는 이런 엄격한 규칙이 보이지 않았다. 그래서 조금 더 찾아봤더니 다음과 같은 재밌는 글을 찾을 수 있었다.

https://item4.blog/2023-09-20/password-the-right-way/

불편한 비밀번호 규칙은 효용성이 없다!


비밀번호 규칙은 실제로 복잡했었다. 2006년 미국 국립표준기술연구소(NIST)는 타인에 의해 비밀번호가 추측되지 않게 하기 위해 알파벳 소문자/대문자, 알파벳이 아닌 문자를 모두 조합하여 사용하는 규칙을 요구하였다. 이 규칙은 전세계 웹사이트 비밀번호 입력의 기준으로 자리잡게 되었다고 한다.

특수문자도 모든 특수문자를 넣을 수 있는 게 아니고, sql 공격을 방지할 수 있는 문자만 허용이 되었기 때문에 비밀번호 규칙은 점점 더 복잡해졌다.


“In the end, it was probably too complicated for a lot of folks to understand very well, and the truth is, it was barking up the wrong tree,” he is quoted as saying. “It just drives people bananas and they don’t pick good passwords no matter what you do.

“Much of what I did I now regret.”

하지만 이후 2017년, 당시 NIST에 재직하면서 논문 작성에도 참여한 Bill Burr는 WSJ와의 인터뷰에서 ‘논문에서 말하는 복잡한 비밀번호 조합 규칙은 에러였고 후회하고 있다’는 발언을 하여 화제가 되었다. Bill Burr 뿐만 아니라 NIST에서도 해당 논문의 개정판을 내면서 해당 주장을 철회했고, 이제 더 이상 그런 규칙을 추천하지 않는다고 적시해두었다고 한다.


(실제 논문 개정판 내용)


갑자기 이렇게 철회한 이유는, 사용자들이 의도와는 다르게 비밀번호를 생성해서 사용했기 때문이었다!

비밀번호에 사용되는 문자의 개수를 늘리면 무차별 대입 공격을 더 잘 막을 수 있다고 생각했지만, 사용자들은 의도와는 다르게 자신들이 항상 사용하는 비밀번호 패턴 뒤에 대문자와 특수문자를 하나씩 붙여서 사용했다. 예를 들어 비밀번호 abc1234를 쓰던 사람은 뒤에 대문자와 특수문자를 하나씩만 붙인 abc1234A!를 사용할 가능성이 높았다. 이런 움직임을 알았던 공격자들은 예상보다 훨씬 쉽게 비밀번호를 뚫을 수 있었다.


결국 여러 문자를 조합해서 비밀번호를 만들어야하는 사용자의 불편만 키우고 실질적인 소득은 없게 되어버렸다고 한다.



🤔그러면 어떤 비밀번호 생성규칙이 좋을까?

  1. 비밀번호 하한 늘리기

    • 비밀번호의 최소 길이를 늘림으로써, 무작위 대입 자체를 힘들게 만들기
  2. 비밀번호 길이의 상한을 두지 않기

  3. 사용할 수 있는 특수문자에 제약을 두지 않기

    • SQL Injection 대비는 필수



마치며..

굉장히 간단한 의문에서 시작된 자료조사였는데, 꽤 재미있었다! 쉽게 지나칠 수 있는 것들도 자세히보면 생각할 게 좀 있는 것 같다.

자료조사를 통해 얻은 결과를 바탕으로 이번 프로젝트에서 아이디와 비밀번호 생성규칙을 다음과 같이 만들어보려고 한다.

아이디 규칙

✅ 5~20자의 영문 소문자, 숫자, 특수기호( _ ), ( - ) 2개만 가능
✅ 첫 시작 문자, 마지막 문자는 특수기호 불가능

비밀번호 규칙

✅ 대소문자 구분 x
✅ 특수기호 제한 없음
✅ 8글자 이상



참고자료

https://item4.blog/2023-09-20/password-the-right-way/
https://www.silicon.co.uk/security/authentification/password-expert-regrets-advice-219579

profile
깊게 탐구하는 것을 좋아하는 백엔드 개발자 지망생 lime입니다! 게시글에 틀린 정보가 있다면 지적해주세요. 감사합니다. 이전블로그 주소: https://fladi.tistory.com/

1개의 댓글

comment-user-thumbnail
2024년 8월 9일

결국 비밀번호 안전의 중요성은 복잡한 문자열보다 이전에 털렸던것과 아예 다른 비밀번호를 쓰는것에 있었던 거네요.. 좋은 글 알아갑니다!

답글 달기