ENCODING

ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127.
Using the below integer array, convert the numbers to their corresponding ASCII characters to obtain a flag.
ASCII =  7비트 인코딩
아래 정수 배열로 숫자를 ASCII로 변환해 플래그를 얻어라 

In Python, the chr() function can be used to convert an ASCII ordinal number to a character (the ord() function does the opposite.
 chr() ord()를 쓰면 되는데, chr은 ASCII 서수를 문자로 ord는 문자를 서수로 바꾸어준다.

문제에선 chr 함수를 써야하는걸 알 수 있다.
[99, 114, 121, 112, 116, 111, 123, 65, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]

s = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
for a in s:
    print(chr(a),end="")

해석해보면 리스트를 변수에 넣고 
for 함수를 사용해서 리스트값을 하나하나 서수를 문자로 변환해 a에 넣고 end를 이용해 하나의 값으로 출력한것
crypto{ASCII_pr1nt4bl3} 

 

HEX

When we encrypt something the resulting ciphertext commonly has bytes which are not printable ASCII characters. If we want to share our encrypted data, it's common to encode it into something more user-friendly and portable across different systems.
Hexadecimal can be used in such a way to represent ASCII strings. First each letter is converted to an ordinal number according to the ASCII table (as in the previous challenge). Then the decimal numbers are converted to base-16 numbers, otherwise known as hexadecimal. The numbers can be combined together, into one long hex string.
Included below is a flag encoded as a hex string. Decode this back into bytes to get the flag.
 
무언가를 암호화 할때 암호문에는 일반적으로 
인쇄가능한 ASCII 문자가 아닌 바이트라는게 있다
이 문제는 16진수 문자열로 인코딩된 플래그가 포함 되있다  
이걸 바이트로 다시 디코딩 해서 플래그 찾으셈 
 
In Python, the bytes.fromhex() function can be used to convert hex to bytes. The .hex() instance method can be called on byte strings to get the hex representation\
 
이럴때 bytes.fromhex() 함수를 사용해서 
16진수 바이트로 변환 할수 있음 
.hex() 는 바이트 문자열에서 호출 되어서 16진수 표현을 얻을수있다함 
 
63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6

a = "63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d"
print(bytes.fromhex(a))

 bytes.fromhex를 이용해서 16진수로 표현된 문자열 a을 바이트로 변환 시켜서 출력시킨것이다 
crypto{You_will_be_working_with_hex_strings_a_lot}

BASE64

Another common encoding scheme is Base64, which allows us to represent binary data as an ASCII string using an alphabet of 64 characters. One character of a Base64 string encodes 6 binary digits (bits), and so 4 characters of Base64 encode three 8-bit bytes.
Base64 is most commonly used online, so binary data such as images can be easily included into HTML or CSS files.
Take the below hex string, decode it into bytes and then encode it into Base64
 
인코딩 체계에
base64 라고 64자의 알파벳을 사용해서 이진데이터를 
ASCII 문자열로 나타낼수 있다 
base64 문자열의 한 문자는 6개의 이진수를 인코딩하므로,
base64의 4문자는 3개의 8비트 바이트를 인코딩한다 
온라인에서 일반적으로 사용되서 이미지와 같은 이진 데이터를 
HTML 또는 CSS 파일에 쉽게 포함할수 있음 
아래 16진수 문자열을 바이트로 디코딩 하고 Base64로 인코딩 해라 
 
 In Python, after importing the base64 module with import base64, you can use the base64.b64encode() function. Remember to decode the hex first as the challenge description states.
 
import base64로 모듈을 가져오고
base64.b64encode()
함수를 사용 할 수 있다 
먼저 16진수먼저 인코딩 해라(해독)
 
72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf
 
일단 16진수를 어떻게 해야할지 생각해보고 있었는데 아까 decoding 할때 썼던 bytes.fromhex를 사용하면 될거같다 근데 
16진수를 먼저 해독하고 모듈을 또 사용해서 답을 하나를 만들어야 하니까 result 사용하면 되겠다 라고 생각했는데 딱히 필요가 없었다 

import base64
a = "72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf"
b = bytes.fromhex(a)
print(base64.b64encode(b))

 import base64로 base64 모듈을 가져와서 
a변수에 문제 넣고 
b변수에서 a를 16진수를 바이트로 해독해주고
결국에 b에들어있는건 바이트 a
그걸 base64.b64encode 출력할때 저 함수를 적용 시켜버리면  
crypto/Base+64+Encoding+is+Web+Safe/

Bytes and Big integers

Cryptosystems like RSA works on numbers, but messages are made up of characters. How should we convert our messages into numbers so that mathematical operations can be applied?
The most common way is to take the ordinal bytes of the message, convert them into hexadecimal, and concatenate. This can be interpreted as a base-16/hexadecimal number, and also represented in base-10/decimal.

RSA와 같은 암호 시스템은 숫자로 작동하지만 메시지는 문자로 구성
수학 연산을 적용할 수 있도록 메시지를 숫자로 어떻게 변환하는
가장 일반적인 방법은
메시지의 서수 바이트를 가져와 16진수로 변환하고 연결하는 것
이는 16진수/16진수로 해석할 수 있으며 10진수/10진수로도 표시

Python's PyCryptodome library implements this with the methods bytes_to_long() and long_to_bytes(). You will first have to install PyCryptodome and import it with from Crypto.Util.number import *

Python의 PyCryptodome 라이브러리는 bytes_to_long() 및 long_to_bytes() 메서드로 이를 구현합니다. 먼저 PyCryptodome을 설치하고 from Crypto.Util.number import *로 가져와야 합니다.
 
해석을 들어보니 모듈을 설치하고 그 안에서 선언 (import)를
한 뒤에
코드를 짜는것이엿다

from Crypto.Util.number import *
 
a = "label"

for i in range(len(a)):
    s = ord(a[i])
    b = s^13
    print(chr(b))

a
l
o
h
a
라고 나온다
플래그 포맷 형식에 맞춰서 입력해주면 된다. 
 

XOR Properties

bytes_to_long() 함수는 바이트 값을 정수(long)형태의 값으로 변환한다.
long_to_bytes() 함수는 정수(long)형태 값을 바이트 
로 변환함 이라는 원리를 알고 해야함 근데 여기서
바이트는 그냥 로마자나 뭐 이런 숫자의 최소 단위라는데 ))
여기서 중요한건 위에서 했던..
xor starter
 bytes.fromhex() 함수를 사용해서
16진수 바이트로 변환 할수 있음 
.hex() 는 바이트 문자열에서 호출 되어서 16진수 표현을 얻을수있다함
이라고 했던 이 개념을 떠올려야한다.
 
bytes.fromhex  = 16진수를 바이트로 바꾸는거임 
근데 문제에서 정수로 바꾸라는 힌트를 줬으니까
bytes.fromhex 로만 쓰면 바이트로만 나오는거임 정수로 나오려면 
bytes_to_long(bytes.fromhex
이렇게 쓸 생각을 해야함 해석하면
16진수를 바이트 (bytes.fromhex)로 바이트를 다시 정수로 (bytes_to_long)     
 
또 멘토링 하면서 알게된 xor성질중에 
xor한 값xor한요소 하나를 xor하면 
나머지 한 요소가 나오는거 
ex))
a^b = c
c^a = b 이렇게 
 

from Crypto.Util.number import*

key1 = bytes_to_long(bytes.fromhex("a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313"))
key2 =key1^bytes_to_long(bytes.fromhex("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e"))
key3 =key2^bytes_to_long(bytes.fromhex( "c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1"))
flag = bytes_to_long(bytes.fromhex( "04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf"))

 근데
Print 소스를 어떻게 짜야할지 모르겠을 뿐더러 소스코드에
오류가 있는거같다

from Crypto.Util.number import*

key1 = bytes_to_long(bytes.fromhex("a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313"))
key2 =key1^bytes_to_long(bytes.fromhex("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e"))
key3 =key2^bytes_to_long(bytes.fromhex( "c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1"))
flag = bytes_to_long(bytes.fromhex( "04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf"))^key1^key2^key3

print((long_to_bytes(flag)))

그래서 생각해보니 bytes to long 쓰고 flag 값은 key1^key2^key3을 해야 나온다고 했으니까 flag 값에 
xor을 해주는것을 까먹었다 
print는 다시 bytes_to_long을
long_to_bytes로 바꾸어서
flag 값을
원래의 형태(bytes)로 바꾸어서 출력 해보려고 하니까 
flag값이 나왔다
*crypto{x0r_i5_ass0c1at1v3}  

 
 
 
 

암호의 특성

  • 기밀성(Confidentiality): 암호화된 내용이 무엇인지 알 수 없어야 함
  • 무결성(Integrity): 원본과 확실한 데이터라는 것
  • 인증(Authentication): 권한이 있는 사람만 접근할 수 있음

 

암복호화 설명

평문(plaintext): 원래 송신자가 전달하려는 원본 메세지
암호문(ciphertext): 송신자와 수신자만 전달 내용을 알 수 있도록 키를 사용해서 알아볼 수 없게 만든 메세지
암호화(encryption): 평문을 암호문으로 바꾸는것
복호화(decryption): 암호문을 평문으로 바꾸는것
키(key): 암복호화에 쓰이는 특정한 값 (자물쇠 열고 잠그는것처럼 키를 사용해서 암복호화를 진행하고 키를 모르면 복호화가 어려움)
 

암호화(encrypt)와 복호화(decrypt)


암호화를 저 그림으로 설명하자면
ex) hello? 라는 평문이 있다고 치면 암호화키를 통해 Olel?h 이런식으로 알아볼수 없도록 만드는 것이 암호화이고
그 암호문을 해커가 중간에서 평문을 알아볼수 없도록 하는것이 암호화의 궁극적인 목표라고 볼 수 있다.
 
복호화란 위처럼 암호화키를 통해 평문을 암호화 시켜서 만든 암호문을 복호화 키를 통해 평문으로 만드는것이다 최종적으로 궁극적으로 평문 ex) hello가 특정한 사람만 볼수있도록 , 즉
특정한 사람만 암호화된 암호문을 평문으로 바꿀수있는 복호화 키를 풀수있도록 어떠한 장치를 설정하면 중간에서 해커나 다른 3자가 볼수없게 된다. 이것이 암복호화의 기초이다.
 
여기서 암호화 키 와 복호화 키가 같은 암호알고리즘을 aes , 암복호화 키가 다른 공개 비대칭키 암호알고리즘을 rsa라고 한다 
추가로 des 라고 매우 오래된 대칭키 알고리즘이 있는데 취약해서 잘 사용하지 않는다..
 

인코딩(Encoding)과 디코딩(Decoding)

 인코딩(encoding)은 말 그대로 Code 화 한다는 뜻이다 즉, A의 형태를 코드화 하는것이다
반대로 디코딩(decoding)은 Code에서 A의 모습으로 되돌리는 것이다 
 
인코딩과 암호화는 목적과 성질이 아예 다르다 
인코딩은 표현 방법을 코드로 바꾸는 것이고, 암호화는 특정한 사람이외에는 남이 정보를 알아보지 못하게 하는 것이다.
그렇다면 반대로 디코딩과 복호화 과정도 똑같은 이유로 차이가 난다
또, encoding decoding에는
KEY가 존재하지 않는다는 점이 가장 큰 차이이다

 
 
 


보안관제에서 멘토링 하며 받은 사이트에 있는
고전 암호학 중에서도 전치암호학을 혼자 회독하면서
정리한 글을 써볼것이다...

 

치환(Substitution): 평문의 각 문자를 다른 문자로 치환하는 기법. 평문의 문자와 암호문의 문자가 이루는 대응 관계에 따라 단일 치환 암호, 다중 치환 암호로 구분됨.

전치(Transposition): 평문을 구성하는 문자들의 순서를 바꾸는 기법.

전수 키 탐색 공격(Exhaustive Key Search Attack): 키 공간을 전부 탐색하는 공격 방법. 가능한 키의 수가 적으면 효과적일 수 있으나, 현대 암호는 키 공간의 크기가 매우 넓으므로 이를 대상으로 사용하기 어렵다.

빈도수 분석(Frequency Analysis): 암호문에서 단어가 등장하는 빈도를 분석하여 통계적으로 복호화하는 공격 기법. 특수한 경우에서만 사용될 수 있다.


 
0. 전치 암호 (Transposition Cipher)

평문의 문자들의 위치 변경,교체로 암호화
= 각 문자의 순서를 바꾸거나 치환의 방법으로 암호문 생성

 
1. KEYLESS TRANSPOSITION CIPHER   

간단한 치환암호인데  KEY 를 정하지 않고도  치환만으로 암복호화가 가능 한것을 말한다 

 
2. RAIL FENCE CIPHER

평문에 문자n개를 지그재그로 나열해 치환을 하여 암호화
= 평문의 문자를 "지그재그" 로 나열하여 암호문 생성
지그재그로 두줄로 나눈뒤 위아래 순서로 문자를 조합해서 암호화 시키는 것
예시는 복잡하니 생략하겠다 

 
3.DECIDE THE TABLE THE NUMBER OF COLUMMS

암호화에 사용될 문자의 열 (column)의 수를 정해주고 암호화 하는 방법임
= 이미지: 평문을 열 수로 나누어서 table에 한 행씩 쓰고 작성된 table을 열 순으로 읽으면
암호문을 생성할수 있음 그래서 meet me at the park라는 평문을 암호화를 해보면

M E E T
M E A T
T H E P       
A R K
 
3-1

복호화는
위의 TABLE로 MMTAEEHREAEKTTP 라는 암호학이 만들어진다 복호화 하는 방법은
위의 TABLE을
열 순으로 다시 채우면 된다 열 순을 이미 (4)라고 정해두었으므로,
1.평문의 전체 길이를 열수로 나누고

2.그 개수만큼 하나의 열(cloumn) 에 쓰고
3.작성된 TABLE 을 행순으로 읽으면 다시 평문으로 읽을 수 있다.

해보자면 15의 문자열의 길이를 4로 나누어서 MMTA,EEHR,EAEK,TTP
=
M M T A
E E H R
E A E K
T T P

이렇게 놓고 행(ROW) 즉 세로로 읽으면 처음의 평문을 만들 수 있다 (복호화)
처음 상태였던 평문 MEAT ME AT THE PARK 가 됨.

 
4.KEYED TRANSPOSITION CIPHER
 

2번에서한 암호화는 평문을 한 행씩 쓰고 한 열씩 있는 쓰는 방법과 읽는
방법을 변경해서 암호화를 완성 시켰다면
Keyed Transpositon Cipher 에서는 평문을 일정한 조각으로 나누고
나누어진 조각을 특정한 규칙에 맞게 글자간 순서를 변경해서 완성 시킨다.
이때 나누어진 조각을 block이라고 하며 결국 평문을 block단위로 나누어
block에서 전치를 수행하게 되는 것.
(이때 block의 값은 정해져있거나 찾아야하는데 여기서는 정해줄것임)

ex))
Enemy Attack Tonight 이라는 문장을 암호화 해보자
block의 크기는 5이고 block 의
치환키는 31452라고 해보자
 
3 1 4 5 2     ←—— 치환키
1 2 3 4 5
 
이를 해석해보면 각 block에서
3번째 글자를 먼저 쓰고 1번째 글자를 두 번 째로 4번쨰 글짜를 세번째로 등등등 쓰면서 
암호화를 진행하라는 말이다
그렇다면 enemy 라는 단어는 eemyn로 암호화 될것이다
아까 말했던 예시문장을 하나하나 조합해보자면
EEMYNTAACKTKONSHITXG 라는 식으로 암호화가 진행된다.
 

4-1

복호화를 하려면
키를 먼저 생성해야 하는데 위에서 표해서 첫번째 열이 12345가 되도록 수정하자

1 2 3 4 5
2 5 1 3 4

그럼 이런식으로 되는데 여기서 복호화 키는 25134가 된다 즉 아까 암호화 시켰던 EEMYN block은 복호화키를 이용해 복호화를 시켜주면 ENEMY가 되는것이다.
Transposition Cipher는 키를 활용해이런식으로 수행할수있게 된다.

 
 
5. Combined Transposition Cipher

이 방법은 그냥 단순하게 앞선 두개의 방법을 합쳐서 만들어진 암호화 기법이다 
3번에서 했던것처럼 table의 열(cloumn)을 정해 table을 생성한 뒤 방금 한 4번의방식처럼
key 를 통해서 치환한다. 그리고 완성된 table을 열 by 열 순으로 읽어 암호문을 완성한다 
 
예제로 아까 했던 Enemy attacks tonight 을 암호화 해보자 
사용되는 키는 31452로 함 block은 5이다 block의 사이즈가 5이기 때문에 
자동적으로 열의 수 도 5가 되는것이다 

 

위는 완성된 평문의 table이고 밑에 있는것은 31452라는 주어진 key를통해 Column간 순서를 치환 했다 
완성된 table은 열 by 열 순서로 읽으면 된다 즉 암호문은 ETTHEAKIMAOTYCNXNTSG 된다.
복호화의 경후에는 열 by 열 순서로 table에 암호문을 채워넣고 아까 했던것처럼 복호화키를 구하면 25134가 되는데
4-1 참고

그걸 이용해서 table의 열을 다시 치환한다 완성된 table을 이번엔 row by row 행 by 행 으로 읽으면 평문을 찾을수 있다
 

 
 
 
 

+ Recent posts