로그인할때 패스워드를 평문(PlainText)으로 서버에 보낼시 보안상 문제가 되지 않을까? 라는 질문에서 부터 시작되었다.

POST... HTTPS...를 생각하더라도 패스워드를 평문으로 다루면 안될것 같다는 막연한 상상(망상인가)... 검증도 안해보고;;

 

0. 기존에 구현한 로그인 순서

1. 클라이언트로 아이디와 비밀번호를 평문형태로 서버에 보낸다. 

2. 아이디를 기준으로 DB에서 패스워드(Bcrypt암호화)를 가져온다.

3. 가져온 DB패스워드를 클라이언트에서 받은 평문비밀번호와 아래와 같이 비교한다. ( PHP )

    if ( password_verify("클라이언트에서 받은 패스워드", "DB에서 가져온 패스워드") ) {
        echo '패스워드 일치';
    } else {
         echo '패스워드 불일치';
    }

 

4. 패스워드가 일치하면 DB에서 나머지 정보를 가져온다.


1. 클라이언트에서 API 요청시 평문으로 보내고 있는 점

 

암호화된 패스워드를 PHP로 보내고 PHP에서 복호화한 패스워드를 앞서 말한 password_verify함수로 비교하면 해결할 수 있지 않을까?

 

1-1.  Bcrypt 방식으로 데이터 베이스에 저장되어 있는 유저의 패스워드 데이터

 

sha-256과 같은 암호화 알고리즘으로 구현할때는 서버에 저장된 해시값과 단순 비교만 하면 문제없이 구현할 수 있었다.

그러나 DB에 저장된 패스워드값이 Bcrypt로 저장되어 있기 때문에 단순 비교가 안되었다. 그래서 password_verify 함수로 비교한 것이다.

"Bcrypt는 패스워드를 해싱할 때 내부적으로 랜덤한 솔트를 생성하기 때문에 같은 문자열에 대해서 다른 인코드된 결과를 반환한다"
https://pjh3749.tistory.com/258 [JayTech의 기술 블로그]

 

2. 그럼 암호화와 복호화가 가능한 알고리즘은 어떤것이 있을까?

 

주변에 이문제에 대해 도움을 요청했고, RSA알고리즘을 사용해 보는건 어떻겠냐는 의견을 받았다.

RSA에 대해 공부한적이 없어 RSA를 구글링하기 시작했다.

 

그렇게 습득한 얕은 지식으로 개인키와 공개키를 생성할 수 있었다.

 

...

 

( 아직 이해가 부족해서 더 공부해야 된다 )

 

3. 앞으로 해야할 TODO

이제 적용하는 일이 남았다.

1. 클라이언트는 공개키를 통해 평문으로된 패스워드를 암호화한다.

 

2. 암호화된 패스워드를 서버(PHP)로 보낸다.

 

3. PHP에서 가지고 있는 개인키로 암호화된 패스워드를 복호화한다.

 

4. 이제 복호화된 패스워드를 password_verify 함수를 통해 검증하면 된다.

 

5. 검증이 완료되면 나머지 유저의 정보를 반환 한다.

 

 

 

4. 마무리

여기 까지가 내가 생각한 패스워드를 안전하게 전달해서 로그인하는 방법이다.

내가 생각한 방법이 문제가 되거나, 현업에서 쓰이는 보편화된 래퍼런스가 있는지 찾아봐야 겠다. 

 

이 포스팅을 보는 분들중 아시는분이 있다면 댓글을 달아 주시면 참 고마울 것 같다 ^^.

 

 

 

 

 

 

참고

www.crocus.co.kr/1203

 

RSA 암호 알고리즘

이 게시물의 내용은 https://www.youtube.com/watch?v=kGUlfVpIfaQ 위의 링크를 기반으로 제작하였습니다. 문제가 된다면 삭제조치 하겠습니다. 1. RSA 암호 알고리즘이란? Rivet, Shamir, Adelman 세사람의 첫이..

www.crocus.co.kr

https://pjh3749.tistory.com/258

 

[Spring] Bcrypt를 이용하여 비밀번호를 암호화하여 저장하는 방법 - 실제 프로젝트 적용기

암호화를 이용하여 원문을 해시화하는 간단한 방법을 찾던 중 Devglan 사이트에서 괜찮은 칼럼을 찾았다. https://www.devglan.com/spring-mvc/storing-hashed-password-database-java 다음 내용은 위 칼럼을 번역..

pjh3749.tistory.com

 

 

 

 


 

본문

카카오톡 PC버전의 로그인창을 보면

비밀번호를 4자리 이상 입력해야 로그인 버튼이 활성화 됩니다.


예제

저도 한번 따라 만들어 봤습니다 ^^;

 

초기 로그인 화면
아이디를 작성할때 키보드가 Activity View를 가리지 않게
일정 길이 미만의 패스워드 로그인버튼 비활성화
일정 길이 이상 패스워드 입력시 활성화


소스코드

EditText의 입력 텍스트가 일정길이 이상일 때 버튼을 활성화 하는 코틀린 소스입니다.

et_password.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(p0: Editable?) {
           		//텍스트를 입력 후

            }
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
				//텍스트 입력 전
            }
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                //텍스트 입력 중
                if(et_password.length() < 4) { // 패스워드의 길이가 4미만이면
                    btn_login.isCheckable = false // 버튼 클릭할수 없게
                    btn_login.isEnabled = false // 버튼 비활성화
                } else {
                    btn_login.isCheckable = true // 버튼 클릭할수 있게
                    btn_login.isEnabled = true // 버튼 활성화
                }
            }
        })

 

 

본 포스팅은 개인적 필요에 의해 기재되었습니다.


원노트에서 서식 복사하여 그대로 기재되었으므로

보시기에 불편할 수 있습니다.

필요하신 부분이 있다면 발췌하여 자유롭게 쓰시면 됩니다.


참고 출처와 댓글은 달아주세요~





생각해야 할 부분


카카오톡 친구 목록은 283명이다.

 

보통의 경우 200명을 넘기며 사업을 하는 사람의 경우 1000명도 넘길것이다.

 

친구목록이 10만명이라고 상상해보자.

이렇게 되면 한번에 많은 데이터를 서버로 요청해야 한다.

 

유저가 어플리케이션을 사용하는 흐름 , User Flow( 이하 플로우 ) 생각해 보자.

 

  1. 어플리케이션을 설치한다.
  2. 이전에 가입하였던 아이디가 있는가?
    1. 있다. 이전사용자
      1. 만약 어플리케이션이 기존에 설치되어 있고 데이터가 존재한다면
         SharedPreFerence ( 이하 SPF )에서 친구 목록 데이터를 불러온다.
      2. 클라이언트는 이전에 친구 추가했던 db ( server ) 요청( Request )한다.
        1. 해당 아이디(userID) USER 테이블에서 검색하자( SELECT ).
        2. userID 검색되면, Friends 테이블에서 해당 userID friendsID SELECT 하자.
        3. 이렇게 나온 friendsID 클라이언트로 전달( Response )한다.
    1. 없다. 처음사용자
      1. USER테이블에 userID 추가( INSERT) 된다.
      2. regDate ( 등록일 ) 칼럼에 년월시분초 ( ms 이하 단위 생략 ) 입력된다.
        ( MySQL date 기능을 사용 or PHP에서 UTC시간을 이용 등등.. )

+@ regLocation( 등록 지역) 입력하자. 클라이언트의 Network 정보 ( IP ) 기준으로.

  1. 서버에서 Response friendsID ArrayList 담는다.
  2. 이후 친구추가가 이루어 질때
    1. ( 어플 메모리상에서 ) ArrayList 추가한다.
    2. 서버 DB 등록 한다.
    3. SPF에도 추가 등록 한다. ( 생명주기를 신경써서 작업한다. )

 

 

플로우를 정리하면

 

1. 신규 유저일 경우 -> 회원가입 -> 아이디를 DB 추가한다

-> 친구 추가를 하면 DB friends테이블에 userId, friendId 칼럼에 각각 등록한다.

userId

friendId

userA

userB

userA

userC

userB

userA

userB

userC

userC

userA

userC

userB

"userA" 친구 목록 => userB, userC

"userB" 친구목록 => userA, userC

"userC" 친구목록 => userA, userB

 2. 기존 유저일 경우

-> 로그인한 유저 아이디를 기준으로한 key값으로 SPF에서 친구목록을 가져온다.

-> SPF 데이터가 존재하지 않을경우 ( 어플리케이션 재설치등 )

Server DataBase ( RDBMS. ex: MySQL )에서 데이터를 가져온다.

-> 가져온 데이터는 SPF 저장하고 어플리케이션이 완전히 종료되고 다시 시작될 우선적으로 SPF에서 불러오도록 한다. ( ,     우선순위를 로컬로 후순위를 서버로 )


SearchView 밑줄 ( queryBackground ) 없애는법




<Layout.XML>

android:queryBackground="@null" <--- 추가



적용 전


적용 후



추가 내용입니다.

 

앱 상단 상태바 ( Status Bar ) 를 없애면 아래 방법은 적용이 안됩니다.

상태바를 없애지 않아야 아래의 방법으로 키보드가 올라올시 뷰가 같이 키보드의 영역만큼 위로 올라갑니다.

 

다른 방법이 있다면 댓글로 알려주세요~!!

 

광고클릭은 포스팅 작성에 큰 힘이 됩니다!

728x90

 

 

1. AndroidManifest.xml파일에서 

android:windowSoftInputMode="adjustResize" 속성을 부여한다.

 

2. activity_main.xml 액티비티 레이아웃에서 ConstraintLayout 으로 설정하고 키보드로 보이지 않는 뷰를 하단으로 이어준다.

app:layout_constraintEnd_toEndOf="parent" )

 

 

스크린샷 참조

 

1. Manifest파일에서 해당 액티비티에 속성을 부여한다.

 

2. Constraint 밑에 뷰들을 배치시킨다.

 

Constraint를 하단으로 맞춰준다

 

 

 

<적용된 모습>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

windowSoftInputMode  속성 모음

 

 1. 설정 X : adjustUnspecified 와 stateUnspecified 가 적용 된다.

 

 2. adjustPan : 키보드가 올라오면 EditText에 맞춰 화면 UI가 실종 됩니다. (위 아래로 잘림)

 

 3. adjustResize : 키보드가 올라와도 EditText와 UI가 화면에 보이도록 Activity를 resize 한다.

 

 4. adjustUnspecified : 시스템이 알아서 상황에 맞는 옵션을 설정 한다. 키보드 조정에 대한 디폴트 값이다.

 

 5. stateHidden : Acitivty 실행 시 키보드가 자동으로 올라오는 것을 방지 한다.

 

 6. stateAlwaysHidden : Acitivty 실행 시 항상 키보드가 자동으로 올라오는 것을 방지 한다. (액티비티 이동 포함)

 

 7. stateVisible : Acitivty 실행 시 키보드가 자동으로 올라 온다. (EditText에 포커스 맞춰짐)

 

 8. stateAlwaysVisible : Acitivty 실행 시 항상 키보드가 자동으로 올라 온다. (EditText에 포커스 맞춰짐) (액티비티 이동 포함)

 

 9. stateUnchanged : 키보드를 마지막 설정 상태로 유지 한다.

 

 10. stateUnspecified : 키보드의 상태가 설정이 안된 상태이다. 시스템이 적절한 키보드를 상태를 설정해 주거나 테마에 따라 설정 해준다. 키보드 상태의 디폴트 값이다. 

NullPointerException 이하 NPE의 주된 원인중 하나는

xml의 뷰 객체 id값과 java 코드에서 매칭이 어긋난 경우다.


캡쳐로 모든 설명을 대신한다.









방지법 -> 


모든 액티비티 뷰의 네이밍 규칙을 통합한다.


ex) btnLogin, etID, tvWelcomeMsg


액티비티안에서 id name이 중복되지 않는다면, 다른 액티비티에서 같은 id name이 사용되더라도 상관없다. ( 실제 메모리 주소값이 다름 )


+ Recent posts