간단히 공부하는 OAuth

이번 프로젝트 중에 OAuth를 구현하는 프로젝트가 있어 늘 궁금했지만, 그리고 늘 해야한다고 생각만 했던 OAuth에 대해 공부한 내용을 최대한 간단하고 간결하게 이야기해보려고 한다.

OAuth 1.0 ? 2.0?

왜 다들 2.0 만 사용하는지 궁금했는데, 간단히 요약하면,
2.0은 Https에게 보안을 전가 하고 인증에만 중심을 두겠다는거고,
1.0은 http던 https던 ftp던 뭐던 상관없이 (독립적으로) 인증을 하기위해 직접 보안을 신경써서 전송하겠다는 거다.

그 외의 명칭이 다르거나 다소 차이점은 있지만 가장큰 차이점은 위에서 말한 전송 방식에 대한 보안을 어떻게 신경쓰느냐 인 것 같다.

OAuth2.0 그리고 지옥으로 가는 길 과 같은 2.0은 위험하다! 라는 이야기도 있지만, 그러면 구글이 아직 까지 쓰고 있지 않을테니 여기서 가장 위험하다고 말해지는 https가 아닌 http를 사용할 경우의 위험만 신경쓰고 OAuth2.0는 https 상에서 통신 한다는 것만을 잊지 말자.

통신 순서

늘 어느 글을 가나 나오는 통신 순서다.

OAuth2 Overview | OAuth2

라고 하는데 솔직히 이것만 봐도 그리고 설명을 쭉 봐도 이해가 잘 되지 않는다.
그래서 그냥 내 나름 대로 정리해 보려고 한다.

목표와 명칭 정리

나는 내가 운영하는 사이트에 페이스북 로그인을 넣으려고 한다.
그럴때 아래와 같은 명칭을 가진다.

Resource Owner: 로그인 하는 사람이다.
Client: 내가 운영하는 사이트다.
Resource Server: 페이스북이다.
Authorization Server: 인증서버인데. 그냥 Resource Server와 통합되있다고 생각하자.

1. OAuth 준비

먼저 난 페이스북 개발자 사이트에 가서 Client id와 Client secret key를 발급 받는다.

2. 로그인 페이지에 페이스북 로그인 버튼을 추가한다.

이제 처음 들어오는 유저가 페이스북 로그인을 클릭하고,

최초 접속이니 내 서버의 Client id와 함께 해당 유저를 페이스북 OAuth 인증 페이지로 리다이렉트 한다.

늘 보던 이런거

확인을 누르면 callback URL으로 임시 패스워드[Authorization code]를 전달한다.

3. 내 서버에서 Access Token 발급 요청

서버는 임시 패스워드와[Authorization code]
내 서버의 client id, secret key를 가지고 Access Token을 발급 요청을 한다.
(혹은 Refresh token도 함께 받는다) 그리고 저장한다.

4. 내 서버에서 Access Token을 사용해 사용자 데이터에 접근한다.

발급 받은 Access Token을 사용해 사용자에 데이터에 접근할 수 있다.
그 정보로 로그인 내 서버에 로그인 시켜주면된다.

다만, 일정 시간이 지나면 Access Token이 만료되기에 Refresh Token을 사용하여 재발급 받는다.

이때 Refresh Token은 영구적으로 안별할 수 도 있고, 재발급 받을 때 마다 Refresh Token도 재발급 될 수 있다. 이는 각 사이트 정책을 따른다.

+α 이미 정보가 저장 되있으면?

그럼 위 2번에서 바로 내 서버의 callback url로 임시 패스워드가[Authorization code] 보내지고 Access Token을 가지고 혹은 갱신해서 로그인 정보를 가지고 올 수 있다.

즉 확인 버튼 누르는 과정만 없어졋다고 생각 해도 된다.


여튼 여러가지 설명이 있는데 내가 이해한 방식은 위와 같은 방식이고,
OAuth를 이해 하는데 도움이 되었으면 좋겠다.

[PHP] Namespace의 범위

TL;DR

PHP의 Namespace의 범위는 include, require의 상관없이 해당 파일에서만 영향을 끼친다.

Namespace

PHP 5.3부터 추가된 같은 이름의 함수, 클래스가 있을 때 네임스페이스로 각각 격리하여 사용할 수 있게 해주는 기능이다.

Simple example

spaceA.php

<?php

namespace A;

echo __FILE__ . ' > ' . __NAMESPACE__ . PHP_EOL;

function atest() { echo "spaceA atest function\n"; }

spaceB.php

<?php

echo __FILE__ . ' > ' . __NAMESPACE__ . PHP_EOL;

function btest() { echo "spaceB btest function\n"; }

index.php

<?php

namespace INDEX;

require('spaceA.php');
require('spaceB.php');

echo __FILE__ . ' > ' . __NAMESPACE__ . PHP_EOL;

btest();
atest();

php index.php로 php를 실행시키면 결과는 다음과 같다.

/home/silnex/test/spaceA.php > A
/home/silnex/test/spaceB.php > 
/home/silnex/test/index.php > INDEX
spaceB btest function
PHP Fatal error:  Uncaught Error: Call to undefined function INDEX\atest() in /home/silnex/test/index.php:11
Stack trace:
#0 {main}
  thrown in /home/silnex/test/index.php on line 11

require('spaceA.php') 의 결과가 출력된 1번째 줄을 보면
네임스페이스는 index.php에서 선언된 INDEX가 아닌 spaceA.php 파일에서 선언된 네임 스페이스다.

require('spaceB.php')의 결과가 출력된 2번째 줄을 보면
네임스페이스는 INDEX도 A도 아닌 아무 선언 안된 것을 볼 수 있다.
즉, 네임스페이스는 다른파일엔 영향을 끼치지 않는다는 걸 알 수 있다.

btest()의 실행 결과인 4번째 줄을 보면,
정상적으로 실행되고 있으나,
atest()의 경우 5번째줄 부터 표시된 에러가 나는것을 볼 수 있다.

이를 통해 함수가 받는 영향을 알 수 있는데,
기본적으로 Namespace가 없는 함수를 먼저 호출 하고, 만약 함수가 없다면,
현재 파일의 Namespace의 함수를 찾는 것을 확인 할 수 있다.

[SimpleDES] Simplified Data Encryption Standard-2

Simplified Data Encryption Standard (Simplified DES) Practice

Author silnex


이전 글에서 SDES에 대한 내용과 필요한 함수들에 대해서 알아 보았다.
이번엔 직접 Keygen, Encryption 및 Decryption을 해보며 SDES에 대해서 알아본다.

Key Generation

Key 1 0 1 0 0 0 0 0 1 0
P10 3 5 2 7 4 10 1 9 8 6
P8 6 3 7 4 8 5 10 9

위 함수와 Key를 사용해 subKey(k1,k2)를 생성한다.

먼저 10bit의 key인 1010000010를 함수 P10에 넣는다.
 ▶ P10(1010000010) ::= (1000001100)
P10의 결과 값을 5bit 씩 쪼개어 LS-1을 진행한 뒤 다시 하나로 합친다.
 ▶ LS-1(10000) = (00001)
        LS-1(01100) = (11000) ::= 00001 11000

subKey 1 Gen LS-1의 결과 값을 P8에 넣는다.
 ▶ P8(0000111000) ::= 10100100 (k1)

LS한 결과 값에 LS-2를 한번 더 적용한 뒤 하나로 합친다.
 ▶ LS-2(00001) = (00100)
        LS-2(11000) = (00011) ::= 00100 00011

subKey 2 Gen LS-2의 결과값을 P8에 넣는다.
 ▶ P8(0010000011) ::= 01000011 (k2)

K1 K2
10100100 01000011

Encryption

PlainText 0 1 1 0 1 1 0 1
IP 2 6 3 1 4 8 5 7
E/P 4 1 2 3 2 3 4 1
P4 2 4 3 1
IP-1 1 3 5 7 2 8 6
S0 1 0 3 2 S1 0 1 2 3
3 2 1 0 2 0 1 3
0 2 1 3 3 0 1 0
3 1 3 2 2 1 0 3

위 함수를 통해 fk를 2번 반복한다.

8bit의 PlainText를 함수 IP에 넣는다.
 ▶ IP(01101101) ::= 1110 0110
{START fk} IP의 결과 값 중 오른쪽4bit(0110)를 함수 E/P에 넣는다.
 ▶ E/P(0110) ::= 00111100
 E/P 결과 값에 subkey k1과 xor 연산을 한다.
 ▶ 00111100 ⊕ 10100100 ::= 1001 1000
k1과 Xor한 결과 값을 S-Box에 넣어 매치되는 행렬값을 구한 뒤 합친다.
 ▶ S0(11,00) = S0(3,0) = 11 (3) | S1(10,00) = S1(2,0) = 11 (3) ::= 1111
S-Box의 결과 값을 P4에 넣고 처음 IP의 결과 값 중 왼쪽4bit와 Xor 연산을한다.
 ▶ P4(1111) ::= 1111 
       1111 ⊕ 1110 ::= 0001 {END fk}
Xor의 결과 값과 처음 IP의 결과 값 중 오른쪽4bit의 순서를 바꾼다.
 ▶ SW(0001 0110) ::= {0110 0001}

SW값을 한번 더 함수 fk를 반복한다.
{START fk} ▶ E/P(0001) ::= 10000010
 ▶  10000010 ⊕ 01000011 ::= 1100 0001
 ▶ S0(10,10) = S0(2,2) = 01 (1) | S1(01,00) = S1(1,0) = 10 (2) ::= 0110
 ▶ P4(0110) ::= 1010
      1010 ⊕ 0110 ::= 1100 {END fk}
 ▶ >> {1100 0001}

두번의 fk에서 나온 결과 값을 IP-1에 넣는다.
 ▶ IP-1(1100 0001) = 01000110
이렇게 나온 결과 값 0 1 0 0 0 1 1 0가 PlainText(01101101)를 Key(1010000010)로 암호화한 CipherText(암호문)이 된다.


 

Decryption

 

CipherText 0 1 0 0 0 1 1 0
IP 2 6 3 1 4 8 5 7
E/P 4 1 2 3 2 3 4 1
P4 2 4 3 1
IP-1 1 3 5 7 2 8 6
S0 1 0 3 2 S1 0 1 2 3
3 2 1 0 2 0 1 3
0 2 1 3 3 0 1 0
3 1 3 2 2 1 0 3

위 함수를 통해 fk를 2번 반복하는데 Encryption과 과정은 동일하다.
하지만 이번엔 Decryption이기 때문에 fk에서 사용되는 key의 순서가 k2, k1순으로 사용되어야한다.

8bit의 CipherText를 함수 IP에 넣는다.
 ▶ IP(01000110) ::= 1100 0001
{START fk} IP의 결과 값 중 오른쪽4bit(0001)를 함수 E/P에 넣는다.
 ▶ E/P(0001) ::= 10000010
 E/P 결과 값에 subkey k1과 xor 연산을 한다.
 ▶ 10000010 ⊕ 01000011 ::= 1100 0001
k1과 Xor한 결과 값을 S-Box에 넣어 매치되는 행렬값을 구한 뒤 합친다.
 ▶ S0(10,10) = S0(2,2) = 01 (1) | S1(01,00) = S1(1,0) = 10 (2) ::= 0110
S-Box의 결과 값을 P4에 넣고 처음 IP의 결과 값 중 왼쪽4bit와 Xor 연산을한다.
 ▶ P4(0110) ::= 1010
       1010 ⊕ 1100 ::= 0110 {END fk}
Xor의 결과 값과 처음 IP의 결과 값 중 오른쪽4bit의 순서를 바꾼다.
 ▶ SW(0110 0001) ::= {0001 0110}

SW값을 한번 더 함수 fk를 반복한다.
{START fk} ▶ E/P(0110) ::= 00111100
 ▶ 00111100 ⊕ 10100100 ::= 1001 1000
 ▶ S0(11,00) = S0(3,0) = 11 (3) | S1(10,00) = S1(2,0) = 11 (3) ::= 1111
 ▶ P4(1111) ::= 1111
       1111 ⊕ 0001 ::= 1110 {END fk}
 ▶ >> {1110 0110}

두번의 fk에서 나온 결과 값을 IP-1에 넣는다.
 ▶ IP-1(1110 0110) = 01101101
이렇게 나온 결과 값 0 1 1 0 1 1 0 1가 CipherText(01000110)를 Key(1010000010)로 복호화한 PlainText(평문)이 된다.


이미지 출처 및 참고 자료

[SimpleDES] Simplified Data Encryption Standard

Simplified Data Encryption Standard (Simplified DES)

Author silnex


Introduce S-DES

TL; DR
바로 Example로 넘어가고 싶다면,
[SimpleDES] Simplified Data Encryption Standard Practice 로…

Padding Oracle Attack을 공부하기 위해 CBC에 대해서 공부하던 중 Block Cipher에 대해 자세히 알고 싶다는 생각이 들어,
지금은 사용되지 않지만 가장 유명한 암호화 방식인 Data Encryption Standard(DES)를 공부하게 되었다.
DES알고리즘을 학습해야하지만 일반적인 DES에서 사용되는 key인 56bit는 다소 복잡해 이해 하기가 어려워,
key가 10bit로 이루어진 Simplified DES를 통해 DES알고리즘에 대해서 학습해본다.

SDES는 기존 DES와 Key의 bit수 차이와 반복되는 Round 의 차이만 있을 뿐 알고리즘은 동일하며,
SDES의 확장을 통해 DES를 이해를 위해 만들어진 SDES인 만큼 DES의 56bit키가 왜 위험한지에 대해서도 충분이 이해 할 수 있다고 한다.

Analyze DES

SDES Scheme (위 그림에 오류가 있는데 keygen을 하는 부분에서 2번째 Shift는 Shift를 2번해주어야 한다.)

DES는 대칭키 암호이기 때문에 Key를 통해 subKey인 K1과 K2를 생성하는 Key Generation()과정, (PlainText를 Block단위로 쪼개어 암호화 하기위해서다. DES가 Block Cipher라 불리는 이유)
PlainText(평문)를 암호화하는 Encryption() 과정,
암호화된 CipherText(암호문)를 복호화 하는 Decryption()과정까지 총 3개의 과정이 필요하다.

이제 필요한 함수에(P10, P8, Shift, IP, IP-1, SW, fk, E/P, S-Box, P4 )대해서 알아보자.

Functions

Key Generation에서 사용되는 함수들

Keygen for Simplified DES

 

Function P10 

input length(or bit): 10
output length(or bit): 10

P10의 P는 Permutation(순열)의 약자로, 아래와 같은 함수로 표현된다.

P10(k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) = (k3, k5, k2, k7, k4, k10, k1, k9, k8, k6)

수식으로 표현하니 이해하기 여러울 수 도있지만, 단순히 순서를 바꾸는 역할을 할 뿐이다.
예를들어 P10(1,2,3,4,5,6,7,9,0) = (3,5,2,7,4,10,1,9,8,6) 처럼 순서만 바꾸는 역할을 한다.
다만, P10에서 사용되는 바뀌는 순서에 대한 값은 임의의 값이 아닌 SDES에서 고정적인 값이다.

P10을 표로써 표현하면 아래와 같이 표현할 수 있다.

P10
3 5 2 7 4 10 1 9 8 6

 

Function P8 

input length(or bit): 10
output length(or bit): 8

또한 P10과 같은 의미이나 10개의 인자값을 받아 8개만 선택해 출력하는 함수이다.
수식으로 표현하면,

P8(k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) = (k6, k3, k7, k4, k8, k5, k10, k9)

즉, 결과 값에 없는 k1, k2는 버려진다. 이를 표로 표현하면 아래와 같이 표현 할 수 있다.

P8
3 7 4 8 5 10 9

 

Function Shift

input length(or bit): 5
output length(or bit): 5

Shift는 BitShift연산자중에서 Left Shift를 의미하는데, 왼쪽으로 넘어간 bit는 오른쪽에서 나오게 된다.
즉, 10011(2)을 Shift 2번 이라고 한다면, 00111(2)이 되는것이다.
대게 줄여서 LS라고 하며 Shift횟수에 따라 한번이면 LS-1 두번이면 LS-2라고 한다.

수식으로 표현하자면,

LS-1(10110(2)) = 01101(2); LS-2(11011(2)) = 01111(2)

 

Encryption, Decryption에서 사용되는 함수들

XOR(⊕)은 따로 설명하지 않는다.

Simplified DES Encryption Detail

 

Function IP and IP-1

input length(or bit): 8
output length(or bit): 8

IP는 Initial and Final Permutations의 약자로, 처음과 끝에 순서를 바꾸어 주는 역할을 한다.
즉 P10 과 크게 다르지 않다. 다만 IP는 ‘역’인 IP-1 가 존재한다. 
수식으로 표현하면,

IP(k1, k2, k3, k4, k5, k6, k7, k8) = (k2, k6, k3, k1, k4, k8, k5, k7)
IP-1(k2, k6, k3, k1, k4, k8, k5, k7) = (k1, k2, k3, k4, k5, k6, k7, k8)

으로 표현된다. 즉, IP-1(IP(X)) = X란 뜻이다.
이를 간단히 표를 통해 표현하면 아래와 같다.

IP
2 6 3 1 4 8 5 7
IP-1
4 1 3 5 7 2 8 6

 

Function fk

input length(or bit): 8
output length(or bit): 8

fk에서 k는 keygen에서 생성된 key의 종류를 의미한다.
fk는 입력받은 8bit의 값을 4bit/4bit 으로 쪼개어 왼쪽bit/오른쪽bit라고 부르며 나누어 사용한다.

중요한건 오른쪽bit인데 순서데로 E/P를 거쳐 Xor후에 S0, S1로 나누어져 동작 하고,
이를 다시 P4의 넣어 출력후 왼쪽bit와 Xor한다.
말로 표현하니 이해가 힘들수도 있지만, DES에서 가장 핵심이기에 잘 알아두자.

 

Function E/P

input length(or bit): 4
output length(or bit): 8

E/P는 Expansion/Permutation의 약자로 말 그대로 확장하고 순서를 바꾼단 뜻이다.
이도 IP나 P10과 같이 순서를 바꾸는 것은 동일하지만 4자리의 bit를 8bit로 확장 한다는 점이다르다.

E/P를 수식으로 나타내면 다음과 같고,

E/P(k1, k2, k3, k4) = (k4, k1, k2, k3, k2, k3, k4, k1)

이를 표로 나타내면 아래와 같다.

E/P
4 1 2 3 2 3 4 1

 

Function S0 S1(S-Box)

S0, S1 각각 input length(or bit): 4
output length(or bit): 2

S0와 S1는 S-Box라고 불리며, 기존의 E/P, IP, P10과는 달리 행렬을 이용한 연산이지만,
그렇게 복잡한 연산은 아니다.
다만, 이를 위해선 고정된 S-box 행렬이 필요한데 두 행렬은 아래와 같다.

S0 1 0 3 2 S1 0 1 2 3
3 2 1 0 2 0 1 3
0 2 1 3 3 0 1 0
3 1 3 2 2 1 0 3

입력(4bit)에대하여 위의 행렬을 참고해 다음과 같은 연산을 진행한다.

Ex) input : 0101 1010(2) 
(구분을 위해 색을 칠했으며, E/P와 key을 xor한 8bit 입력을 4bit로 쪼개어 각각 대입하여 사용한다.)

S0(01(2),10(2)) S1(10(2),01(2)) => S0(1,2) S1(2,2) => 1, 1 => 01 01(2)

S-box를 수식으로 표현하면 다음과 같이 표현할 수 있으나 이해가 위 예제를 통해 이해가 힘들때 참고 정도로만 사용하면된다.

i = input; n = 0, 1;
Sn(i1,4,i2,3)

Function P4

input length(or bit): 4
output length(or bit): 4

P4는 기존의 IP P10과 동일하게 4자리의 bit를 순서를 바꾸어 주는 역할을 한다.
수식으로 표현하면 다음과 같고,

P4(k1, k2, k3, k4) = (k2, k4, k3, k1)

표로 표현하면 아래와 같다.

P4
2 4 3 1

 

Function SW

input length(or bit): 8
output length(or bit): 8

SW는 단순히 왼쪽 4bit와 오른쪽4bit를 바꾸어주는 역할을 한다.
간단한 과정이니 수식으로만 표현하겠다.

SW(k1, k2, k3, k4, k5, k6, k7, k8) = (k5, k6, k7, k8, k1, k2, k3, k4)


이로써 S DES에서 암호화, 복호화와 키 생성에 필요한 함수를 모두 알아보았다.
이를 통해 다음 글에선Key를 직접 생성해 보고 Encryption과 Decryption을 직접 해본다.

 


이미지 출처 및 참고 자료

http://homepage.smc.edu/morgan_david/vpn/C-SDES.pdf