오늘은 암호화 알고리즘중에 AES라는걸 포스팅해보려고 한다. 당당하게 쓰기는 하지만, 이번에 처음으로 암호알고리즘을 배우고 써보는 것이니 잘못된 점이 있을 수도 있다. 우선 개념을 먼저 몇 개 알아야한다.
대칭 키 암호는 암호화 알고리즘의 한 종류로, 암호화와 복호화에 같은 암호 키를 쓰는 알고리즘을 의미한다.
AES는 대칭 키의 종류로 암호화와 복호화에 같은 키를 사용한다. 이는 보안상 문제가 있기에 보완한 것이 공개(비공개) 키 알고리즘이다.
공개 키 암호는 암호화 알고리즘의 한 종류로, 공개 키와 비공개 키로 암호화와 복호화에 다른 키를 쓰는 알고리즘을 말한다.
이 공개 키 암호는 어떤 키로 암호화를 하느냐에 따라 방식이 달라진다.
공개 키로 암호화를 하는 경우에,
상대방의 공개 키로 암호화한 데이터를 보내면, 상대방은 자신의 비공개 키로 복호화를 한다.
공개 A 키로 암호화를 하면, 비공개 B 키로 복호화
비공개 B 키로 암호화를 하면, 공개 A 키로 복호화
DES를 대체한 암호 알고리즘이며 암호화와 복호화 과정에서 동일한 키를 사용하는 대칭 키 알고리즘이다.
S-Box(Substitution Box)는 암호키와는 별개로 AES 알고리즘의 편의를 위해 만든 16*16의 테이블이다.
설명하기로는, 모든 입력에 대한 SubBytes 연산을 계산한 테이블이라한다.
사실이든 아니든, AES에서 암호키와 동일할 정도로 중요하다.
테이블의 값은 다음과 같다.
SubBytes에서 치환하는 방법은 간단하다.
예를들어 값이 0X7a라면 7와 a를 분리하고, 7를 행에, a를 렬에 넣고 만나는 곳이 SubBytes 연산의 결과가 된다. 위의 그림으로 예를들면 0xda가 연산의 결과이다.
코드는 다음과 같다.
for (i = 0; i < 4; i++) { x = plan_text[i] >> 4;
y = plan_text[i] - (x << 4);
plan_text[i] = S_BOX[x][y];
}
int tmp;
for (int i = 0; i<4; i++) {
for (int j = 4 - i; j < 4; j++) {
tmp = plan_text[i][0];
for (int k = 0; k < 4 - 1; k++) {
plan_text[i][k] = plan_text[i][k + 1];
}
plan_text[i][3] = tmp;
}
}
unsigned char a[0x04], b[0x04], h;
for (int i = 0; i<4; i++) {
for (int j = 0; j<4; j++) { a[j] = plan_text[j][i]; h = (unsigned char)((signed char)plan_text[j][i] >> 7);
b[j] = plan_text[j][i] << 1;
b[j] ^= 0x1b & h;
}
plan_text[0][i] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1];
plan_text[1][i] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2];
plan_text[2][i] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3];
plan_text[3][i] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0];
}
0 | 1 | 2 | 3 |
4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 |
for(i = 0 ; i < 3 ; i ++)
TempKey[j] = CipherKey[i + 1][3];
TempKey[3] = CipherKey[0][3];
그럼 TempKey는 다음과 같이 된다.
for (i = 0; i < 4; i++) { x = tmp2[i] >> 4;
y = tmp2[i] - (x << 4);
TempKey[i] = S_BOX[x][y];
}
for (i = 0; i<4; i++) {
tmp[i][0] = CipherKey[j][0] ^ tmp2[j] ^ R_Con[j][0];
}
그 다음부터는 이전에 연산한 렬과 XOR 연산을 하면 된다.
for (j = 0; j<4; j++) {
for (k = 1; k<4; k++) {
tmp[j][k] = CipherKey[j][k] ^ tmp[j][k - 1];
}
}
이를 위의 알고리즘 순서도의 것과 같이 적절히 반복시키면 암호화가 완성된다.
복호화는 다음 포스팅에서 쓰겠다. 다만, 순서도에서도 볼 수 있듯이 단순히 역순에 불과하다.어셈블리를 처음부터 이해하자 -1- (0) | 2019.01.13 |
---|---|
UML을 살펴보자 (0) | 2019.01.13 |
std::tuple을 알아보자. (0) | 2018.04.26 |
Lambda (람다) (0) | 2018.04.25 |
함수 포인터로 함수명 변경하기 (완결) (0) | 2018.04.24 |
댓글,
Lowpoly
게임 서버 프로그래머 지망생