프롤로그
아...여기 파트 그냥 노가다라 개귀찮다
카이사르
로마황제 율리우스 카이사르가 만든 암호문으로써, 모든 알파벳 문자를 일정한 크기만큼 이동시키고, 그 문자로 지환하여 만든다.
A | B |
B | C |
C | D |
D | E |
1칸씩 뒤로 밀려서 만들어진 것을 알 수 있다.
A LOT OF THINGS OCCUR EACH DAY
위 규칙을 적용했을 때 해당 문장은
B MPU PG UIJOHT PDDVS FBDI EBZ
로 알아보기 힘든 문장이 되었다.
구현
A~Z까지를 0~25의 숫자로 맵핑한다.
A->0, B->1, C->2...
여기서 내가 몇 칸 이동할 것인지를 변수 K 라고 두고, 현재의 문자 인덱스를 I라고 했을 때 인코딩 된 값은 (I+K) % 26이다.
카이사르 암호 도구를 구현하는 핵심은 카이사르 문자변환식인데, 이를 표현해주는 도구는 암호디스크이다.
코드
ENC = 0;
DEC = 1;
def makeDisk(key):
keytable = map(lambda x: (chr(x+65), x), range(26))
key2index = {}
for t in keytable:
alphabet, index = t[0], t[1]
key2index[alphabet] = index;
# print(key2index);
if key in key2index:
k = key2index[key];
else:
return None, None
enc_disk = {}
dec_disk = {}
for i in range(26):
enc_i = (i+k)%26
enc_ascii = enc_i + 65
enc_disk[chr(i+65)] = chr(enc_ascii);
dec_disk[chr(enc_ascii)] = chr(i+65)
return enc_disk, dec_disk
def caesar(msg, key, mode):
ret=''
msg = msg.upper()
enc_disk, dec_disk = makeDisk(key)
if enc_disk is None:
return ret
if mode is ENC:
disk = enc_disk
if mode is DEC:
disk = dec_disk
for c in msg:
if c in disk:
ret+=disk[c]
else:
ret+=c;
return ret;
def main():
plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "F"
print("Original : \t%s" %plaintext.upper());
ciphertext = caesar(plaintext, key, ENC);
print("Caesar Cipher :\t%s" %ciphertext);
deciphertext = caesar(ciphertext, key, DEC);
print("Deciphered:\t%s" %deciphertext);
if __name__ == "__main__":
main();
실행결과
Original : ABCDEFGHIJKLMNOPQRSTUVWXYZ
Caesar Cipher : FGHIJKLMNOPQRSTUVWXYZABCDE
Deciphered: ABCDEFGHIJKLMNOPQRSTUVWXYZ
key 값 F인 것을 확인하면 첫번째 글자가 A에서 F까지 5칸 뒤로 (A-> b, c, d,e, f) 간 것을 확인 할 수 있고, 나머지 문자들도 5칸씩 뒤로 옮겨진 것을 확이할 수 있다.
코드 분석
keytable = map(lambda x: (chr(x+65), x), range(26))
key2index = {}
for t in keytable:
alphabet, index = t[0], t[1]
key2index[alphabet] = index;
# print(key2index);
keytable로 (A, 0), (B, 1) ... 이런식으로 만들고 이걸 딕셔너리화 하는 과정이다.
if key in key2index:
k = key2index[key];
else:
return None, None
키 값에 따라서 몇 칸 옮길 지 정하는 거고, 키값이 유효하지 않으면 그냥 None 처리 때려버린다
enc_disk = {}
dec_disk = {}
for i in range(26):
enc_i = (i+k)%26
enc_ascii = enc_i + 65
enc_disk[chr(i+65)] = chr(enc_ascii);
dec_disk[chr(enc_ascii)] = chr(i+65)
return enc_disk, dec_disk
key 값에 따라서 key 값 만큼 이동한 것을 디스크에 저장하는 것이다.
암호화 디스크, 복호화 디스크 둘 다 설정해놓는다.
def caesar(msg, key, mode):
ret=''
msg = msg.upper()
enc_disk, dec_disk = makeDisk(key)
if enc_disk is None:
return ret
if mode is ENC:
disk = enc_disk
if mode is DEC:
disk = dec_disk
msg 를 대문자로 전부 바꿔놓고, mode 에 따라서 암호화를 할지, 복호화를 할지 정한다
for c in msg:
if c in disk:
ret+=disk[c]
else:
ret+=c;
return ret;
그 메시지를 이제 암호화/복호화 하는 과정이다.
그 외 나머지들은 뭐...파이썬 기본 문법인데 거의 안 쓰는 것들이라서 그냥 넘어가겠다.
아핀 암호
카이사르 암호의 암호키 개수는 모두 26개이므로, 26개 암호키에 대해 모두 적용해보면 반드시 암호문을 해독할 수 있다.
아핀 암호는 카이사르 암호의 변형으로 암호키의 개수를 늘린 암호화 방법이다.
기존에 Enc(i) = (k+i)%26 을 만족했더라면, 이 아핀 암호는
End(i) = (k1*i + kw) %26을 만족한다. 이 때 k1은 26과 서로소인 수(1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25) 이고, k2는 0~25 사이의 수이다. 즉 아핀 암호의 개수는 카이사르보다 12배 더 많은 312개의 암호키를 가지고 있다.
코드
ENC = 0;
DEC = 1;
def makeDisk(k1, k2):
enc_disk = {}
dec_disk = {}
for i in range(26):
enc_i = (i*k1+k2)%26
enc_ascii = enc_i + 65
enc_disk[chr(i+65)] = chr(enc_ascii);
dec_disk[chr(enc_ascii)] = chr(i+65)
return enc_disk, dec_disk
def affine(msg, key1, key2, mode):
ret=''
msg = msg.upper()
enc_disk, dec_disk = makeDisk(key1, key2)
if enc_disk is None:
return ret
if mode is ENC:
disk = enc_disk
if mode is DEC:
disk = dec_disk
for c in msg:
if c in disk:
ret+=disk[c]
else:
ret+=c;
return ret;
def main():
plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key1, key2 = 3, 5
print("Original : \t%s" %plaintext.upper());
ciphertext = affine(plaintext, key1, key2, ENC);
print("Affine Cipher :\t%s" %ciphertext);
deciphertext = affine(ciphertext, key1, key2, DEC);
print("Deciphered:\t%s" %deciphertext);
if __name__ == "__main__":
main();
카이사르에서 살짝 변형되었다.
실행결과
key1 = 3, key2 = 5일때
Original : ABCDEFGHIJKLMNOPQRSTUVWXYZ
Affine Cipher : FILORUXADGJMPSVYBEHKNQTWZC
Deciphered: ABCDEFGHIJKLMNOPQRSTUVWXYZ
에필로그
2024-1-13 아핀내용 추가
'보안 스터디 > 암호학' 카테고리의 다른 글
[암호학] 암호화 해킹 #6 (AES 및 구현) (0) | 2024.01.18 |
---|---|
[암호학] 암호화 해킹 #5 (3DES 및 구현) (1) | 2024.01.18 |
[암호학] 암호화 해킹 #4 (대칭키 암호, Symmetric-key Cryptography) (0) | 2024.01.17 |
[암호학] 암호화 해킹 #3 (전치 암호 도구 만들기) (5) | 2024.01.14 |
[암호학] 암호화 해킹 #1 (간단한 암호 도구 만들기 -1) (3) | 2024.01.09 |