Hyper Text Transfer Protocol 'Secure' Socket layer의 줄임말이다.
HTTP에 secure이 붙어서 더 안전한 녀석이다.
2. 작동방식으로 보는 HTTP vs HTTPS
HTTP는 문자 형식 그대로 정보를 보낸다. 그것이 비밀번호 같은 민감한 정보가 있다고 해도 그대로 보낸다.
중간에 그것을 가로채면 그것을 바로 뺏겨버린다.
HTTPS는 그것을 '해싱' 하여 알 수 없는 텍스트로 바꿔서 정보를 보낸다.
그것을 서버에서 해석해서 알아듣는다. 중간에 정보를 뺏겨도 해석할 방법을 모르기 때문에 상관없다.
그리고 특별한 기관에서 '인증서'를 받은 곳에서만 이 HTTPS를 사용할 수 있기 때문에 비슷하게 만들어놓은 피싱 사이트인지를 확실히 알 수 있어서 신뢰하지 않는 사이트에서는 개인정보와 관련된 것들을 사용하지 않고 해킹을 막을 수 있다.
그리고 확실하게 프로토콜 부분에 HTTP 형식인지, HTTPS 형식인지를 명시해 줘야 한다. 아니면 올바르지 않은 형식으로 정보를 읽어 오게 되므로 안된다.
기밀성(privacy) : 제삼자가 중간에서 정보를 가로챌 수 없게 암호화함
무결성(integrity) : 정보가 중간에 조작되지 않는다.
이 둘을 잘 지키고 있기 때문에 우리는 HTTPS가 더 안전하다고 말할 수 있다.
3. 인증서
앞서 말했듯이, 브라우저가 접속한 서버가 정상적인 우리가 의도했던 서버라는 것을 보장하는 인증이다.
인증된 기관(CA, Certificate Authority)에서 인증서를 발급하고, 그 인증기관들은 많지 않다. 그래서 받은 인증서를 인증기관들에게 확인하여 확실한 사이트 임을 보증하게 되는 것이다.
주소창 위에 '자물쇠' 마크를 눌러보면 인증서의 상태를 확인할 수 있다. 티스토리 같은 경우 SSL Server Certificate라고 되어있다.
4. 어떻게 암호화를 할까?
이들은 서로 각각의 '키'를 가지고 있다.
이 키를 이용해 암호화를 하게 되고 키의 종류에 따라 해석하는 방식이 달라진다.
대칭키
메시지를 보내는 쪽과 받는 쪽, 둘 다 똑같은 키를 가지고 있어서 해석하는 방식을 공유하여 암호화된 메시지를 해석해서 사용한다.
이때, 키만 노출되지 않는다면 중간에 메시지를 가로채더라도 해석할 수 없다.
하지만 결국, 한 번은 키를 보내는 쪽에 줘야 하기 때문에 이때 가로채면 막을 수가 없는 단점이 있다.
비대칭키
두 개의 키를 가지고 해석을 하게 된다. 하나는 '공개키'로 이것은 누구나 볼 수 있으며 사용자가 사용하게 된다. 이는 모두에게 공개되어 있기 때문에 이 키 하나만 가지고는 아무것도 할 수 없다.
하나는 '개인키'로, 서버에서 가지고 있다. 공개키로 암호화된 메시지는 서버에서 개인키를 이용해야만 다시 복호화할 수 있다.
인증서와 같은 정보들은 서버에서 개인키로 암호화되어 사용자에게 보내지고, 이도 마찬가지로 개인키로 암호화된 내용은 사용자의 공개키로만 복호화가 가능하다. 그래서 인증서가 올바르지 않은 사이트에서의 정보를 해석하려고 하면 안 될 테니까, 우리는 안전한 사이트에서만 사용할 수 있다.
4. Hashing
메시지를 암호화하는 알고리즘이다. 항상 고정길이를 리턴하고, 항상 input과 output이 일정하다. 즉, 순수 함수이다.
그리고 해싱된 메시지는 복호화가 키를 모르고서는 사실상 불가능하다.
물론 너무 간단하고 쉬운 경우는 이미 해싱된 결과들이 저장되어 해석할 수 도 있다. 이것을 레인보우 테이블이라고 한다.
예를 들어, 1234, password 같은 걸로 비밀번호를 정해놓으면 아무리 암호화 해 놔도 다 뚫린다는 것이다.
하지만 이는, 'Salt'를 이용하게 되면 더욱 안전하게 만들 수 있다.
원래 있던 패스워드에서 자신만이 아는 문자를 추가해서 더 욱 복잡한 해쉬를 만들어서 서버는 솔트 값을 알고 그것까지 포함해서 해석하게 된다. 사용자마다 각기 다른 솔트 값을 가지고 있다면 더욱 좋다.
5. 결국, 어떻게 메시지를 주고받나요?
handshake
가장 먼저, 서버를 클라이언트가 신뢰하지 못하는 단계에서 클라이언트가 무작위의 데이터를 보낸다.
그것의 응답으로 서버에서 생성된 무작위 데이터와 인증서를 보낸다.
클라이언트는 받은 인증서를 브라우저에 내장된 CA들의 정보와 대조하며 신뢰할 수 있는 서버인지를 확인한다.
브라우저의 인증서 확인
인증서에 있는 공개키를 알맞은 CA의 개인키로 복호화한다.
이때 정상적인 서버에서 받은 인증서라면, 복호화가 올바르게 된다.
하지만 아니라면 신뢰할 수 없는 사이트가 되는 것이다.
다시 서버로
이제 비대칭키와 대칭키를 같이 사용한다.
대칭키를 클라이언트와 서버는 공유하게 된다. 이때, 이 대칭키를 공유하는 방식이 비대칭키를 이용한 방식이다.
만약, 계속 비대칭키 방식만 사용한다면 사이트를 이용할 때 주고받는 수많은 데이터들을 모두 비대칭 방식으로 만들면 시간이 너무 오래 걸린다.
아까. handshake 단계에서 만든 무작위 데이터, 받은 거, 자기가 만든 것 둘을 합쳐서 임시로 키를 만든다.
이 임시키를 서버로 공개키로 보내진다. 이렇게 하면 양쪽에 동일한 대칭키를 만들게 된다.
6. 쿠키
사이트를 방문할 때, 내 브라우저에 저장되는 작은 텍스트 정보들이다.
물론 나한테 저장된 정보기 때문에 정보를 수정하거나, 누군가에게 탈취당할 위험도 있다. 그래서 민감한 정보는 넣지 않는다.
정말 중요한 정보들은 서버 측의 '세션'에서 관리하게 된다.
이때, 사용자마다 작은 임시키를 쿠키에 넣어서 준다.
이 사용자가 브라우저를 통해 사이트의 페이지들을 탐색할 때, 서버가 그 키를 보고 그 유저가 누구인지 알 수 있다.
그래서 로그인이 안된 상태로 장바구니에 많은 아이템들을 담아 놓고 로그인을 하면 그대로 아이템들이 남아 있는 것이다!
아이디 저장, 자동 로그인 같은 기능도 똑같다!
그래서 쿠키를 지우면 자동 로그인이 풀리는 것이다.
이때, '캐시'를 이용하면, 사용자가 자주 사용하는 데이터를 캐시에 담아, 가져오는데 비용이 많이 드는 정보를 사용자의 컴퓨터나 서버에 저장하여 그 비용을 줄일 수 있다.
SQL은 일정한 형식을 가지고 데이터 베이스에 데이터를 저장하지만, NoSQL은 그 형식을 없애어서 더 자유롭게 자료를 저장할 수 있다는 것에 가장 큰 차이점을 가진다.
그렇다고 한쪽이 무조건 좋다 라고 할 수 없다. 상황에 따라 맞는 방법을 사용하게 된다.
2. 둘의 차이점
수평적 확장성 vs 수직적 확장성 :
수평적 확장성 => NoSQL: 서버의 갯수를 늘리면 무한대로 저장공간이 늘어날 수 있고, 응답의 속도도 크게 떨어지지 않는다. 그래서 큰 프로젝트를 할 때 더욱 어울린다. 물론 그만큼 사용되는 비용도 많이 늘어난다.
수직적 확장성 => SQL: 하나의 노드에서 모든 것을 처리하게 된다. 그래서 계속 한 곳에 쌓인다고 표현하는 것 같다. 고성능의 장비 하나로 모든 것들을 처리하게 되기 때문에 비용은 적다. 하지만 처리속도에 그래도 무리가 간다.
쿼리 언어의 유무
기본적인 언어는 비슷하게 사용된다. 하지만 NoSQL같은 경우, Relation Data 즉, 다양한 행과 열로 이루어진 테이블들이 계속해서 JOIN 되어 조밀하게 연결되어 있는 경우, 정확한 틀이 없어서 유지보수를 하기 복잡해진다.
스키마의 유연성
앞에서도 말 했듯이, 정확한 형태의 스키마를 이용해 데이터를 저장하게 되는 SQL과 더 자유롭게 스키마를 형성할 수 있는 NoSQL의 스키마의 유연성이 가장 큰 차이를 보인다.
간단하게 말하면 NoSQL은 아무 JSON 문서도 다 데이터 베이스에 넣어버릴 수 있다. 모든 오브젝트 형식을 다 넣을 수 있기 때문이다. 이것이 자유다!
3. JSON vs BSON
JSON형식은 우리가 알고 있는 그 형식이다. {}로 묶은 각각의 필드들이 문자열처럼 따옴표로 이루어져 있고, 그에 대한 값을 : 뒤에 적어주며, 쉼표로 각각의 필드들을 구분해 준다.
{
"id": 1,
"name": "Tom"
"age": 22
}
BSON은 JSON 처럼 텍스트 형태가 아니라 여러 가지 다양한 데이터 타입도 다 사용이 가능한 형식이다. JSON보다 읽는 속도가 빠르다. 하지만 JSON처럼 인간이 읽어서 내용을 파악하는 것은 무리가 있다.
{"hello": "world"} →
\x16\x00\x00\x00 // total document size
\x02 // 0x02 = type String
hello\x00 // field name
\x06\x00\x00\x00world\x00 // field value
\x00 // 0x00 = type EOO ('end of object')
MongoDB에서는 둘 다 데이터 베이스에 넣을 수 있다. 하지만 MongoDB 내부에서는 BSON 형식으로 사용 중이다.
4. MongoDB
MongoDB는 NoSQL의 모델 중 하나이며, DOCUMET를 이용한 방식으로 데이터 베이스에 접근한다.
mySQL처럼 비슷한 명령어들이 있으며, 몇 가지는 다르다.
5. MongoDB에서 주로 사용하는 명령어
mongo : 인스턴스 활성화, 간단하게 시작할 때 사용한다고 생각하면 된다.
use 데이터 베이스 이름 : 사용할 데이터 베이스를 결정한다.
show dbs : 데이터 베이스의 목록을 본다.
db.stats() : 데이터 베이스의 상태를 본다.
db.shutdownServer() : 데이터 베이스를 끈다.
db.logout() : 데이터 베이스에서 로그아웃 한다.
db.createCollection(컬렉션 이름) : 컬렉션을 생성한다.
db. 컬렉션 이름.insert({json형식의 데이터}): 컬렉션에 데이터를 넣는다. => 만약 컬렉션을 만들지 않았어도 상관없다. 없으면 만들어 넣는다!
db. 컬렉션 이름.find(): 컬렉션을 확인한다.
db. 컬렉션 이름.remove({json형식에 맞게 적은 삭제할 document의 내용})