기본 콘텐츠로 건너뛰기

추천 가젯

무차별 암호 대입 공격(Brute Force)란?

  무차별 암호 대입 공격이란 무차별 암호 대입 공격은 여러 시도를 통해서 비밀번호나 암호화 키를 알아내는 공격이다. API 키와 SSH 로그인 정보를 해킹하는 데 무차별 암호 대입 공격이 사용된다. 무차별 암호 대입 공격은 웹사이트의  로그인 정보를 노리는 봇이지뭐. 마치 비밀번호를 돌려서 사용하는 자물쇠처럼, 0000부터 9999까지 모든 경우의 수를 대입하는 것과 같다. 지능적이 아닌 무식하게 올바른 비밀번호 조합을 찾을 때까지 다양한 문자 조합을 시도한다.  무차별 암호 대입 공격의 장점과 단점 무차별 암호 대입 공격의 가장 큰 장점은 시간이 충분하다면 무조건 효과가 있다는 것이다. 전 세계에 존재하는 모든 비밀번호 기반 시스템과 암호화 키는 무차별 암호 대입 공격으로 해킹할 수 있다. 반면에 무차별 암호 대입 공격은 목표를 달성하기 위해 가능한 문자 조합을 모두 시도해야 하는 경우도 있기 때문에 속도가 매우 느리다 이러한 단점은 문자 개수가 증가할수록(비밀번호가 길어질수록) 커진다. 예를 들어, 4자리 자물쇠의 경우의 수는 0000부터 9999까지 총 1000개인 반면, 3자리 자물쇠는 1000개, 2자리 자물쇠는 100개이다. 만약 초당 1500만 개의 키를 무차별 대입할 때, 아래 이미지와 같이 해킹하는 데 시간을 알 수 있다. 영어 대소문자(a-Z), 숫자(0-9), 특수문자(~!@#$%^&*()_+|`-=\;':",./<>?[]{})를 모두 사용한다면 각 문자당 존재할 수 있는 경우의 수는 52+10+32 = 94이다. 비밀번호가 8글자라면 94 8  개 (6.1 X 10 10 개 정도), 13글자라면 94 13 개   (4.7 X 10 25 개 정도)로 커진다. 문자열의 길이가 충분히 길다면 무차별 대입 공격자가 비밀번호를 알아내는 데 오랜 시간이 걸린다. 무차별 암호 대입 공격을 막는 방법 인증 시스템을 개발할 때, 한 IP에서 너무 많은 로그인 실패가 발생하는 ...

Base64 이론과 파이썬 예제

BASE64

개요

우리는 데이터를 처리할 때, 문자열(ASCII) 데이터를 사용하기도 하고 이진(Binary)데이터를 사용하기도 한다.
문자열 데이터든, 이진 데이터든, 최종적으로 컴퓨터는 이진 데이터로 변환해 처리하지만, 이진 데이터는 사람이 읽기 힘들고, 문자열을 주로 전송하는 프로토콜(SMTP, HTTP 등)에서 원활한 작동이 일어나지 않을 수 있다.
따라서 이진 데이터를 문자열 데이터로 변환하는 과정이 필요하다.

이 과정에서 이진 데이터를 16진수(HEX)로 변환하는 방법이 고안되었다.  
예를 들어, '01000101    00110001    01001100'이라는 데이터가 있다.
이 이진 데이터는 사람이 읽기도 힘들고, 무슨 데이터를 뜻하는지 확인하기 어렵다.
따라서 이 데이터를 표기할 때 10진수나 16진수를 이용하여 표현한다.

0

1

0

0

0

1

0

1

0

0

1

1

0

0

0

1

0

1

0

0

1

1

0

0

4

5

3

1

4

C

0x45

0x31

0x4C


010001010011000101001100 -> 45 31 4C
위와 같이 3바이트에 해당하는 내용을 단 여섯 문자로 표현할 수 있으며, 
16진수의 표기범위인 0~F를 직관적으로 이해할 수 있기에 파일 데이터를 분석할 때 주로 HEX 표기를 사용한다.

다만, 이렇게 Binary를 HEX로 변환하는 것은, 데이터의 분석을 조금 더 쉽게 하기 위함일 뿐이지, Binary 데이터를 문자열로 변환하는 목적으로는 잘 사용되지 않는다.
그러면 어떻게 Binary 데이터를 문자열로, 그것도 효율적으로 바꿀 수 있을까.


ASCII

바로 Binary 데이터와 ASCII 문자를 서로 연결하는 사전을 만들어서, 해당 사전에 맞게 Binary 데이터를 ASCII 문자로 변환한다. 이전의 HEX 표기처럼 특정한 패턴의 Binary 데이터를 ASCII 문자에 대칭시키는 것이다.
다만 이러한 방법을 생각해 내도 문제가 발생한다. 1바이트는 256개의 값을 가질 수 있고, ASCII 코드는 128개의 값을 가진다. 그것도 일부 문자들은 unprintable control code로, 실제 출력할 수 있는 문자가 아니라 운영체제 등을 제어하는 기능을 위해 존재하기 때문에, 실제로 사용할 수 있는 문자는 128개보다 훨씬 적다.
따라서 Binary 데이터와 ASCII 문자를 연결하는 사전에는 실제로 출력할 수 있는 문자, 그리고 각종 통신 프로토콜에서 문제없이 동작할 수 있는 문자를 사용해야 한다.
그렇게 사용할 수 있는 문자는 대문자 'A'부터 'Z'까지, 소문자 'a'부터 'z'까지, 숫자 '0'부터 '9'까지,  그리고 '+'와 '/'가 있다. 이렇게 총 64개의 문자를 사용하여 Binary 데이터를 표현한다.

Binary - ASCII 사전

이제 Binary 데이터를 ASCII 코드로 변환할 차례다. 하나 문제가 있다면, 1바이트는 2^8개의 값을 가지고, 위에서 정한 ASCII 문자들은 2^6개인 것이다.  이에 대한 해결은 간단한데, 8비트짜리 바이트 3개(24비트)를 6비트 4개(24비트)로 쪼개어, 이를 위에서 정한 문자 4개로 표현하는 것이다. 그리고 남은 공간에는 '=' 문자로 채우게 된다.
아래는 Binary 데이터를 ASCII Character로 표기하는 사전이다. 이 사전이 있다면 Binary 데이터를 ASCII 문자로 변환할 수 있고, 그 반대도 가능하다.
Encoding and Decoding Base64 Strings in Python - GeeksforGeeks


Binary - ASCII 인코딩, 디코딩

위의 개요에서 살펴본 '010001010011000101001100' Binary 데이터를 ASCII 문자로 변환해보자. 먼저 3바이트를 6비트짜리 4개 묶음으로 나눈다.


0

1

0

0

0

1

0

1

0

0

1

1

0

0

0

1

0

1

0

0

1

1

0

0

010001

010011

000101

001100


그리고 나누어진 6비트짜리 묶음을 위 사전을 참고해 각각 치환한다.

010001

010011

000101

001100

R

T

F

M


결과는 'RTFM'으로, 성공적으로 인코딩이 완료되었다. 역순으로 진행하면 디코딩까지 할 수 있다.

파이썬 예제

1. 파일을 Base64로 인코딩하여 텍스트 파일로 출력

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
import base64
 
# 파일 경로
file_path = '파일_경로/파일_이름.확장자'  # 실제 파일 경로로 수정
output_file_path = '인코딩된_파일.txt'  # 저장할 파일명
 
def encode_file_to_base64(file_path, output_file_path):
    try:
        with open(file_path, 'rb'as file:
            # 파일을 읽어들여 Base64로 인코딩
            encoded_content = base64.b64encode(file.read())
 
            # Base64를 텍스트 파일로 저장
            with open(output_file_path, 'w'as output_file:
                output_file.write(encoded_content.decode('utf-8'))
            print(f'파일이 {output_file_path}로 성공적으로 인코딩되었습니다.')
 
    except FileNotFoundError:
        print('파일을 찾을 수 없습니다.')
    except Exception as e:
        print(f'오류 발생: {e}')
 
# 파일을 Base64로 인코딩하고 텍스트 파일로 저장
encode_file_to_base64(file_path, output_file_path)
 
cs


2. 인코딩된 텍스트를 파일로 출력

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
import base64
 
# Base64로 인코딩된 텍스트 파일 경로
encoded_file_path = '인코딩된_파일.txt'  # 실제 파일 경로로 수정
output_file_path = '복원된_파일.bin'  # 이진 파일로 저장할 경로 및 파일명
 
def decode_base64_to_file(encoded_file_path, output_file_path):
    try:
        with open(encoded_file_path, 'r'as encoded_file:
            # Base64로 인코딩된 파일을 읽음
            encoded_content = encoded_file.read()
 
            # Base64를 디코딩하여 이진 파일로 저장
            with open(output_file_path, 'wb'as output_file:
                output_file.write(base64.b64decode(encoded_content))
            print(f'파일이 {output_file_path}로 성공적으로 디코딩되었습니다.')
 
    except FileNotFoundError:
        print('파일을 찾을 수 없습니다.')
    except Exception as e:
        print(f'오류 발생: {e}')
 
# Base64로 인코딩된 텍스트 파일을 디코딩하여 이진 파일로 저장
decode_base64_to_file(encoded_file_path, output_file_path)
 
cs

끝!

댓글

가장 많이 본 글