[컴] DUNS 번호 발급받기

DUNS 번호 발급받기 / duns number 발급 / 무료 발급



DUNS 번호 발급받기

아래 링크로 가서 apple 계정으로 login 을 하고 나서 발급받을 수 있다. 이녀석이 왜 필요하냐면, 나중에 SSL 인증서중에 EV certificate 를 발급받을 때 필요하다.




[컴] EV, OV, DV 인증서의 차이

인증서 종류 , ssl certificate 종류


EV, OV, DV 인증서

EV, OV, DV 인증서의 차이

간단하게 이야기 하면, 인증서의 동작에 차이는 없다. 다만 인증서를 발급해 주는 기관(흔히 CA라고 한다.) 에서 얼마나 인증서를 발행 해 주기전에 check 를 하느냐의 차이다.

그래서 EV, OV 에는 인증서(certificate)의 Subject field 에 'O'(organization) 가 추가된다. 그리고 Certificate policy 의 값도 다르다.



EV, OV, DV 확인법[ref. 3]

2012년의 ref. 3 에서는 현재로서는 DV(Domain validated)와 OV(Organization Validated) 를 구분할 수 없다.고 했다. 이때는 CA/Browser Forum 에서 제시한 Baseline Requirements 가 막 나왔을 때였어서, 각 CA(Certificate Authority)마다 어떤 식으로 OV인지, DV인지 표시하는 방법이 달랐다고 한다.

하지만 현재는 2018년이니 훨씬 더 많은 CA가 Baseline Requirements 를 따르고 있을 것이라 생각한다.

Certificate policy 에 기록

RFC 5280

X.509 에서는 RFC 5280 에 정의된 것처럼 Certificate policy 에 어떤 종류의 certificate 인지 적는다.

CA가 자신의 OID(object identifier) 를 적는다. 이 OID 는 발급한 certificate과 관련된 practices 를 적어놓은 문서를 가리킨다.
  • http://oidref.com : 여기서 oid 번호가 어떤 의미인지 파악할 수 있다.

CA/Browser Forum

Baseline Requirements 에서도 같은 방법을 사용한다.

google 의 인증서, OV
GlobalSign 의 EV 인증서
DV 인증서 예제


DV, OV, EV 발급방법의 차이

DV(Domain Validated)

  • 회사정보를 확인하지 않고, 인증서에 보이지도 않는다.[ref. 4]

OV(Organization Validated)

An Organization Validation (OV) SSL certificate is considered to be suitable SSL certificate for medium to large size business. This is because it offers higher validation as compared with DV certificate and displays domain name, organization name on the certificate. The encryption offered is up to 256-bit that enhances user’s confidence in the website they are transacting on.
On the other hand, for the issuance of EV SSL certificate, you need to submit quite a lot of documents to the certificate authority as per their need and requirement. This stringent verification process ensures strong encryption with a green padlock sign in the address bar ensuring protection against hackers.


Read more https://thebroodle.com/web/ssl/how-ev-ssl-certficate-works/
  • An Organization Validation (OV) SSL certificate
  • OV 를 발급받을 때는
    • 도메인 소유권을 확인하고,
    • "기관(organization)과 "인증서를 신청한 개인"에 대한 조사

EV(Extended Validation)

  • CA/B forum 에서 제안했다.
  • CA가 "기관(organization)" 과 "인증서를 신청한 개인"에 대해 훨씬 엄격한 검사
  • ref. 5를 보면 EV 인증서는 발급에 대략 1개월 정도 소요되는 듯 하다. 참고로 ref. 5 에서 이야기한 저렴한 곳은 여기 같다.

See Also

References

  1. What is an EV (Extended Validation) SSL Certificate and How it Works?
  2. What Are the Types of SSL?
  3. How to tell DV and OV certificates apart | UNMITIGATED RISK, 2012년 9월
  4. DV, OV or EV? How to offer the right SSL Certificate - OpenSRS, 2015. 5. 22
  5. EV SSL 인증서 발급 과정에서 알게된 것들 - 리디주식회사 RIDI Corporation, 2017년 3월 5일

[컴] Application Pperformance Monitoring tools

APM / application performance monitoring / APM tools / open source APM tools / application performance management


서버 성능 측정 도구

  • SCOUTER APM :  현재 버전(v.1.8.5) 에서는 Java Web application 에 대한 성능측정만 제공
  • AppNeta : AppNeta's free Project plan has almost 100% of the functionality
  • Zipkin : 트위터에서 만들었음. distributed system 에서 사용함.
  • Appdash : distributed application monitoring system, GO, python app 에 사용가능 그리고 Protocol Buffer 를 사용하는 app 에 사용가능
  • inspectIT :  Open Source APM (application performance management) tool for monitoring and analyzing your Java(EE) software applications.
  • New Relic : offer free versions of their products
  • AppDynamics: offer free versions of their products
  • appnomic.com


See Also

  1. Performance Monitoring Comparison: Build vs. Buy
  2. MySQL :: MySQL Workbench



References

  1. Are there any good, free, open source APM, i.e., Application Performance Management, products available other than commercial ones like New Relic and AppDynamics, and can Google Analytics perform this job? - Quora


[컴][보안] 로그인 관련 보안 2

로그인과 보안 / secure login / 로그인 고민




목차
  1. 로그인 관련 보안 - 1
  2. 로그인 관련 보안 - 2










handshake - exchange the symmetric key

여기서 관건은 MitM 공격이 ssl 을 해놨을 때 틀린 CA 에 대해서 volley (정확히는 HttpsConnection) 가 verification 을 해서 error 을 내뿜으면, 굳이 이 작업을 하지 않아도 될 듯 하다. 그러나 이것은 실제 test 를 해보기 전에 아직 확신할 수 없다.


client <-------------> server
request key   ---->
              <---- public key
symmetric key ----> 


public key 를 server 에서 받지 않는다.

ssl/https 에서는 public key 를server 에서 받은 후 그 public key 를 이용해서 symmetric key 를 주고 받게 된다. 이 경우에 인증서를 인증할 수 있기에 이렇게 한다. 하지만 나는 보내주는 public key 가 누가 보냈는지 알 수 가 없다. 중간에서 공격자가 보내도 그냥 맞는 거구나 하고 보내 버릴 것이다.



server 가 client 로 부터 symmetric key 를 받고나서 server 는 해당 key 를 어떤 user 의 key 라고 알고 있어야 한다. 그래야 해당 user 의 request 가 오면 그 key 를 사용해서 복호화(decryption) 을 할 수 있다. 이를 위해서 DB 에 저장이 필요하다.


이 때 token 이 있는 경우라면, token 을 보고 user 를 구분할 수 있다. 하지만, token 이 없는 경우라면, 임시로 저장을 해 놓아야 하는데, 이를 위해서 phone number 를 public key 로 암호화 해서 보낸다.

하지만 여기서 "폰번호" 는 임시 token 으로 사용하는 것이라, 실제 id 와 연관된 db 에 저장하지 말자. 실제 id 로 사용되는 폰번호와 관련해서 사용하면 공격자가 이상한 값이나 존재하는 값과 비슷한 값을 보내는 경우 다른 사람이 사용하는 record 에 저장하는 문제가 생길 수 있다.

  • token 을 가지고 있는 경우 : token 을 보고 판별한다.
  • token 이 없는 경우 : 폰번호를 public key 로 key 를 주고받을 때 같이 보낸다.
    • 가입이 이미 되어 있는 경우
    • 가입이 안된 경우



Hacking

 아래와 같은 공격이 가능하다. 하지만 아래와 같이 할 것이라면, 차라리 가짜 app 을 하나 만들어서 비밀번호를 입력하게 하는 것이 훨씬 간단하다. 그래서 그나마 공격자가 선택하는 방법은 public key 를 바꿔 놓는 수준이 될 듯 하다.

공격자가 자신의 server 로 접속하게 해서 비밀번호를 알아낸다.


이상황에서 고려할 수 있는 hacking 은 누군가(여기서는 A라고 칭하자.) 의 핸드폰을 몰래 가져다가 public key 를 공격자의 public key 로 교체하고 A 에게 다시 돌려주는 것이다.

이 상황은 ssl 인증서로 무력화 될 수 있지만, 폰을 훔쳤을 때 인증서도 조작할 수 있다.

그러면 A 는 이 public key 를 가지고 통신을 하겠지만, 직접 server 와 통신할 수 없다. key 가 틀려서. 그래서 domain 을 공격자의 server 로 변경해 놓는다.
  1. public key 변경
  2. domain 변경(or DNS 조작)
 이 상황에서 공격자의 server 와 통신을 하면서 A 가 실제로 송금을 한다면, 송금은 안되지만, 공격자는 A 의 auth token 과 비밀번호를 알 수 있다.
  1. auth-token
  2. 비밀번호
이러면 공격자는 A 의 폰을 훔치고, 이 auth-token 과 비밀번호를 가지고 자신의 계좌로 송금할 수 있다.

대처

이 상황을 막고자, public key 를 쉽게 바꿀 수 없도록 한다. 그 방법으로 public key 를 file 자체로 놔두지 않고, xor 등의 연산을 통해 만들어 사용한다. 그리고, crc 등의 방법을 사용해서 변경되지 않음을 확인한다?

이글  이 도움을 준다.
  1. public key 를 xor 등의 연산을 통해 획득
  2. CRC 등의 방법을 이용해서 public key 내용이 변하지 않음을 확인.(이부분도 공격자가 변경 해 놓을 수 있다. 하지만 이런 식으로 힘을 드리는 것보단 차라리 app 을 교체해 놓는 것이 낫다.)
  3. 이체 후 서버에서 고객의 email 등(또는 GMS 등, 실제 서버만이 가능한 것)으로 알림을 준다. (폰으로 주는 것은 안된다. 공격자가 이미 전화번호를 알고 있어서 sms 를 흉내내서 보낼 수 있다.)
    이것은 고객이 자신의 송금 명령이 제대로 된 서버에게 보내졌는지를 확인하는데에 도움을 준다.












[컴][보안] 로그인 관련 보안 1



2015년10월에 정리한 글을 다시 옮겨왔다.




Toss 의 로그인

Toss 가 본인 명의의 휴대폰 1대에서만 사용가능하다고 한다.
송금이 사용자의 휴대폰에서만 가능하다.

그래서 자신이 직접 전화번호(phone number) 를 입력할 수 없다.

폰번호, 기기 ID 확인은 어디서?

폰번호 + 기기 ID (IMEI) 가 일치해야 할 듯 하다. 이것을 통신사에서 확인할 수 있나? 아니면 server 에 가지고 있어야 하는가?


  1. 사용자의 비밀번호를 아는 경우 : 사용자의 폰이 아니라서 불가능
  2. 사용자의 폰에서 시도하는 경우 (훔친 경우) : 사용자의 비밀번호를 몰라서 불가능
  3. 사용자의 폰을 복제하는 경우 : 새롭게 login 을 하면 문자가 날라온다. 그러므로 걸릴 듯 하다.
  4. 사용자의 폰을 훔친경우 + 비밀번호를 아는 경우 : 어쩔 수 없다?

처음에 등록하는 암호가 이들이 사용하는 Login password 인 듯 하다.
이 값을 받아서 hash 해서 저장하고, local 에도 hash value 로 저장 해 놓는다.
그리고, 전화번호와 pw 를 보내서 인증을 받는다?

toss 가 local 에 가지고 있는 값, TOSS.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="gaCode">9WOv+FvTQXaaU2+aNj1DTw==
    </string>
    <string name="seqNo">zeYYBd62OnqMld4PxW64h++T+yhxeq3wA+Cb3BTBJWM=
    </string>
    <string name="aesKey">xOolFn/09ZO1boBpzGsMw3sWQ3AnlstqHfqPc9k+PJUhksJN0aRU7J631l2oLcme
    </string>
    <string name="pKey">Dw0tPa4Nm58Dt7UxfEuk7tOs7VSQ9pZPOMQ+VGthUU1HKDwTxcjeULVdwdIzQZkh
    </string>
    <string name="timestamp">RNZp58Zh16VZs4IKulvXtQ==
    </string>
    <string name="promotion"></string>
    <string name="privateKey">...
    </string>
    <string name="initData">...
    </string>
    <string name="pNumber">5bEKGSs6BbE2lE4vAt32lQ==
    </string>
    <string name="hasSetTossAlarm">9zV6TSbGJjPn0EnPdHkCxA==
    </string>
    <string name="birthDate">y/6msagccRolTPjekUgFCg==
    </string>
    <string name="name">4Ta03cJDFgrqcAT0RUgdJA==
    </string>
    <string name="faultCount">xfjOGX+ONgBoI7KVMAD40g==
    </string>
    <string name="INIT">9zV6TSbGJjPn0EnPdHkCxA==
    </string>
</map> 



SSL에서 Main-In-The-Middel Attack 





Login 2


여기 글 처럼 auth token 을 쓰자. 그리고 비밀번호를 수정할 때 마다 auth token 이 다시 만들어지게 된다. 이러면 아래의 고민 중 credential 을 stolen 당할 때 client 에 암호화 과정이 들어가 있어서 hacker 들이 추측할 수 있는 여지가 줄어든다.

조금 다른 점은 새롭게 로그인할 때마다 시간을 기록하고, auth token 을 다시 만든다? time 을 더해서?
그러면 한 앱에서 한개만 가능할 것이다.

이건 처음에 생각한 것과 비슷한데, 처음 생각은 auth token 처럼 고정적인 token 을 만들생각을 안하고, expired token 만 고려했는데, 이번엔 2개의 token 을 사용하자.

이 Auth Token 을 가지고 있고, 이녀석을 가지고 다시 expired 가 있는 token 을 얻어오도록 하자.


https sniff, MITM

MITM 의 공격에서는 보통 인증서가 잘못 되었다고 뜬다. (참고) 이것이 volley 에서 어떻게 동작하는지 확인이 필요하다. 만약 error 가 된다면, 굳이 https 가 공격 당할 걱정을 안해도 될까?? 일단 가능할 듯 하다.

MITM 공격에 대비해서 https 위에 다시 한번 https 를 얹어놓자. 정확히 비슷하지는 않지만, sniffing 을 대비해서 한 번 더 encryption 을 해 놓는다. 이부분은 https 와 비슷하게, asymmetric encryption 으로 symmetric 의 key 를 주고 받고, 이 key 를 이용해서 encrypt 해서 보내면, server 에서 decrypt 를 한다.
symmetric encryption 의 key 는 주기적으로 server 에서 교체하면 된다.
client 의 public key 는 client 에 대한 인증역할도 같이 할 수 있다. 그러기 위해서 각 user 의 private key 를 저장하고 있는다.


auth token, expired token

expired token 이 csrf 공격의 방어 기능을 할 수 있다. 그렇다면 expired token 의 generation 을 절대적으로 핸드폰에서만 가능하도록 해야만 한다. phone number 를 가져와서 expired token 의 hash 를 만들때 사용한다.



auth token , no expired token

auth token 만을 이용하자. 이러면, rooting 된 폰에 의해서 auth token 을 stolen 되고, data/data 내용을 그대로 가져가서 새로운 폰에서 toss 를 시작한다고 하면, 여기서 다 잘 된다고해도, 송금할 때 결국 비밀번호를 다시 입력해야 한다. 그래서 괜찮다.

폰정보를 가지고 있을 필요는 없어 보인다. 이 또한 복제될 수 있어서.

expired token 이 필요치 않은 이유

expired token 은 sniffing 때문에 필요하다고 생각했는데, expired token 대신에 auth token 을 사용하다가 sniffing 을 당한다고 해도, 결국 비밀번호를 다시 입력 하는 부분 때문에 사용할 수 없을 듯 하다.

sniffing 에 대한 대비

위의 <https sniff, MITM> 를 참고하자.
expired token 등 sniffing 될 요소들을 사용할 때 한번 더 암호화 하고, ssl 을 사용한다. 이것은 hacked 된 https line 에서 해킹이 어렵게 해준다.

그러면 비밀번호를 보내는 순간에 sniffing 을 당하지 않아야 하는데.... https 같은 경우 secured line 이 아닌 상황이라면, 비밀번호가 노출되는데, 이때를 위해 public key 로 암호화를 걸어놓자.? 하지만 이경우도 brute force 로 알아낼 것이다. 왜냐하면 toss 의 경우는 "숫자4+문자" 의 형태라, 경우의 수가 작은 편이다. public key 가 노출된 상황이라면, 모든 case 에 대한 table 을 가지고 있게 되고, 이런 상태라면 암호화를 한 비밀번호도 손쉽게 노출된다.

그러면 주기적으로 public key 를 갱신해준다. ? 그러면 public key 를 저장하지 말고, network 로 받는다. 하지만 이 경우에 xor 등으로 난독화 하려는 계획이 어려워 질 수 있다. 물론 2개를 받아서 xor 후에 사용할 수도 있을 듯 하다.

송금 수신자 정보 암호화

만약 phone 을 hacking 하지 않고, sniffing 만 하는 경우에, token 을 알고 있다면, 송금이 가능해 진다. 이때 비밀번호가 같이 가기에 괜찮은데, 이렇게 되기 위해서는
비밀번호와 수신자 정보를 같이 암호화 해야 한다. 따로 암호화 하면, 비밀번호 부분을 가져다 이용할 수 있다.
그래서 encrypt("비밀번호","수신자정보") 형식등으로 암호화를 해서 보내야 한다. 그러면 비밀번호를 모르기에 암호화 키를 알아도 적절한 값을 만들 수 없다.
그런데, 비밀번호가 간단하니, 여기에 "hashed 폰번호" 또는 "hashed timestamp" 를 추가로 이용한다.?



rooting 에 대한 대비

그리고 auth-token 은 rooting 등으로 쉽게 가져갈 수 있다. 이것은 다른 app 들에서 하듯이 rooting 인 phone 에서 실행이 안되도록 하는 방법이 있다. 하지만 이것도 우회하는 법들이 생겨났기에, 임시방편밖에 안된다.
rooting 을 하고, token 을 가져간 공격자는 이것을 가지고, 시도를 할 수 있지만, 다행히 비밀번호를 몰라서 바로 hacking 당하지 않는다. 그러므로 잘못 시도된 비밀번호에 대해 user 에게 알려줄 필요가 있다.



처음 등록시 password 전달

처음에 public/private key pair 를 가지고 있는 상태가 된다. public key 를 client 가 가지고 있는다. 이 key 는 처음 password 를 등록할 때 쓰이게 된다.
client 에서는 public key 로 암호화 한다. 이 때 random 값을 같이 준다.
  • public_key_encrypt(pw, random)
password 와 public key 가 모두 노출되어도 유추할 수 없다. random 값이 없으면 rainbow table attack 이 가능할 수 있다.

key 교체시

key version 관리가 필요하다. 서버에서 key 를 바꾸고 새롭게 key 를 장착할 때 기존의 모든 client 가 새로 등록을 할 수 없게 된다. 이 경우에 새로운 버전을 설치하라고 알려줄 필요도 있을 듯 하다.


default public/private key pair

  1. 처음에 접속하면 받도록 하자. 어차피 공개된 녀석이라 굳이 가지고 있을 필요는 없을 듯 하다.
  2. 이녀석은 client 에서 server 로 보내기만 하는 경우이면서
  3. 크기가 작은 녀석을 암호화 할 때 사용가능 하다.(asym 은 암호화 속도가 느려서 큰 것은 힘들다.) 

symmetric 암호 key

  • public_key_decrypt<유저 입력 password  + 랜덤 값+ 폰 넘버>
client 에서 결정하자. 이 시도가 좋지 않을 수 있다. 대부분 서버에서 결정하고 내려준다.(여기를 확인하면 이것이 일반적인 결정인 것을 알 수 있다.)

 임시 key 등은. 하지만 여기서는 public key 를 가지고 있는 쪽이 client 여서 client 가 결정을 내린다. public key 로 암호화 해서 보내면, private key 를 가진 server 만 알 것이다.


client 에서 보낸 암호를 가지고 symmetric 암호화를 하면 된다. 이 때 symmetric 암호키는 랜덤한 값이며, 항상 password 를 보내는 순간에 password 와 같이 보낸다. 그리고 symmetric key 를 받자마자 서버가 symmetric 암호화로 data 를 보낸다. 이러면, sniffing 을 당해도 rainbow attack 등을 피할 수 있다. 그리고 매번 변경돼서, token 을 가져가도 크게 의미가 없다. 누군가 token 을 가지고 key 를 시도한다해도, 암호를 같이 encrypt 하지 않았다면 인정받지 못하게 된다.

세션이 없기에, db 에 임시 저장이 필요하다? 이렇게 되면, 암호가 invalidate 되는 시점도 정확히 정해져야 한다. random 한 값이 사용되므로, 항상 db 에 저장해야 할 필요가 있다.TokenAuthentication 도 token 을 가지고, 이녀석에 해당하는 user 를 가져오는데, 이것처럼 TokenAuthentication 일 때 symmetric key 도 같이 가져오도록 한다.

이 상황은 하지만,처음 로그인에서는 가능하지만, 이후에 token 으로 login 을 하는 경우에는 적합하지 않다. 송금을 누르고 송금정보가 날라갈 때 암호화할 key 가 이미 있어야 한다. 그렇지 않다면, 2번 왔다갔다 해야 한다.


만약 client 가 random 하게 값을 정해서 server 로 보냈다고 하자. 그렇다면, 누구나 그렇게 random 하게 만들어서 server 로 보낼 수 있다. 공개키는 얻을 수 있으니. 그러면 server 는 아무하고 encrypted 통신을 하게 된다. client 가 공격자인 경우도 생긴다.



Login

  • 전화번호 : 노출
  • public key : 해킹에 의해 노출
  • 비밀번호 : 입력
    • 비밀번호를 key logger 를 사용하지 않는한 안전하다고 가정.

여기서 문제는 rainbow table 로 경우의 수를 만들어서 던져볼 수 있다. 그래서 local 에서 credential 을 만들 때 hashing 을 한 번 하고, 그 값을 가지고 credential 을 만들어야 한다. 그러나 그래도 source 를 decompile 한다면, hashing 횟수나 salt 를 쉽게 파악할 수 있을 듯.

time delta

time delta 를 쓰지 않으면, 결국 client 를 hacking 해서 보안이 문제될 수 있다.
그래서 본인 휴대폰 인증받는 순간(문자, ARS 등)  의 시간을 기준으로 한 time 를 만들어서 보내자.
그러고 인증이 통과되면,(로그인 완료후) 이 시간을 server db 에 저장 해 놓고,
time(sec.) 이 이 시간에서 멀지 않은 시간(약 30분?) 으로 setting 된다면,
ok 로 받아드린다.

  • 공격 유형 : 이것은 해커가 public key, id, pw 를 모두 알고 있는 상태에서 해 볼 가능성이 있는 공격이다. 근데 pw 가 노출될 확률이 낮다.



폰을 도난 당한 경우

누군가 폰을 훔쳐갔을 경우, 도둑이 rooting 을 할 수 있다. 그러면, SharedPreference 등에 접근할 수도 있고, 그대로 app 을 사용할 수 있다.

정지방법
이 경우에 외부에서 정지시킬 수 있어야 한다.
  1. 다른 폰에서 앱을 새롭게 login 을 하거나, : time-delta 로 이전 로그인을 차단한다.  / 비밀번호를 변경한다.?
  2. web 을 통해 정지 명령 : server db 에서 time 을 조작해서 time-delta 를 이용할 수 있다.
이 가능하다.

공격

  • 해킹을 통해, credential 을 얻은 경우 : 이 경우 시도해도, 위의 "정지방법" 에 의해 time-delta 가 맞지 않아서 걸린다. 그래서 setCurTime 을 이용한 time 대한 수정을 하려고 할 것이다.(아래 참고)
  • public key, id, pw, 얻은 경우 : time delta 를 알아내기 위해, 다양한 time 을 넣고, credential 을 만들고 사용하려 할 것이다. 이런 접근이 있는 경우 서버에서 감지해서 처리해야 한다. -> 패스워드 변경유도



setCurTime 에 대한 공격

만약 이 request 를 외부에서 해 온다면? 이걸 어떻게 app 에서만 하도록 할 수 있나?

첫 인증시만 사용가능 하도록 : 이것은 ARS 인증? 등을 할 때, 인증이 성공한 경우에만(로그인을 하듯이) time 을 저장한다. 그 외의 경우에는 setCurTime 을 요청하지 않는다.

본인인증 확인 가운데에 설정을 하는 것이라, 노출되지 않는다?
credential 을 만들 때 전해준다.? : 이건 다른 쪽에서 비슷하게 흉내낼 수 있다. rainbow attack 이 들어올 것이다.

공격 상황

  • 해커가 credential 을 가지고 있다.(public key (비밀번호 + id + timedelta )) 그래서 이 credential 에 time-delta 가 들어가는 것을 알고, 이 time-delta 를 맞추기 위해 setCurTime 을 특정 시간으로 조정하려 할 때(무자비하게 여러번 시도 할 것이다.), 
  • credential 을 새롭게 만드는 것도 시도할 수 있지만, 비밀번호를 모를 확률이 크다.













본인인증

  • 한국 모바일 인증 > 개인정보취급방침 : 여기에 보면, toss 가 처음에 인증을 위해 필요한 항목을 입력하는 것과 일치하는 것을 알 수 있다. 아래 2가지 항목을 확인하자.
    • 본인확인기관(이동통신사, 공인인증기관 등)을 통한 본인확인 정보의 일치여부 확인 : 휴대폰번호, 통신사, 성명, 성별, 생년월일, 내/외국인 구분
    • 휴대폰 사용자 확인을 위한 SMS인증번호 전송

위의 인증을 위해서라도, server 에서는 "전화번호"를 가지고 있어야 한다.


OAuth 등의 로그인을 고려해 보자. facebook 같은 녀석으로 한번 login 을 하고 나면, 그 이후로 access token 으로 이녀석을 접근한다. 이것도 어쩔 수 없이 한번의 노출을 만들지만, 그 이후에 id/pw 는 노출되지 않으므로, 항상 id/pw 가 노출되는 것보다 현저하게 노출위험을 줄일 수 있다.

같은 의미로, app 이 처음 실행할 때만 id/pw 를 입력받도록 한다. 그리고 나서 access token 을 발급하자. 그러면, 이 access token 을 저장하고 있다가, 다시 app 을 실행하게 되면, 이 access token 을 보내고,


JWT vs Django login


Using JSON Web Tokens as API Keys 를 참고해서 login 을 위해 JWT 를 사용하기로 했다.
Redirecting Our Django Website to Our Ember App - Shippo

장점

  • 위의 글을 참고한다면, 다양한 방법으로 token 을 이용할 수 있을 듯 하다.
  • Django Rest Framewrok jwt 를 이용하면, permission_class 등의 방법을 그대로 사용할 수 있다.


Django login 도 같은 기능을 제공하긴 한다. csrftoken 을 이용해서, 그런데 문제는 site 에 접근하지 않고, csrftoken 을 받아오는 방법을 찾기가 시간이 걸린다. 그리고 확장성도 떨어진다. Django 자체의 login 과 연동하긴 좋을 수 있다.




client 가입 알고리즘

서버

  1. IMEI 와 전화번호를 서버에 저장한다.
    처음 인증할 때 "통신업체"를 통해 폰이 본인인 것을 확인한다.(아무래도 handset 자체에 대한 검증은 하지 않는 듯 하다.)
  2. public key 를 client에 넘겨준다.
  3. 이때의 datetime 을 기록한다.

client

  1. public key 를 저장한다. 저장시 여기를 참고 
  2. IMEI 와 timestamp 를 public key 를 이용해서 암호화해서 저장하고, 이것을 사용한다.
    • 이것이 결국 password 역할을 할 것이다.
    • 해커는 이 날짜의 존재를 모르기에 만들기 어려울 것이다.
    • 만약 decompile 로 날짜와 함께 만들어진다는 것을 안다고 해도, 이 날짜가 특정시간에 맞춰야 하기에 그 특정시간을 알 수 없다.
  3. public key 를 가지고 있어도 되고, 버려도 된다.
  4. 이 암호화된 IMEI 와 phone number 를 server 로 날려서 token 을 받는다.

서버

  1. 서버에서는 client 에서 온 암호화된 text 를 private key 로 decrypt 한다.
  2. 그리고 날짜를 public key를 넘겨준 날과 비교한다. 시간상 10분(?) 이내라면 허락한다.
  3. 그 이외의 날짜가 같이 IMEI 와 encrypt 된 경우에는 허락하지 않는다.




asynch algo 를 사용한다. timestamp 를 넣어서 암호화된 text 가 steal 되어도 안전하게 만든다.





client 에서 자동 로그인

  1. phone number SIM 에서 읽기
  2. device id 가져오기
  3. phone_number + device id 를 가지고 encryption or hashing
  4. 이 값을 server 로 전송해서 login

pw 암호화

device id 를 phone number 를 key 로 해서 암호화 한다. 이 때 key 는 phone number 를 4자리 단위로 shift 해서 만든다.
  • 01023026616 --->  66160102302 



JWT

djangorestframework-jwt  사용

  • 접속시에 token 을 만든다. 
  • 이 token 은 expiration time 을 갖는데, 이 expiration time 이 끝나기 전에 refresh 를 하면 계속 유지된다. (JWT_EXPIRATION_DELTA)
  • 하지만 이런식으로 같은 token 이 유지되는 시간도 한계를 정할 수 있다.(JWT_REFRESH_EXPIRATION_DELTA)
  • 어느정도 시간 유지가 적절한가?
  • 계속 화면을 띄워놓고 있는 경우에 계속 refresh 를 하기는 부담스럽다. 차라리 refresh 를 못하게 하고, expiration time 을 1일 정도로 가져가는 것이 나은가?






IMEI 를 확인하지 않는경우

SIM의 MSISDN + IMSI 를 복제된 경우

여기서 toss 처럼 인증을 하면, 문자를 받거나, 전화인증에서 양쪽에 전화가 걸려올 수 있다. 그래서 노출될 수 있다. 하지만 그 순간에 본인이 핸드폰을 못봐서 넘어갔을 확률이 있으므로, 이를 대비해서 로그인 후 "로그인했다" 는 정보를 시간과 함께 sms 로 전달해 준다.

그러므로 굳이 IMEI 정보를 알고 있지 않아도 될 듯 하다.



로그인

1번째 로그인

폰에서 app 을 깔고, 처음 로그인 할 때 (전화번호, 이름, 기기 id ) 를 server에 저장
그리고 계속 이 번호로 로그인한다.
처음에 비밀번호를 등록할 때,


이 때 특정 public key 를 보내준다. ???
그럼 public key 로 특정 값을 암호화 해서 server 로 보내게 되면 server 는 그 값에 해당하는 private key 를 가지고 그녀석이 맞다는 것을 확인한다. 그런데 이것은 결국 https 라서, 전체적으로 이런 일을 중복해서 할 이유는 없다.


2번째 로그인

2번째 부터는 phone number 와 기기의 id 를 가지고 로그인한다?
여기서 jwt 를 얻어온다. 그리고 이 값으로 통신한다.


phone number 의 저장

phone number 는 서버의 db 에 저장된다. 서버에서 직접적으로 sms 를 보내는 등의 일을 해야 하기 때문에 어쩔 수 없이 노출된 값을 가지게 된다.

다만 DB에 암호화된 값으로 저장하고, decode 해서 사용할 수는 있다. 이 경우는 key 를 어떻게 가지고 있어야 할 지 고민해야 한다. 장고의 SECRET_KEY 를 이용할 수도 있다.


패스워드, hash(phone_number + Device ID)

송금할 때 사용하는 패스워드 이외에는 패스워드가 따로 없다. 대신에 기기의 ID(Device ID) 를 이용한다. 이 녀석을 직접적으로 pw 로 사용해서 확인할 필요는 없고, 이 ID 를 seed (또는 salt) 로 이용해서 나온 값(hash 값이면 될 듯 하다.)을 이용한다.

이 값을 server 의 DB 에 저장하고, 매 로그인할 때 client 에서 (phone-number, device id) 로 hash 값(또는 암호화한 값)을 만들어 보낸다.?

client 에 암호화, 해시함수를 두는 경우

이것이 server db 를 해킹한 사람들이 client 의 library 에 대한 decompile 을 시도할 것이다.

그러면 시간이 걸리겠지만 가능해 진다. (사실 암호화나, hash 함수나, 이름만 알면 그냥 사용하면 되고, 단순히 seed 나 salt 값을 어떻게 적용했는지의 문제일 뿐일 수 있다.)  그러면 hacking 해서 번호와 device id 에 대한 해독이 가능할 수 있다.
하지만 이 경우에도 phone number 의 암호화가 되어 있는 경우에는 알아내기 힘들 수 있다.

이 부분이 binary 로 되어 있어 decompile 이 어렵고 시간이 걸려서 포기하는 집단도 있을 것이다.

application server 에 암호화, 해시함수를 두는 경우

기기 id 와 폰 번호를 바로 server 로 넘기고, server 는 이 값을 가지고 hash function 을 이용해서 비밀번호를 만들어 저장해 놓는다.

이 경우 hash function 은 노출되지 않아서 server db 를 해킹한 해커는 application server 에 대한 해킹을 다시 하지 않는 이상 db 에서 의미있는 값을 얻기 어렵다.

하지만 client 쪽에서 format 만 맞춰서 쉽게 request 를 날릴 수 있게 된다. request 날리면 서버에서 알아서 암호화를 하고 비교를 할 테니, 암호화의 의미가 server db 가 해킹당했을 때의 대비만을 위한 것이 된다.



만약 phone-number 가 노출된 경우

phone number 를 phone SIM 에서 바로 가져오기 때문에(SIM 에서 안드로이드 SDK 를 통해) 직접 입력하지 않는다. 그래서 phone 의 SIM 에 새겨진 번호를 조작하지 않았다면 괜찮다.


만약 SIM 을 조작했다면?(복제폰?)

전화번호가 같더라도, device id 가 같지 않다. 그래서 이 경우에는 device id 까지 해커가 훔쳐야 한다.

만약 SIM 을 복제 하고, device id 도 복제했다면

폰으로 시도

비밀번호를 몰라서 막히던지, 비밀번호 재설정을 할 때 막힌다.
비밀번호 확인작업을 하는데, 이때 비밀번호 재설정도 할 수 있다. 그런데 재설정 작업은 이들이 자신만의 방법(계좌에 돈 보내고, 그 날짜로 확인)을 이용한다. 이과정 때문에 어쩔 수 없이 공인인증서 등으로 확인이 된다.
그렇기 때문에 여기서 막힌다.

pc로 시도

여기에 어떻게 해서 이들이 send request format 에 맞춰서 송금 명령을 server 로 보냈다고 하자. 그러면 여기서 jwt token 을 얻고, 이 token 으로 계속 통신을 할 것이다. 하지만 송금할 때에는 다시 비밀번호를 직접 입력해야 한다. 결국 비밀번호를 몰라서 실패한다.



기기 ID 가 노출되어서 알려진 경우

기기id가 노출돼서 그것을 카피한 핸드폰으로 시도 해도 암호방식을 해킹해야 한다.

암호방식 binary

암호방식은 이것이 일단 binary라서 바로 해독은 불가능하지만 해킹이 불가능은 아니다. 그래도 memory 채 가져와서 사용할 수 있을지도.?


그런데 시드 서버가 갖고 있어야 하는가?
암호화한 값을 비교 할 수만 있면 된다.
암호를 해독할 필요가 있나?
서버가 털릴때를 대비해야한다.
암호화도 털려서 온다해도 서버에서 인증이 거부 될만한 요소를 가지고 있는가?


서버가 해킹될 때

서버가 털리면
  • 암호화된 패스워드(기기id, IMEI)
  • 전화번호 : 암호화 하는 것이 나을 듯 하다. 속도의 저하가 있을 수 있지만 보안이 더 중요하다.
  • 실명
  • 암호화된 송금 비밀번호(hashed value)
DB 암호화를 고려해 볼 수도 있다. (:: DBguide.net :: 데이터 전문가 지식포털)
이 부분은 일단 많은 방법들이 나와 있어서 크게 문제되지는 않을 듯 하다.


송금 비밀번호

송금 비밀번호는 계속해서 다른 기기에서도 일치여부를 확인할 수 있어야 한다.
그래서 서버쪽에서만 암호화 또는 hashing을 한다.

hashing 의 salt 를 무엇으로 해야 하나?

기기가 바뀌어도 유지돼야 해서, device id 는 안된다.
폰번호가 바뀐 경우는 모르겠다.
명확한 것은 실명인 듯 하다.


스니핑에 대한 고려로

송금 비밀번호를 서버쪽에 보낼 때 암호화가 필요한가? 필요할 듯 하다. 스니핑을 하지 않더라도, 임의로 값을 만들어서 보내는 경우에 앱을 통해서가 아니라 외부툴일 가능성이 있는데 외부 툴로 가능하게 되면, 쉽게 뚤린다. 토스의 5자리의 경우는 특히.

그러므로 보내기 전에 한번 가공을 하고, 그 값을 서버 DB 에 저장된 값과 비교하는 것이 나을 듯 하다.

이것도 마찬가지로 server db 가 해킹당한 후에 해커가 client 의 decompile 을 노릴 수 있다.



서버쪽에서 해킹 당한 경우

이 경우 hashing 되어 있어서, hashing algorithm 을 적용하고, salt 를 파악하지 못하면 의미가 없다. application server 도 해킹을 같이 당해야 한다.

client 에서 당하는 경우


  • 클라이언트에서 입력한 상황에서 메모리의 값을 steal 할 확률 : 이정도의 해킹이 쉽게 될지 모르겠다. 메모리 주소를 쉽게 알 수 없을테니. 일단 잘모르겠다.
  • 키에 대한 로깅으로 해킹하는 방법이 있을 수 있는데 : 키에 대한 로깅을 방지하려고 난독 키보드를 이용한다.








[컴][웹] lumen 에서 session 사용하기



lumen 에서 session 사용하기

  • lumen version: 5.4.*

config/session.php

session.php 는 laravel 의 config 에서 관련 config를 가져와서 <lumen>/config/ 에 copy 하면된다.

그리고 이 session.php 를 load 하려면 boostrap/app.php 에 code 를 추가해야 한다.
$app->configure('session');


가능한 설정들은 아래와 같다. 자세한 사항은 config file 의 주석을 참고하자.

  • 'driver' => env('SESSION_DRIVER', 'file'),
  • 'lifetime' => env('SESSION_LIFETIME', 120),
  • 'expire_on_close' => true,
  • 'encrypt' => false,
  • 'files' => storage_path('framework/sessions'),
  • 'connection' => null,
  • 'table' => 'sessions',
  • 'store' => null,
  • 'lottery' => [2, 100],
  • 'cookie' => env(
            'SESSION_COOKIE',
            str_slug(env('APP_NAME', 'laravel'), '_').'_session'
     ),
  • 'path' => '/',
  • 'domain' => env('SESSION_DOMAIN', null),
  • 'secure' => env('SESSION_SECURE_COOKIE', false),
  • 'http_only' => true,
  • 'same_site' => null,


illuminate/session

illuminate/session 이 필요하다. 일단 설치를 해주자. 참고로 lumen 의 버전과 맞춰야 했다.
composer require illuminate/session
composer require illuminate/cookie "^5.4"


bootstrap/app.php

StartSession Middleware

bootstrap/app.php 에 middleware 를 추가해주자.
$app->middleware([
    \Illuminate\Session\Middleware\StartSession::class,
]);

SessionServiceProvider

SessionServiceProvider를 등록해주자.
$app->register(Illuminate\Session\SessionServiceProvider::class);
$app->register(Illuminate\Cookie\CookieServiceProvider::class);


binding

$app->bind(Illuminate\Session\SessionManager::class, function ($app) {
    return $app->make('session');
});

// cookie relevant
$app->bind(Illuminate\Contracts\Cookie\QueueingFactory::class, 'cookie');

위처럼 해주지 않으면 아래와 같은 exception 이 발생한다.
Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class Illuminate\Support\Manager


session 폴더 권한

windows 에서는 sessions 폴더를 만들어놔야 한다. 그렇지 않으면 ErrorException in Filesystem.php 이 발생한다. linux 에서도 만들어 놔야 하는지는 모르지만, 최소한 write 권한 설정은 해줘야 할 듯 하다.
<lumen>\storage\framework\sessions

session 사용법

당연한 이야기지만 session_domain 설정이 제대로 되어 있어야 session 이 동작한다.

.env file

SESSION_DOMAIN=.example.com
APP_NAME=company_name

Controller

$session = $request->session();
$session->put('sample','hello');
echo $session->get('sample');

$allValues = $request->session()->all();
echo $allValues['_token']
// delete
$request->session()->forget('key');
$request->session()->flush();


login

참고로 SessionGuard 에만 login() 이 존재한다. 로그인을 하게 되면 user 에 맞는 session 을 set 해주게 된다.(SessionGuard::updateSession)
  • Auth::login()
  • Auth::guard('web')->login()

view




References

  1. laravel - How can I use Illuminate\Session\Middleware\StartSession::class on lumen 5.2 - Stack Overflow
  2. laravel - Enabling session in lumen framework - Stack Overflow
  3. What's the best way to start the session manually?
  4. No longer works with Lumen 5.2 · Issue #23 · esbenp/lumen-api-oauth · GitHub

[컴][생각] 프로그래머의 초과근무

초과근무 /

프로그래머의 초과근무


Stack Overflow’s 2018 Developer Survey 에서 프로그래머들이 엄청나게 많은 양의 overtime 일을 하고 있다는 것이 드러났다. 그래서 관련되서 reddit 에 댓글들이 엄청달렸다.

reddit 에서 best 댓글은 아래와 같다.



프로그래머의 초과근무는 여러모로 좋지 않다. reddit 의 댓글에 있는 글들이 수많은 안좋은 이유를 알려준다.

프로그래머가 새로운것을 찾고, 학습하는 시간도 결국 프로그래머의 일하는 시간이지만, 안타깝게도 실제로 그것을 인정받기는 쉽지 않다.

그래서 나는 저 reddit 의 댓글에 찬성한다. 정말 이 한몸 불살라서 내가 돈을 많이 벌겠다는 의지가 아니라면, 정해진 시간만 일하라고 하고 싶다. 어차피 그 이외의 시간에도 풀리지 않았던 문제나 풀어야할 문제가 머리속에서 지워지지 않아서 자신도 모르는 사이에 일하게 될 테니 말이다.

References


  1. Stack Overflow’s 2018 Developer Survey reveals programmers are doing a mountain of overtime : programming