-
부제목비밀번호의 유출 전적을 조회해주는 애드온입니다
-
깃허브 주소
-
작업 기간2021.07.10.-2021.07.12.
비밀번호가 유출되었는지 알려주는 사이트이다.
거대한 데이터에 구미가 댕겨 이걸 사용해 비밀번호가 유출이 되었는지 회원가입 과정에서 알려주는 프로그램을 짜보고자 했다.
압축을 풀어보니 25GB 상당의 거대한 데이터가 나왔다.
너무 거대해 일반적인 텍스트 에디터로는 열리지 않아 HEX 에디터를 사용해 열었다.
데이터 구조는 이와 같게 생겼다
SHA1(40byte):유출횟수(int)
이를 분석하여 DB에 직접 넣어주었다. (초당 2천줄 꼴로 들어갔다.)
INSERT는 오래걸리더라도 바로바로 원하는 값이 존재하는지 찾아주어야 하기에 약간의 생각을 하였다.
SHA_FIELD 항목에 앞 다섯 글자를 빼내어 인덱스로 해준다면 LIKE 를 사용해 빠르게 쿼리를 할 수 있을것이라고 생각을 하였고, 이를 위해 SHA_FIELD(5) 만큼 빼내어 인덱스로 지정해주었다.
인덱스는 해당 컬럼의 분산도(카디널리티)가 높을 수록 유용하게 쓰이기 때문에 해시값에 적당하다고 판단하였다.
실시간으로 DB에서 해시값을 가져와야 하기 때문에 쿼리가 매우 중요하다
먼저 쿼리를 가져오는 부분을 코딩할 때 데이터들은 INSERT작업중이였고 아직 COMMIT이 되지 않은 데이터들이라 불러오는 것이 불가능 했다.
이는 그냥 몇 일 기다리면 해결되는 문제였으나 나중에 많은 커넥션이 동시에 들어오면 DB가 block상태가 되어 뻗어버리는 일도 일어날 수 있다.
위 두 문제를 해결하기 위해 트랜잭션 레벨이라는 것을 알게 되었다.
READ UNCOMMITTED |
1) COMMIT 되지 않은 데이터에 다른 트랜잭션에서 접근할수 있다. 2) INSERT, UPDATE, DELETE 후 COMMIT 이나 ROLLBACK에 상관없이 현재의 데이터를 읽어온다. 3) ROLLBACK이 될 데이터도 읽어올 수 있으므로 주의가 필요하다. 4) LOCK이 발생하지 않는다. |
READ COMMIITED |
1) COMMIT 된 데이터에 다른 트랜잭션에서 접근할 수 있다. 2) 구현 방식이 차이 때문에 Query를 수행한 시점의 데이터와 정확하게 일치하지 않을 수 있다. 3) LOCK이 발생하지 않는다. 4) MySQL에서 많은 양의 데이터를 복제하거나 이동할 때 이 LEVEL을 추천한다. |
REPEATABLE READ |
1) Default LEVEL이다. 2) SELECT시 현재 시점의 스냅샷을 만들고 스냅샷을 조회한다. 3) 동일 트랜잭션 내에서 일관성을 보장한다. 4) record lock과 gap lock이 발생한다. 5) CREATE SELECT, INSERT SELECT시 lock이 발생한다. |
원래는 SELECT던 INSERT던 해당 상태를 스냅샷한 부분에서 데이터를 읽어온다.
순차적으로 처리하기 위해서인데, 이렇게 되면 한 세션에서 데이터를 읽거나 쓰고 있다면 해당 DB는 블럭상태가 되어버린다.
그러면 해당 DB에서는 블럭상태일동안 읽지 못하게 되고, 이를 해결하기 위해 READ UNCOMMITTED를 사용하기도 한다.
물론 이렇게 해결하는것이 절대 좋은 방법이라고 할 수는 없으나, 내가 데이터를 저장한 테이블에 경우 INSERT가 초반을 제외하고는 없으며 단순히 읽기만 하면 되기 때문에 위 방법을 사용하기로 했다.
위와같이 설정해주면 된다.
다음으로 데이터를 가져올때 쿼리이다.
위와 같이 SHA_FILED와 LIKE를 활용하여 인덱스를 탈 수 있도록 하였다.
'?' 에는 SHA 쿼리에 앞 5글자를 잘라낸 다음 뒷자리에 %를 썼음
ex) 'ABCDE%'
위와같이 check.php를 넣었다.
데이터를 가져오기 성공
JSON으로 보내주었다.
※ 클라이언트
1차 비밀번호 체크
ajax를 통한 비밀번호 유출 확인
※ 결과
기본적으로 비밀번호 폼은 위와같이 생겼다.
비밀번호 조건을 만족하지 못했을 경우 '비밀번호를 확인해주세요.' 라는 메세지가 나온다.
비밀번호 조건을 만족했을 경우 sha1 암호화를 하여 서버로 쿼리를 날리게 된다.
쿼리를 체크하여 비밀번호 해시값이 존재하면 '이 비밀번호는 위험합니다! 유출 횟수: xxx회' 와 같이 위험 메세지가 나온다.
그리고 안전한 비밀번호를 입력했을 경우 이 비밀번호는 안전합니다 라고 뜨며 초록색으로 바뀌게 된다.
0