티스토리 뷰
오늘 소개 할 암호는 비즈네르 암호(vigenere cipher) 입니다.
비즈네르 암호는 다표식 암호 중에서도 반복키 암호(repeating-key cipher)입니다.
반복키 암호란 단어나 구로 된 키워드(keyword)를 필요한 만큼 반복해
key로 사용하는 암호입니다.
암호문은 모듈로 26에 대해 평문 숫자와 키 숫자를 더한 값으로 나타낼 수있습니다.
평문이 "computer" 키워드가 "dog"인 비즈네르 암호의 예를 살펴봅시다.
키워드 | d | o | g | d | o | g | d | o |
키워드숫자 | 4 | 15 | 7 | 4 | 15 | 7 | 4 | 15 |
평문 | c | o | m | p | u | t | e | r |
평문 숫자 | 3 | 15 | 13 | 16 | 21 | 20 | 5 | 18 |
암호문 | g | d | t | t | j | a | i | g |
암호문숫자 | 7 | 4 | 20 | 20 | 10 | 1 | 9 | 7 |
위의 표처럼 키워드는 필요한 만큼 반복되고 암호문은 모듈러 26에 대해
key와 평문의 숫자를 더한 값입니다.
다음은 복호화에 대해 생각해봅시다.
반복키 암호의 주기를 알게되면 같은 키를 사용하는 암호문끼리의 빈도 분석이 가능해집니다 !
암호 주기를 l 문자의 갯수를 n이라고 해봅시다.
각 l열에 n/l 개의 문자가 있는 배열을 생각할 수있습니다.
같은 열에서는 같은 키로 암호화했기 때문에 동시발생지수가 약 0.066일 것이고
무작위로 서로 다른 두 열을 선택하고 각 열에서 문자를 하나씩 뽑는다면
동시발생지수는 약 0.038일 것입니다.
따라서 전체 동시발생지수는 다음과 같이 계산 할 수 있습니다.
주기 l | 1 | 2 | 3 | ... | 10↑ |
동시발생지수 | 0.066 | 0.052 | 0.047 | ... | 0.038 |
n의 값이 클때 주기 l에 따른 대략의 동시발생지수의 값으로 주기(l)을 추측할 수도 있습니다.
또는 직접 구한 동시발생지수와 위의 식을 같다고 식을 만든 후
l에 대한 방정식을 풀어 대략의 l의 값을 추측할 수도 있습니다.
주기를 구하는 다른 방법에는 카지스키 테스트(kasiski test)가 있습니다.
카지스키 테스트는 반복되는 문자열을 찾는 것에서 출발합니다.
반복 문자열의 각각 첫 문자부터 다음 반복이 나타나기까지 문자의 갯수를 셉니다.
반복되는 문자열의 각격의 공약수가 암호 주기가 될 가능성이 높다고 할 수 있습니다.
왜냐하면 평문에서 반복되는 부분이 반복되는 키를 기준으로 같은 위치에 오면
암호문도 반복되기 때문입니다.
물론 반복되는 문자열에는 반복되는 키가 아닌 우연의 경우가 있을 수도 있습니다.
따라서 어떤 간격을 포함했을 때 주기가 1이 나온다면 그 간격은 검사에 포함하지 말아야 합니다.
같은 key를 통해 암호화된 암호문은 일반 텍스트와 같은 빈도를 가지고 있기 때문에
주기를 찾은 후에는 빈도분석법을 통해 key를 찾을 수 있습니다.
inputText = []
cipherText = []
coin = [0 for i in range(26)]
def modulo(a,b):
a = a % b
return a
def vigenere(inputText,key):
textLen = len(inputText)
keyLen = len(key)
for i in range (0,textLen):
val = modulo((ord(inputText[i]) - ord("a") + 1) + (ord(key[modulo(i,keyLen)]) - ord("a") + 1),26)
if(val == 0) :
cipherText.append('z')
else:
cipherText.append(chr(val + ord("a") - 1))
def analysis(inputText):
textLen = len(inputText)
for i in range(0,textLen):
index = ord(inputText[i]) - ord("a")
coin[index] += 1
value = 0
for i in range(0,26):
value += pow(coin[i]/textLen,2)
return value
def textPrint(text):
textLen = len(text)
for i in range(textLen):
print(text[i],end='')
if __name__ == "__main__":
inputText = input("enter plainText : ")
inputText = inputText.lower()
inputText = inputText.replace(" ","")
textLen = len(inputText)
key = input("enter a key : ")
coincidence = analysis(inputText)
print("index of coincidence is " + str(coincidence))
vigenere(inputText,key)
print("cipher text : ",end='')
textPrint(cipherText)
비즈네르 암호를 생성하는 코드와
동시발생지수를 계산하는 코드를 작성해 보았습니다.
동시발생지수를 통해서 비즈네르 암호의 주기를 추측해 볼 수 있을 것입니다.
오늘도 긴글 읽어주셔서 감사합니다.
부족하거나 틀린부분은 알려주시면 감사하겠습니다.
'암호론' 카테고리의 다른 글
[암호론] 8. DES(Data Encryption Standard), 현대암호, 블록암호 (0) | 2020.11.03 |
---|---|
[python] 7. 전치암호 (transposition cipher) (0) | 2020.10.30 |
[암호론]5. 동음이의 암호, 동시발생지수 (0) | 2020.09.30 |
[python] 4. 힐 암호(Hill cipher) (0) | 2020.09.28 |
[python] 3.아핀 암호(affine cipher) (0) | 2020.09.20 |
- Total
- Today
- Yesterday
- 파이썬 비동기
- 비대칭키암호
- 파이썬 문법
- 전치암호
- Quantum Computing
- thread
- 양자컴퓨터
- 양자컴퓨팅
- Encrypted Traffic Analysis
- 암호론
- ACM Computing survey
- 파이썬
- 동시발생지수
- 파이썬암호
- python
- systemhacking
- 파이썬문법
- 덧셈암호
- Quantum entanglement
- wechall
- pythonic
- Qiskit
- 복호화
- 시저암호
- Cryptography
- 암호화
- 곱셈암호
- 대칭키암호
- 공개키암호
- ETA 프로젝트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |