---
# System prepended metadata

title: Write up crypto hack

---


> # **WRITE UP CRYPTOHACK**
# **ASCII**

 ![Snipaste_2024-06-08_16-11-52](https://hackmd.io/_uploads/B1lxWj-rC.png)

 
Với bài này và hint là sử dụng **chr()** để chuyển từ mã ascii thành kí tự và **ord()** là chuyển từ kí tự sang ascii.
 [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
 
 Chúng ta có thể code như sau:
 
```python
data1 = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
for i in data1:
    print(chr(i), end='')
```
**Giải thích:**
*Với **data1** là các số đề bài cho, **for i in data** là vòng lặp để chuyển từng số sang kí tự, **print(chr(i),end='')** là chuyển sang kí tự bằng cách sử dụng hàm **chr()**, **end=''** là để in các kí tự lên một dòng. Nếu không có dòng này thì kết quả sẽ là:*
> c
r
y
p
t
o
{
A
S
C
I
I
_
p
r
1
n
t
4
b
l
3
}

**Kết quả:**
Dòng code này để chuyển các số trong bảng mã ascii thành kí tự. khi chạy chương trình thì nó ra kết quả là:
**crypto{ASCII_pr1nt4bl3}**

**Hãy thử làm ngược lại:**
*Ở bài trên thì chúng ta đã dùng hàm **chr()** để chuyển đổi số thành kí tự. Bây giờ hãy sử dụng hàm **ord**() để đổi lại văn bản thành mã số:*
```python
text = "crypto{ASCII_pr1nt4bl3}" 
print('\n')
for i in text:
    print(ord(i),end='')
```
**Giải thích:**
**Text** là để gán chuỗi kí tự trong dấu **""**,**for i in text** để gọi vòng lặp, **print(ord(i))** là để chuyển các kí tự trong text thành số bằng cách sử dụng hàm **ord()**, **end=''** là để các số nằm hết trên 1 dòng
***Và kết quả chúng ta thu được là:***
**9911412111211611112365836773739511211449110116529810851125**



# **Hex**
![image](https://hackmd.io/_uploads/SkbtuCWrC.png)
> *Ở bài này thì chúng ta sẽ dùng bảng mã hex để giải mã*
 **63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d**
 
Nhìn đoạn kí tự trên thì chúng ta thấy nó không có ý nghĩa gì cả. Nhưng thử đổi những kí tự đó từ hex về text(byte) xem nó có ý nghĩa gì.
**Đây là chương trình chuyển đổi từ hệ thập lục phân(cơ số 16) sang byte(cơ số 10):**
```python=
data2="63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d"
//gán dữ liệu cho data2
print('\n')
byte_data2=bytes.fromhex(data2)
//chuyển đổi một chuỗi hexa (data2) thành dữ liệu byte và lưu vào biến byte_data2
//Hàm fromhex() của lớp bytes trong Python nhận vào một chuỗi các số hexa và trả về một đối tượng byte tương ứng.

print(byte_data2,'\n')
```
> **Ví dụ, nếu data2 = '68656c6c6f' (đây là chuỗi hexa của từ ‘hello’), sau khi chạy đoạn code trên, byte_data2 sẽ chứa dữ liệu byte tương ứng với chuỗi ‘hello’.**
> 
Sau khi chạy chương trình trên thì ta thu được kết quả tương ứng đó là:
**crypto{You_will_be_working_with_hex_strings_a_lot}**

# Base 64
> **Base64 là một hệ mã hóa dùng để chuyển đổi dữ liệu nhị phân thành chuỗi các ký tự ASCII. Nó thường được sử dụng khi cần mã hóa dữ liệu nhị phân, đặc biệt khi dữ liệu đó cần được lưu trữ và chuyển giao qua các hệ thống được thiết kế để xử lý dữ liệu văn bản.**

**Cách hoạt động của base 64 như sau:**
1.Dữ liệu nhị phân được chia làm 3 bytes
2.Mỗi nhóm 3 byte này sẽ tạo ra 4 số nguyên trong khoảng từ 0 đến 63.
3.Mỗi số nguyên này sau đó được thay thế bằng một ký tự tương ứng trong bảng mã Base64.

![image](https://hackmd.io/_uploads/HyXxW1MSA.png)

Ở thử thách này thì đề yêu cầu chuyển **chuỗi hex** đã cho thành **kiểu bytes** và giải mã nó qua **base 64**. Nó cũng cho gợi í là sử dụng module với câu lệnh **import base64** và sử dụng hàm **base64.b64encode()** để giải mã chúng.
Có thể nhận ra cách làm bài này là có liên quan tới bài trên, kế thừa cách lập trình ở bài trên ta được đoạn code sau:
```python
import base64
data3="72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf"
//Đoạn này chuyển chuỗi hex thành byte như bài ở trên.
byte_data3=bytes.fromhex(data3)

//sử dụng gợi í của đề, chúng ta sử dụng base64.b64encode()
giaima=base64.b64encode(byte_data3)
print(giaima, '\n')
```
Sau khi chạy chương trình trên thì ta sẽ thu được kết quả là:
**crypto/Base+64+Encoding+is+Web+Safe/**

# Bytes and big integers
![image](https://hackmd.io/_uploads/rJmRXyzrA.png)

Ví dụ trên ta có thể hiểu như sau:

1. **Tin nhắn**: Bạn bắt đầu với tin nhắn "HELLO".
2. **ASCII byte**: Bạn chuyển từng ký tự của tin nhắn thành giá trị ASCII tương ứng của chúng. Ví dụ, ký tự 'H' có giá trị ASCII là 72, 'E' là 69, và 'L' là 76, 'O' là 79. Vì vậy, "HELLO" được chuyển thành [72, 69, 76, 76, 79].
3. **Byte hex**: Bạn chuyển từng giá trị ASCII này thành dạng hexa. Ví dụ, 72 (trong hệ thập phân) tương ứng với 0x48 (trong hệ hexa), 69 tương ứng với 0x45, 76 tương ứng với 0x4C, và 79 tương ứng với 0x4F. Vì vậy, [72, 69, 76, 76, 79] được chuyển thành [0x48, 0x45, 0x4c, 0x4c, 0x4f].
4. **Base-16**: Bạn nối các giá trị hexa này lại với nhau để tạo thành một số nguyên trong hệ hexa, tức là 0x48454c4c4f.
5. **Base-10**: Cuối cùng, bạn chuyển số nguyên này từ hệ hexa sang hệ thập phân, tức là từ 0x48454c4c4f sang 310400273487.

Vậy, bạn đã chuyển tin nhắn "HELLO" thành số nguyên 310400273487 thông qua một chuỗi các bước chuyển đổi. 

Quay trở lại với đề bài, chúng ta phải chuyển đổi một số nguyên rất lớn về mật mã đang được giấu. Chúng ta có thể đi theo hướng chuyển dãy số trên về dạng byte.
**Lưu ý:** Bạn cần tải thư viện **PyCryptodome** trước bằng câu lệnh:
> ***pip install pycryptodome*** 

**Sau đây là cách làm:**
```python
import base64
from Crypto.Util.number import long_to_bytes
data4='11515195063862318899931685488813747395775516287289682636499965282714637259206269'
text4= long_to_bytes(int(data4))
print(text4,'\n')
```
**Giải thích:**
1. `import base64`: Đây là lệnh import module `base64` trong Python, module này cung cấp các hàm để làm việc với mã hóa Base64.
2. `from Crypto.Util.number import long_to_bytes`: Đây là lệnh import hàm `long_to_bytes` từ module `Crypto.Util.number`. Hàm `long_to_bytes` được sử dụng để chuyển đổi một số nguyên dạng long (số nguyên lớn) thành dạng byte.
3. `data4='11515195063862318899931685488813747395775516287289682636499965282714637259206269'`: Đây là khai báo một chuỗi số nguyên lớn và gán cho biến `data4`.
4. `text4= long_to_bytes(int(data4))`: Ở đây, chuỗi số nguyên `data4` được chuyển thành số nguyên bằng hàm `int()`. Sau đó, hàm `long_to_bytes()` được sử dụng để chuyển đổi số nguyên này thành dạng byte và gán cho biến `text4`.
5. `print(text4,'\n')`: Cuối cùng, đoạn code in ra giá trị của `text4`, tức là dữ liệu byte tương ứng với số nguyên lớn ban đầu.
 
Kết quả của chương trình sau khi chạy là:
**crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}**


# XOR
![image](https://hackmd.io/_uploads/BkYr2i-oC.png)

**Trước tiên chúng ta cần hiểu XOR là gì**
XOR (viết tắt của eXclusive OR - hoặc độc quyền) là một phép toán logic cơ bản. Nói một cách đơn giản, XOR trả về giá trị ĐÚNG khi và chỉ khi hai đầu vào khác nhau. **Nếu cả hai đầu vào đều giống nhau (cùng đúng hoặc cùng sai), kết quả sẽ là SAI.**

![image](https://hackmd.io/_uploads/B1W0poWoC.png)

Ví dụ:

Công tắc đèn: Nếu bạn có hai công tắc điều khiển một bóng đèn, mỗi công tắc đại diện cho một đầu vào. Khi chỉ một trong hai công tắc được bật, đèn sẽ sáng (XOR = 1). Nếu cả hai công tắc đều bật hoặc đều tắt, đèn sẽ tắt (XOR = 0).
Mạch điện tử: XOR được sử dụng rộng rãi trong các mạch điện tử để thực hiện các phép toán logic phức tạp.
Mã hóa: XOR cũng được ứng dụng trong các thuật toán mã hóa để thực hiện các phép toán trên bit dữ liệu.

Trong lập trình(Python), chúng ta sử dụng dấu ^ để xor 2 giá trị lại với nhau(ở dạng số)
Ví dụ: 0110 ^ 1010= 1100

Quay lại với đề bài, đề bài yêu cầu chuyển các kí tự "label" thành chuỗi kí tự mới với format cryto{chuỗi kí tự mới} bằng cách xor từng kí tự trong chuỗi label với số 13
> **Hướng làm bài:** vì phép xor chỉ được thực hiện giữa số và số nên đầu tiên chúng ta sẽ chuyển chuỗi kí tự thành số bằng cách sử dụng lệnh ***ord()*** rồi xor và cuối cùng chuyển lại giá trị mới bằng câu lệnh ***chr()***

```python
def text_to_unicode(s):
    return [ord(c) for c in s]

def unicode_to_text(unicode_values):
    return ''.join(chr(u) for u in unicode_values)

label = "label"
unicode_values = text_to_unicode(label)
xor_values = [i ^ 13 for i in unicode_values]
xor_text = unicode_to_text(xor_values)

print("Danh sách giá trị sau khi XOR:", xor_values)
print("Văn bản sau khi giải mã:", xor_text)
```
Hai hàm def là hàm định nghĩa và có kiểu giá trị trả về là số hoặc chữ 
***text_to_unicode(s):***
Hàm này nhận một chuỗi s và trả về danh sách các giá trị mã Unicode tương ứng với từng ký tự trong chuỗi.
Ví dụ: Nếu bạn chạy hàm với chuỗi "label", nó sẽ trả về danh sách [108, 97, 98, 101, 108] (mã Unicode của các ký tự trong chuỗi).

***unicode_to_text(unicode_values):***
Hàm này nhận danh sách các giá trị mã Unicode và trả về chuỗi ký tự tương ứng.
Ví dụ: Nếu bạn chạy hàm với danh sách [108, 97, 98, 101, 108], nó sẽ trả về chuỗi "label".
***unicode_values = text_to_unicode(label)***
Câu lệnh này gán giá trị của unicode_value thành các số được chuyển đổi từ chữ sang bảng mã unicode bằng cách gọi lại hàm đã định nghĩa trước đó là ***text_to_unicode(s)*** tương đương với ***text_to_unicode(label)*** và kết quả sẽ trả về giá trị số tương ứng với **"label"**
**xor_values = [i ^ 13 for i in unicode_values]** gán giá trị xor_value bằng giá trị khi xor 13 với chuỗi "label" sau khi đổi thành số

***xor_text = unicode_to_text(xor_values)*** tương tự như trên.

***print("Danh sách giá trị sau khi XOR:", xor_values)
print("Văn bản sau khi giải mã:", xor_text)*** 
In ra màn hình giá trị xor và bảng mã

Kết quả thu được là **aloha**
kết hợp với format của đề bài thì flag của chall này sẽ là ***cryto{label}***

# XOR PROPERTIES
![image](https://hackmd.io/_uploads/Syrcd2-jC.png)
**Ở bài này ta sẽ đi tìm flag khi biết key1,2,3.**
Sử dụng tính chất của phép XOR: chúng ta sẽ sử dụng tính tự nghịch đảo, tức là A ^ A =0, dựa vào đó ta sẽ đem cụm **FLAG ^ KEY1 ^ KEY3 ^ KEY2** xor với **KEY1 ^ KEY3 ^ KEY2** vì lúc đó KEY1 ^ KEY3 ^ KEY2 sẽ bị triệt tiêu và còn lại flag
**Dưới đây là cách code:**
```python
import pwn
KEY1 = int("a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313", 16)
KEY2KEY1 = int("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e", 16)
KEY2KEY3 = int("c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1", 16)
FLAGKEY1KEY3KEY2 = int("04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf", 16)
flag= (FLAGKEY1KEY3KEY2 ^KEY2KEY3 ^KEY1 )
print(bytes.fromhex(hex(flag)[2:]))
```
Trước khi chạy chương trình, với ai chưa cài thư viện pwn thì vào terminal của ide coding gõ dòng lệnh ***pip install pwn***

Các con số **16** ở cuối mỗi dòng đều liên quan đến **hệ thống số thập lục phân (hexadecimal)**. Hãy xem xét từng phần trong đoạn mã:

**int("a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313", 16)**:
Đây là việc chuyển đổi chuỗi mã hex "a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313" thành một số nguyên.
Số này được biểu diễn bằng hệ thập lục phân (base 16).
**FLAGKEY1KEY3KEY2 ^ KEY2KEY3 ^ KEY1:**
Đây là phép XOR giữa các số nguyên đã được chuyển đổi từ chuỗi mã hex.
Kết quả của phép XOR này là một số nguyên.
**print(bytes.fromhex(hex(flag)[2:]):**
Đoạn mã này chuyển số nguyên kết quả thành chuỗi hex và sau đó trích xuất chuỗi hex từ vị trí thứ 2 trở đi.
Cuối cùng, nó chuyển chuỗi hex trở lại thành dãy byte và in ra.
~~Đáp án cuối cùng thu được là:~~ ***crypto{x0r_i5_ass0c1at1v3}***

# FAVORITE BYTE
![image](https://hackmd.io/_uploads/r1Ex70ZiA.png)
**Hướng giải quyết:**
Vì đề bài đã giấu vị trí của byte đó nên chúng ta phải đi bruteforce xem đáp án như thế nào.
P/s:
![image](https://hackmd.io/_uploads/B1RYQAWi0.png)
=> Chúng ta sẽ cho chạy key trong khoảng từ 0-255(225-0+1=256)
**Dưới đây là phần code:**
```python
data = "73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d"
byte_data2 = bytes.fromhex(data)

for i in range(256):
    flag = bytes([b ^ i for b in byte_data2])
    if b'crypto{' in flag:
        print(flag.decode())

```
**byte_data2 = bytes.fromhex(data):** chuyển chuỗi hex ở trên thành byte rồi gán cho giá trị byte_data2 
**flag = bytes([b ^ i for b in byte_data2]):** sử dụng vòng lặp để xor i(0-255) với giá trị byte_data2 đã tính ở trên.
Vì chương trình sẽ cho output rất dài và chúng ta đã biết được format của cờ là ***crypto{*** nên cta sẽ dùng câu lệnh if để lọc ra kết quả như sau 
>     if b'crypto{' in flag:
>         print(flag.decode())
Cuối cùng đáp án ta thu được là: ***crypto{0x10_15_my_f4v0ur173_by7e}***

# YOU ETHER KNOW, XOR YOU DON'T
![image](https://hackmd.io/_uploads/r1zyLAbjR.png)
Sử dụng những gì đã học ở trên, ta có thể làm như sau:
```python
data = "0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104"
encrypted_data = bytes.fromhex(data)
flag_format = b"crypto{"
key = [o1 ^ o2 for (o1, o2) in zip(encrypted_data, flag_format)] + [ord("y")]
flag = "".join(chr(o1 ^ o2) for (o1, o2) in zip(encrypted_data, key * (len(encrypted_data) // len(key) + 1)))
print("Flag:")
print(flag)
```
**zip(encrypted_data flag_format)**: lấy từng cặp byte từ 2 biến encryp_data và flag_format.
Cụ thể ví dụ o1^o2 for(o1o2) in zip(a,b) với a=[100,101,102] và b=[97,98,99] thì kết quả thu được sẽ là [5,7,5]
![image](https://hackmd.io/_uploads/rJyzsiNoC.png)
>Ví dụ để mn dễ hiểu về dòng lệnh trên, nó sẽ lấy từng kí tự của chuỗi encryp_data xor cho từng kí tự của chuỗi flag_format. Chương trình trên là 2 phép so sánh để mọi người thấy cách hoạt động của câu lệnh. Theo 2 cách thì cuối cùng đáp án ta thu được đều giống nhau, nhưng cách 1 sẽ nhanh hơn so với cách 2 Đáp án khi chạy chương trình ví dụ là:
![image](https://hackmd.io/_uploads/BkgsjoEiA.png)

Còn vì sao +ord["y"] thì chúng ta hãy thử xor chuỗi data với crypto{, ta sẽ thu được kết quả là **myXORke**
![image](https://hackmd.io/_uploads/H1ql63VjA.png)
Vì myxorke không có ý nghĩa nên chúng ta có thể thử thêm y vào sao cho cụm đó có ý nghĩa.(điều này sẽ hữu ích cho việc decode bên dưới)
**flag = "".join(chr(o1 ^ o2) for (o1, o2) in zip(encrypted_data, key * (len(encrypted_data) // len(key) + 1)))**: câu lệnh này sẽ đem đi xor từng kí tự của **encrypted_data** với **key** của nó. Sau khi xor hết **kí tự cuối** của "myxorkey" thì nó sẽ xor tiếp với **kí tự đầu tiên** của "myxorkey" tức là kí tự "m". Điều này sẽ ***lặp đi lặp lại*** đến khi hết kí tự trong chuỗi **encrypted_data**
**len(encrypted_data) // len(key)** trong đoạn mã có nghĩa là lấy phần nguyên của kết quả chia độ dài của encrypted_data cho độ dài của key
Ví dụ encryp có độ dài là 20, key có độ dài là 8 thì 20/8 ra 2 dư 4. để lặp hết phần dư thì chúng ta phải cộng thêm 1 vào để cho độ dài của encryp được phủ hết. Giống như kiểu bạn có cây thước dài 20cm, mà cái bao của bạn có 16cm(8x2) thì bạn muốn bao hết được cây thước có thể nối thêm một bao sao cho che đi phần thước dư ra. Và đó là lý do chúng ta phải cộng thêm 1
Kết quả cuối cùng ta thu được: ***crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}***
Nếu ở trên chúng ta không cộng cho ord("y") thì key nó sẽ là myxorky. Tất nhiên nó cũng sẽ ra được kết quả. Dưới đây là code cho hướng đó:
![image](https://hackmd.io/_uploads/SySHI6Ni0.png)
Như bạn có thể thấy, chương trình vẫn sẽ ra được flag, nhưng mà nó sẽ không có một ý nghĩa gì cả. Vì vậy **thêm y vào myxorke** sẽ là hướng đi đúng cho chúng ta.
Có một cách khác nhanh hơn và dễ hiểu hơn:
```python
from pwn import xor

data = bytes.fromhex('0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104')

key = b'myXORkey'

flag = xor(key, data)

print(flag)

#output sẽ là: b'crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}'
```

# Network attack
![image](https://hackmd.io/_uploads/Sk6xcutjC.png)
Đầu tiên chúng ta sẽ tải file chall. 
Code trong nó sẽ trông như thế này:
![image](https://hackmd.io/_uploads/rynNqOKiA.png)
Trong đề bài cũng đã có gợi ý cho chúng ta đó là: **Đối với thử thách này, hãy kết nối tới socket.cryptohack.orgtrên cổng 11112. Gửi một đối tượng JSON với khóa buyvà giá trị flag.**
Bạn nhìn trong code thấy có hàm tên là **request={}**. Trong hàm đó hãy sửa giá trị **clothes** thành **flag** và chạy chương trình, và thế là chúng ta đã có kết quả.
![image](https://hackmd.io/_uploads/r1fejdFs0.png)
Flag chúng ta thu được là: **crypto{sh0pp1ng_f0r_fl4g5}**

# Lemur xor
![image](https://hackmd.io/_uploads/SJfZjTFiC.png)
Ở bài này, thay vì xor các byte của dữ liệu thì chúng ta sẽ xor các byte RGB của ảnh.
Vậy xor rgb là gì?
> XOR RGB là một phép toán logic XOR (Exclusive OR) được áp dụng trên các thành phần màu RGB (đỏ, xanh lá, xanh dương) của các pixel trong một hình ảnh
> Chi tiết về XOR RGB:
> RGB (Red, Green, Blue): Đây là mô hình màu được sử dụng phổ biến trong hình ảnh kỹ thuật số, trong đó mỗi pixel được biểu diễn bằng ba giá trị tương ứng với cường độ của các màu đỏ (Red), xanh lá (Green), và xanh dương (Blue). Mỗi giá trị này thường nằm trong khoảng từ 0 đến 255 (8 bit).
> Áp dụng XOR trên RGB:
Khi thực hiện XOR trên các thành phần màu RGB của hai pixel từ hai hình ảnh khác nhau, ta thực hiện phép XOR trên từng cặp giá trị của các thành phần màu tương ứng.
> Ví dụ:
> Giả sử chúng ta có hai pixel:
> 
> Pixel 1 có giá trị RGB là (R1, G1, B1) = (120, 200, 50)
> Pixel 2 có giá trị RGB là (R2, G2, B2) = (90, 150, 100)
> Thực hiện phép XOR trên từng thành phần màu:
> 
> R = R1 XOR R2 = 120 XOR 90 = 34
> G = G1 XOR G2 = 200 XOR 150 = 86
> B = B1 XOR B2 = 50 XOR 100 = 82
> Kết quả sau phép XOR sẽ là một giá trị RGB mới:
> 
> Pixel kết quả: (34, 86, 82)

Vậy giờ chúng ta sẽ viết code để xor 2 tấm hình đề cho.
```python
from PIL import Image
# Mở hai hình ảnh
image1 = Image.open(r'C:\Users\ADMIN\Downloads\flag_7ae18c704272532658c10b5faad06d74.png')
image2 = Image.open(r'C:\Users\ADMIN\Downloads\lemur_ed66878c338e662d3473f0d98eedbd0d.png')

# Lấy kích thước hình ảnh
width, height = image1.size

# Tạo một hình ảnh mới để lưu kết quả
result_image = Image.new('RGB', (width, height))

# Lặp qua từng pixel để thực hiện phép XOR trên các byte RGB
for x in range(width):
    for y in range(height):
        r1, g1, b1 = image1.getpixel((x, y))
        r2, g2, b2 = image2.getpixel((x, y))

        # Thực hiện phép XOR trên các giá trị RGB
        r = r1 ^ r2
        g = g1 ^ g2
        b = b1 ^ b2

        # Lưu giá trị RGB mới vào hình ảnh kết quả
        result_image.putpixel((x, y), (r, g, b))
# Hiển thị hình ảnh kết quả
result_image.show()
```
**From PIL import Image:** Chúng ta sẽ sử dụng thư viện PIL(python image libary) để nhập hình ảnh vào.
**image = Image.open(N)** Là câu lệnh để nhập ảnh từ thư mục với N là đường dẫn. Lưu ý nhớ thêm r trước đường dẫn để python nhận định đây là đường dẫn.
**For x for y:** sử dụng 2 vòng lặp lồng nhau để xor các giá trị pixel của 2 ảnh. giống như dùng trong ma trận.
Sau khi chạy chương trình thì chúng ta sẽ được trả về một tấm ảnh mới:
![image](https://hackmd.io/_uploads/Hyo1RTKs0.png)
Ở trên ảnh chúng ta sẽ thấy được flag: **crypto{X0Rly_n0t!}**
# RSA
Giới thiệu về RSA:
> Theo wikipedia, **RSA** là một thuật toán mật mã hóa khóa công khai. Đây là thuật toán đầu tiên phù hợp với việc tạo ra chữ ký điện tử đồng thời với việc mã hóa. Nó đánh dấu một sự tiến bộ vượt bậc của lĩnh vực mật mã học trong việc sử dụng khóa công cộng. RSA đang được sử dụng phổ biến trong thương mại điện tử và được cho là đảm bảo an toàn với điều kiện độ dài khóa đủ lớn.
> Thuật toán RSA có hai khóa: khóa công khai (hay khóa công cộng) và khóa bí mật (hay khóa cá nhân). Mỗi khóa là những số cố định sử dụng trong quá trình mã hóa và giải mã. Khóa công khai được công bố rộng rãi cho mọi người và được dùng để mã hóa. Những thông tin được mã hóa bằng khóa công khai chỉ có thể được giải mã bằng khóa bí mật tương ứng. Nói cách khác, mọi người đều có thể mã hóa nhưng chỉ có người biết khóa cá nhân (bí mật) mới có thể giải mã được.
> Ta có thể mô phỏng trực quan một hệ mật mã khoá công khai như sau: Bình muốn gửi cho An một thông tin mật mà Bình muốn duy nhất An có thể đọc được. Để làm được điều này, An gửi cho Bình một chiếc hộp có khóa đã mở sẵn và giữ lại chìa khóa. Bình nhận chiếc hộp, cho vào đó một tờ giấy viết thư bình thường và khóa lại (như loại khoá thông thường chỉ cần sập chốt lại, sau khi sập chốt khóa ngay cả Bình cũng không thể mở lại được-không đọc lại hay sửa thông tin trong thư được nữa). Sau đó Bình gửi chiếc hộp lại cho An. An mở hộp với chìa khóa của mình và đọc thông tin trong thư. Trong ví dụ này, chiếc hộp với khóa mở đóng vai trò khóa công khai, chiếc chìa khóa chính là khóa bí mật. 

**Modular Exponentiation**
![image](https://hackmd.io/_uploads/BygqPwpjA.png)
Công thức **pow(base, exponent, modulus)**
Ví dụ: 2^10 mode 17 theo công thức nó sẽ là:
**pow(2,10,17)**
Tương tự như vậy, với câu hỏi 101^17 mod 22663, ta có thể làm theo:
![image](https://hackmd.io/_uploads/H1YwODTo0.png)
Đáp án là **19906**

# Public key(khóa công khai)
![image](https://hackmd.io/_uploads/rJF3ODTiR.png)
Để làm bài này, ta sẽ có một số công thức:
> C=M^e mod N
>trong đó C là giá trị sau khi mã hóa
>M là giá trị cần mã hóa
>e là số mũ có giá trị là **0x10001** hoặc **65537**
>N là số nguyên nào đó được tạo thành từ p và q với công thức **N=p*q**

Áp dụng công thức trên, ta thấy
M=12, e=65537, p=17 và q=23
Trước tiên chúng ta sẽ đi tìm giá trị của N và sau đó sử dụng C=M^e mod N để mã hóa số 12.
Dưới đây là code:
![image](https://hackmd.io/_uploads/SJX99PpjA.png)
Vậy đáp án của bài là **301**
# private key(khóa riêng tư)
![image](https://hackmd.io/_uploads/SkWnjwTjC.png)
**Phi(N)=(p-1)*(q-1)**
có e bằng 65537, số mũ =-1, áp dụng công thức đã học ta có:
![image](https://hackmd.io/_uploads/ryQlTPTsA.png)

# RSA decryption
![image](https://hackmd.io/_uploads/r1IEpvpi0.png)
Ở trên chúng ta đã có công thức mã hóa rsa, ở bài này chúng ta sẽ có công thức để giải mã
> **M=C^d mod N**
> d chính là nghịch đảo modulo của e, hay **d=e^-1 mod phi(N)**
Đề bài cho N, cho e, cho c vậy chúng ta sẽ đi tìm d và phi(N)

Dựa vào gợi ý của đề bài, chúng ta có thêm p và q.
Dưới đây là code:
```python
N = 882564595536224140639625987659416029426239230804614613279163
e = 65537
p = 857504083339712752489993810777
q = 1029224947942998075080348647219
#Sử dụng khóa riêng mà bạn tìm thấy cho các tham số này trong thử thách trước để giải mã văn bản mã hóa này:
c = 77578995801157823671636298847186723593814843845525223303932
phi=(p-1)*(q-1)
d= pow(e,-1,phi)
print("day la so d:", d)
print("Day la gia tri sau khi giai ma",pow(c,d,N))
```
Kết quả thu được:
![image](https://hackmd.io/_uploads/B1hFZuToC.png)

# RSA signatures
![image](https://hackmd.io/_uploads/rJtuVR6jC.png)
**Sign the flag crypto{Immut4ble_m3ssag1ng} using your private key and the SHA256 hash function.**
Trước tiên chúng ta sẽ xem qua cách sử dụng hàm băm sha256 trên python
![image](https://hackmd.io/_uploads/B1cuu0pi0.png)
> Giải thích:
**hashlib.sha256()**: Tạo một đối tượng băm SHA-256.
**update()**: Thêm dữ liệu vào đối tượng băm. Dữ liệu cần được mã hóa thành bytes, do đó sử dụng message.encode() để chuyển đổi chuỗi thành bytes.
**hexdigest()**: Lấy giá trị băm dưới dạng chuỗi thập lục phân (hexadecimal).

Ở trong file đề cho chúng ta có:
> N=15216583654836731327639981224133918855895948374072384050848479908982286890731769486609085918857664046075375253168955058743185664390273058074450390236774324903305663479046566232967297765731625328029814055635316002591227570271271445226094919864475407884459980489638001092788574811554149774028950310695112688723853763743238753349782508121985338746755237819373178699343135091783992299561827389745132880022259873387524273298850340648779897909381979714026837172003953221052431217940632552930880000919436507245150726543040714721553361063311954285289857582079880295199632757829525723874753306371990452491305564061051059885803
> 
> 
> d=11175901210643014262548222473449533091378848269490518850474399681690547281665059317155831692300453197335735728459259392366823302405685389586883670043744683993709123180805154631088513521456979317628012721881537154107239389466063136007337120599915456659758559300673444689263854921332185562706707573660658164991098457874495054854491474065039621922972671588299315846306069845169959451250821044417886630346229021305410340100401530146135418806544340908355106582089082980533651095594192031411679866134256418292249592135441145384466261279428795408721990564658703903787956958168449841491667690491585550160457893350536334242689

Dựa vào dữ kiện đề cho, kết hợp cách dùng sha256(lược bỏ một số cái không cần thiết) ta có:
```python
import hashlib
from Crypto.Util.number import bytes_to_long

n = 15216583654836731327639981224133918855895948374072384050848479908982286890731769486609085918857664046075375253168955058743185664390273058074450390236774324903305663479046566232967297765731625328029814055635316002591227570271271445226094919864475407884459980489638001092788574811554149774028950310695112688723853763743238753349782508121985338746755237819373178699343135091783992299561827389745132880022259873387524273298850340648779897909381979714026837172003953221052431217940632552930880000919436507245150726543040714721553361063311954285289857582079880295199632757829525723874753306371990452491305564061051059885803
d = 11175901210643014262548222473449533091378848269490518850474399681690547281665059317155831692300453197335735728459259392366823302405685389586883670043744683993709123180805154631088513521456979317628012721881537154107239389466063136007337120599915456659758559300673444689263854921332185562706707573660658164991098457874495054854491474065039621922972671588299315846306069845169959451250821044417886630346229021305410340100401530146135418806544340908355106582089082980533651095594192031411679866134256418292249592135441145384466261279428795408721990564658703903787956958168449841491667690491585550160457893350536334242689
data=b'crypto{Immut4ble_m3ssag1ng}'
hash = hashlib.sha256(data)
s = pow(bytes_to_long(hash.digest()), d, n)
print(s)
#cái digest() này là lấy giá trị băm dưới dạng byte rồi su dụng hàm bytes_to_long để chuyển thành số nguyên
```
Kết quả:
> 13480738404590090803339831649238454376183189744970683129909766078877706583282422686710545217275797376709672358894231550335007974983458408620258478729775647818876610072903021235573923300070103666940534047644900475773318682585772698155617451477448441198150710420818995347235921111812068656782998168064960965451719491072569057636701190429760047193261886092862024118487826452766513533860734724124228305158914225250488399673645732882077575252662461860972889771112594906884441454355959482925283992539925713424132009768721389828848907099772040836383856524605008942907083490383109757406940540866978237471686296661685839083475

# Prime part 1
# Factoring
![image](https://hackmd.io/_uploads/SyYyb9Nn0.png)
**Factorise the 150-bit number 510143758735509025530880200653196460532653147 into its two constituent primes. Give the smaller one as your answer.**
Đề bài yêu cầu chúng ta phân tích số 150 bit thành 2 số nguyên tố cấu thành của nó và lấy số nhỏ hơn. Ví dụ 6=2*3 với 2 và 3 là số nguyên tố
với bài này chúng ta sẽ sử dụng công cụ trực tuyến để giải:
Vào đường link sau:
https://www.dcode.fr/prime-factors-decomposition
Điền số vào và đợi kết quả:
![image](https://hackmd.io/_uploads/H1N4HtuhC.png)

Chúng ta thu được 2 số là **19704762736204164635843**, **25889363174021185185929**
Vì để bài yêu cầu lấy số nhỏ hơn nên ta lấy **19704762736204164635843** và nộp.


# Inferius Prime
![image](https://hackmd.io/_uploads/HkjXM94nR.png)
Tải 2 file về chúng ta sẽ thu được như sau
![image](https://hackmd.io/_uploads/Sy45GqNn0.png)
 và
 ![image](https://hackmd.io/_uploads/ByeifqNhC.png)

 Chúng ta sẽ phân tích số n đề cho giống như bài trên để tìm p và q.
 ![image](https://hackmd.io/_uploads/B1gAQEqNh0.png)
với p,q và một số dữ kiện đề cho, ta có:
```python
from Crypto.Util.number import getPrime, inverse, bytes_to_long, long_to_bytes, GCD
n = 984994081290620368062168960884976209711107645166770780785733
e = 65537
ct = 948553474947320504624302879933619818331484350431616834086273
p=1160939713152385063689030212503
q=848445505077945374527983649411
phi=(p-1)*(q-1)
d = pow(e, -1, phi)
print(long_to_bytes(pow(ct, d, n)))

```
Kết quả thu được:
> **b'crypto{N33d_b1g_pR1m35}'**

Giải thích code:
Ở phần private key ở trên, chúng ta đã thấy được công thức M=$C^d$ mod N
Và d= $C^-1$ mod phi(N)
Với M là bản rõ, C trong bài là ct tức là cipher text(bản mã). Muốn tìm m thì chúng ta phải có được d, mà muốn có được d thì phải tìm phi(N) với p và q là 2 số nguyên tố tạo thành N.
Còn vì sao ở đoạn tìm flag phải dùng hàm long_to_byte thì hàm này sẽ chuyển một số nguyên lớn về các ký tự.

# Monoprime
![image](https://hackmd.io/_uploads/B1SOY54nA.png)
Đây là nội dung trong file:
![image](https://hackmd.io/_uploads/HkoqFcEh0.png)
Vì đề bài có kêu tại sao không sử dụng 1 số nguyên tố rồi nhân nó lên để được N, vậy chúng ta có thể thấy N được cấu thành từ 1 số nguyên tố hay là $p^2$=N
Vậy thì ta sẽ căn bậc 2 N lên để tìm p và q
dữ kiện tương tự bài trước nên chúng ta sẽ tận dụng code bài trước để làm:
```python
from Crypto.Util.number import  long_to_bytes

n = 171731371218065444125482536302245915415603318380280392385291836472299752747934607246477508507827284075763910264995326010251268493630501989810855418416643352631102434317900028697993224868629935657273062472544675693365930943308086634291936846505861203914449338007760990051788980485462592823446469606824421932591
e = 65537
ct = 161367550346730604451454756189028938964941280347662098798775466019463375610700074840105776873791605070092554650190486030367121011578171525759600774739890458414593857709994072516290998135846956596662071379067305011746842247628316996977338024343628757374524136260758515864509435302781735938531030576289086798942
phi= n-1

d = pow(e, -1, int(phi))
print(long_to_bytes(pow(ct, d, n)))
```
kết quả thu được:
> **b'crypto{0n3_pr1m3_41n7_pr1m3_l0l}'**

Giải thích code: Giống như bài trên, riêng phần phi tại sao bằng n-1 thì đây là 1 số nguyên tố mũ 2 lên để được N, vậy tức là phi(n)=(p-1)*(q-1) mà vì p=q nên ct sẽ là phi(N)= (p-1)*(p-1) = $(p-1)^2$ = $p^2$ -1
mà $p^2$ nó lại chính bằng N nên phi(N)=N-1

# Manyprime
![image](https://hackmd.io/_uploads/r18U6dd3A.png)
Không như bài trên chỉ sử dụng 1 số nguyên tố nữa ở bài này đề cho 30 số nguyên tố, dựa vào cách làm tương tự mấy bài trên kèm sử dụng vòng lặp thì ta sẽ giải được.
Bắt đầu với việc phân tích file đề cho:
![image](https://hackmd.io/_uploads/r1HRau_30.png)
Đem số N đi phân tích:
![image](https://hackmd.io/_uploads/Hk5ZCuu3A.png)
Chúng ta sẽ gom chúng vào 1 cái list, kết hợp khai báo biến, ta sẽ được chương trình như sau:
```python
from Crypto.Util.number import  long_to_bytes
phi = 1
n = 580642391898843192929563856870897799650883152718761762932292482252152591279871421569162037190419036435041797739880389529593674485555792234900969402019055601781662044515999210032698275981631376651117318677368742867687180140048715627160641771118040372573575479330830092989800730105573700557717146251860588802509310534792310748898504394966263819959963273509119791037525504422606634640173277598774814099540555569257179715908642917355365791447508751401889724095964924513196281345665480688029639999472649549163147599540142367575413885729653166517595719991872223011969856259344396899748662101941230745601719730556631637
e = 65537
ct = 320721490534624434149993723527322977960556510750628354856260732098109692581338409999983376131354918370047625150454728718467998870322344980985635149656977787964380651868131740312053755501594999166365821315043312308622388016666802478485476059625888033017198083472976011719998333985531756978678758897472845358167730221506573817798467100023754709109274265835201757369829744113233607359526441007577850111228850004361838028842815813724076511058179239339760639518034583306154826603816927757236549096339501503316601078891287408682099750164720032975016814187899399273719181407940397071512493967454225665490162619270814464
lst = [9282105380008121879, 9303850685953812323, 9389357739583927789, 10336650220878499841, 10638241655447339831, 11282698189561966721, 11328768673634243077, 11403460639036243901, 11473665579512371723, 11492065299277279799, 11530534813954192171, 11665347949879312361, 12132158321859677597, 12834461276877415051, 12955403765595949597, 12973972336777979701, 13099895578757581201, 13572286589428162097, 14100640260554622013, 14178869592193599187, 14278240802299816541, 14523070016044624039, 14963354250199553339, 15364597561881860737, 15669758663523555763, 15824122791679574573, 15998365463074268941, 16656402470578844539, 16898740504023346457, 17138336856793050757, 17174065872156629921, 17281246625998849649]

for i in lst:
    phi = (i-1)*phi
d = pow(e, -1, phi)
print(long_to_bytes(pow(ct, d, n)))
```
Kết quả thu được:
> **b'crypto{700_m4ny_5m4ll_f4c70r5}'**

Đoạn code trên chỉ cần giải thích đoạn phi = (i-1)*phi, mấy cái còn lại tương tự
Như ta đã biết thì $phi = (p-1)(q-1)$ với p và q là các số nguyên tố. Nhưng với nhiều số nguyên tố như bài này thì chúng ta cũng sẽ mở rộng cthuc tương tự: $phi(n)$=($p_1$ - 1) * ($p_2$ - 1)*($p_3$ - 1) * ... * ($p_n$ - 1)
với $n$=$p_1$ * $p_1$ *$p_2$ * $p_3$ * ... * $p_n$
Như vậy thì phi(n) sẽ nhân các số nguyên tố -1 của N, mà trong code thì
![image](https://hackmd.io/_uploads/rJHK7Y_2R.png)
Đó chính là cách thể hiện công thức tính phi với nhiều số nguyên tố trong code.

# Salty
![image](https://hackmd.io/_uploads/SkSbm7jhC.png)
Đây là file output của nó:
![image](https://hackmd.io/_uploads/S1zQXmonC.png)
Vì e=1 nên ta chuyển ct bằng long_to_byte
```python
from Crypto.Util.number import  long_to_bytes
n = 110581795715958566206600392161360212579669637391437097703685154237017351570464767725324182051199901920318211290404777259728923614917211291562555864753005179326101890427669819834642007924406862482343614488768256951616086287044725034412802176312273081322195866046098595306261781788276570920467840172004530873767
e = 1
ct = 44981230718212183604274785925793145442655465025264554046028251311164494127485
print(long_to_bytes(ct))
```
> **Flag thu được: crypto{saltstack_fell_for_this!}**

# Modulus Inutilis
![image](https://hackmd.io/_uploads/ryoM8Xs3A.png)
File text: 
![image](https://hackmd.io/_uploads/SJkV87sh0.png)
Vì e mũ 3 nên giờ chúng ta sẽ căn bậc 3 ct để tìm flag
Ta cần tải thư viện sympy về để tính toán.
**pip install sympy**
chúng ta sẽ có code như sau:
```python
import sympy
from Crypto.Util.number import long_to_bytes
n = 17258212916191948536348548470938004244269544560039009244721959293554822498047075403658429865201816363311805874117705688359853941515579440852166618074161313773416434156467811969628473425365608002907061241714688204565170146117869742910273064909154666642642308154422770994836108669814632309362483307560217924183202838588431342622551598499747369771295105890359290073146330677383341121242366368309126850094371525078749496850520075015636716490087482193603562501577348571256210991732071282478547626856068209192987351212490642903450263288650415552403935705444809043563866466823492258216747445926536608548665086042098252335883
e = 3
ct = 243251053617903760309941844835411292373350655973075480264001352919865180151222189820473358411037759381328642957324889519192337152355302808400638052620580409813222660643570085177957
flag = sympy.root(ct, e)
print(long_to_bytes(flag))

```
flag thu được: **crypto{N33d_m04R_p4dd1ng}**
# Prime part 2
# Infinity descent
![image](https://hackmd.io/_uploads/HJbMe_eT0.png)
Chúng ta có dữ liệu như sau:
> n = 383347712330877040452238619329524841763392526146840572232926924642094891453979246383798913394114305368360426867021623649667024217266529000859703542590316063318592391925062014229671423777796679798747131250552455356061834719512365575593221216339005132464338847195248627639623487124025890693416305788160905762011825079336880567461033322240015771102929696350161937950387427696385850443727777996483584464610046380722736790790188061964311222153985614287276995741553706506834906746892708903948496564047090014307484054609862129530262108669567834726352078060081889712109412073731026030466300060341737504223822014714056413752165841749368159510588178604096191956750941078391415634472219765129561622344109769892244712668402761549412177892054051266761597330660545704317210567759828757156904778495608968785747998059857467440128156068391746919684258227682866083662345263659558066864109212457286114506228470930775092735385388316268663664139056183180238043386636254075940621543717531670995823417070666005930452836389812129462051771646048498397195157405386923446893886593048680984896989809135802276892911038588008701926729269812453226891776546037663583893625479252643042517196958990266376741676514631089466493864064316127648074609662749196545969926051
e = 65537
c = 98280456757136766244944891987028935843441533415613592591358482906016439563076150526116369842213103333480506705993633901994107281890187248495507270868621384652207697607019899166492132408348789252555196428608661320671877412710489782358282011364127799563335562917707783563681920786994453004763755404510541574502176243896756839917991848428091594919111448023948527766368304503100650379914153058191140072528095898576018893829830104362124927140555107994114143042266758709328068902664037870075742542194318059191313468675939426810988239079424823495317464035252325521917592045198152643533223015952702649249494753395100973534541766285551891859649320371178562200252228779395393974169736998523394598517174182142007480526603025578004665936854657294541338697513521007818552254811797566860763442604365744596444735991732790926343720102293453429936734206246109968817158815749927063561835274636195149702317415680401987150336994583752062565237605953153790371155918439941193401473271753038180560129784192800351649724465553733201451581525173536731674524145027931923204961274369826379325051601238308635192540223484055096203293400419816024111797903442864181965959247745006822690967920957905188441550106930799896292835287867403979631824085790047851383294389

Giờ ném n vào tool trên dcode để tìm 2 số nguyên tố cấu thành nó:
![image](https://hackmd.io/_uploads/ryrIgOeaR.png)
Có p,q, ta tiến hành code để tìm flag:
```python
from Crypto.Util.number import  long_to_bytes

n = 383347712330877040452238619329524841763392526146840572232926924642094891453979246383798913394114305368360426867021623649667024217266529000859703542590316063318592391925062014229671423777796679798747131250552455356061834719512365575593221216339005132464338847195248627639623487124025890693416305788160905762011825079336880567461033322240015771102929696350161937950387427696385850443727777996483584464610046380722736790790188061964311222153985614287276995741553706506834906746892708903948496564047090014307484054609862129530262108669567834726352078060081889712109412073731026030466300060341737504223822014714056413752165841749368159510588178604096191956750941078391415634472219765129561622344109769892244712668402761549412177892054051266761597330660545704317210567759828757156904778495608968785747998059857467440128156068391746919684258227682866083662345263659558066864109212457286114506228470930775092735385388316268663664139056183180238043386636254075940621543717531670995823417070666005930452836389812129462051771646048498397195157405386923446893886593048680984896989809135802276892911038588008701926729269812453226891776546037663583893625479252643042517196958990266376741676514631089466493864064316127648074609662749196545969926051
e = 65537
c = 98280456757136766244944891987028935843441533415613592591358482906016439563076150526116369842213103333480506705993633901994107281890187248495507270868621384652207697607019899166492132408348789252555196428608661320671877412710489782358282011364127799563335562917707783563681920786994453004763755404510541574502176243896756839917991848428091594919111448023948527766368304503100650379914153058191140072528095898576018893829830104362124927140555107994114143042266758709328068902664037870075742542194318059191313468675939426810988239079424823495317464035252325521917592045198152643533223015952702649249494753395100973534541766285551891859649320371178562200252228779395393974169736998523394598517174182142007480526603025578004665936854657294541338697513521007818552254811797566860763442604365744596444735991732790926343720102293453429936734206246109968817158815749927063561835274636195149702317415680401987150336994583752062565237605953153790371155918439941193401473271753038180560129784192800351649724465553733201451581525173536731674524145027931923204961274369826379325051601238308635192540223484055096203293400419816024111797903442864181965959247745006822690967920957905188441550106930799896292835287867403979631824085790047851383294389
p=19579267410474709598749314750954211170621862561006233612440352022286786882372619130071639824109783540564512429081674132336811972404563957025465034025781206466631730784516337210291334356396471732168742739790464109881039219452504456611589154349427303832789968502204300316585544080003423669120186095188478480761108168299370326928127888786819392372477069515318179751702985809024210164243409544692708684215042226932081052831028570060308963093217622183111643335692361019897449265402290540025790581589980867847884281862216603571536255382298035337865885153328169634178323279004749915197270120323340416965014136429743252761521
q= 19579267410474709598749314750954211170621862561006233612440352022286786882372619130071639824109783540564512429081674132336811972404563957025465034025781206466631730784516337210291334356396471732168742739790464109881039219452504456611589154349427303832789968502204300316585544080003423669120186095188478480761108168299370326928127888786819392372477069515318179751702985809024210164243409544692708684215042226932081052831028570060308963093217622183111643335692362635203582868526178838018946986792656819885261069890315500550802303622551029821058459163702751893798676443415681144429096989664473705850619792495553724950931
phi=(p-1)*(q-1)
d = pow(e, -1, int(phi))
print(long_to_bytes(pow(c, d, n)))
```
Chương trình cho kết quả là:**b'crypto{f3rm47_w45_4_g3n1u5}'**
# Marin's Secrets
![image](https://hackmd.io/_uploads/HkApgOxaC.png)
Đề bài cho chúng ta dữ liệu sau:
```
n: 658416274830184544125027519921443515789888264156074733099244040126213682497714032798116399288176502462829255784525977722903018714434309698108208388664768262754316426220651576623731617882923164117579624827261244506084274371250277849351631679441171018418018498039996472549893150577189302871520311715179730714312181456245097848491669795997289830612988058523968384808822828370900198489249243399165125219244753790779764466236965135793576516193213175061401667388622228362042717054014679032953441034021506856017081062617572351195418505899388715709795992029559042119783423597324707100694064675909238717573058764118893225111602703838080618565401139902143069901117174204252871948846864436771808616432457102844534843857198735242005309073939051433790946726672234643259349535186268571629077937597838801337973092285608744209951533199868228040004432132597073390363357892379997655878857696334892216345070227646749851381208554044940444182864026513709449823489593439017366358869648168238735087593808344484365136284219725233811605331815007424582890821887260682886632543613109252862114326372077785369292570900594814481097443781269562647303671428895764224084402259605109600363098950091998891375812839523613295667253813978434879172781217285652895469194181218343078754501694746598738215243769747956572555989594598180639098344891175879455994652382137038240166358066403475457 
e: 65537
c: 400280463088930432319280359115194977582517363610532464295210669530407870753439127455401384569705425621445943992963380983084917385428631223046908837804126399345875252917090184158440305503817193246288672986488987883177380307377025079266030262650932575205141853413302558460364242355531272967481409414783634558791175827816540767545944534238189079030192843288596934979693517964655661507346729751987928147021620165009965051933278913952899114253301044747587310830419190623282578931589587504555005361571572561916866063458812965314474160499067525067495140150092119620928363007467390920130717521169105167963364154636472055084012592138570354390246779276003156184676298710746583104700516466091034510765027167956117869051938116457370384737440965109619578227422049806566060571831017610877072484262724789571076529586427405780121096546942812322324807145137017942266863534989082115189065560011841150908380937354301243153206428896320576609904361937035263985348984794208198892615898907005955403529470847124269512316191753950203794578656029324506688293446571598506042198219080325747328636232040936761788558421528960279832802127562115852304946867628316502959562274485483867481731149338209009753229463924855930103271197831370982488703456463385914801246828662212622006947380115549529820197355738525329885232170215757585685484402344437894981555179129287164971002033759724456
```

Làm tương tự như bài trên, ta có:
![image](https://hackmd.io/_uploads/S1QQMOea0.png)
Có p,q kèm dữ liệu như đề bài, ta tiến hành tìm flag:
```python
python
from Crypto.Util.number import  long_to_bytes
n= 658416274830184544125027519921443515789888264156074733099244040126213682497714032798116399288176502462829255784525977722903018714434309698108208388664768262754316426220651576623731617882923164117579624827261244506084274371250277849351631679441171018418018498039996472549893150577189302871520311715179730714312181456245097848491669795997289830612988058523968384808822828370900198489249243399165125219244753790779764466236965135793576516193213175061401667388622228362042717054014679032953441034021506856017081062617572351195418505899388715709795992029559042119783423597324707100694064675909238717573058764118893225111602703838080618565401139902143069901117174204252871948846864436771808616432457102844534843857198735242005309073939051433790946726672234643259349535186268571629077937597838801337973092285608744209951533199868228040004432132597073390363357892379997655878857696334892216345070227646749851381208554044940444182864026513709449823489593439017366358869648168238735087593808344484365136284219725233811605331815007424582890821887260682886632543613109252862114326372077785369292570900594814481097443781269562647303671428895764224084402259605109600363098950091998891375812839523613295667253813978434879172781217285652895469194181218343078754501694746598738215243769747956572555989594598180639098344891175879455994652382137038240166358066403475457
e=65537
c=400280463088930432319280359115194977582517363610532464295210669530407870753439127455401384569705425621445943992963380983084917385428631223046908837804126399345875252917090184158440305503817193246288672986488987883177380307377025079266030262650932575205141853413302558460364242355531272967481409414783634558791175827816540767545944534238189079030192843288596934979693517964655661507346729751987928147021620165009965051933278913952899114253301044747587310830419190623282578931589587504555005361571572561916866063458812965314474160499067525067495140150092119620928363007467390920130717521169105167963364154636472055084012592138570354390246779276003156184676298710746583104700516466091034510765027167956117869051938116457370384737440965109619578227422049806566060571831017610877072484262724789571076529586427405780121096546942812322324807145137017942266863534989082115189065560011841150908380937354301243153206428896320576609904361937035263985348984794208198892615898907005955403529470847124269512316191753950203794578656029324506688293446571598506042198219080325747328636232040936761788558421528960279832802127562115852304946867628316502959562274485483867481731149338209009753229463924855930103271197831370982488703456463385914801246828662212622006947380115549529820197355738525329885232170215757585685484402344437894981555179129287164971002033759724456
p=1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007
q=446087557183758429571151706402101809886208632412859901111991219963404685792820473369112545269003989026153245931124316702395758705693679364790903497461147071065254193353938124978226307947312410798874869040070279328428810311754844108094878252494866760969586998128982645877596028979171536962503068429617331702184750324583009171832104916050157628886606372145501702225925125224076829605427173573964812995250569412480720738476855293681666712844831190877620606786663862190240118570736831901886479225810414714078935386562497968178729127629594924411960961386713946279899275006954917139758796061223803393537381034666494402951052059047968693255388647930440925104186817009640171764133172418132836351
phi=(p-1)*(q-1)
d = pow(e, -1, int(phi))
print(long_to_bytes(pow(c, d, n)))
```
Output chương trình là: **b'crypto{Th3se_Pr1m3s_4r3_t00_r4r3}'**
# Fast Primes
![image](https://hackmd.io/_uploads/BJXYm_lpC.png)
key.pem:
```
-----BEGIN PUBLIC KEY-----
MFswDQYJKoZIhvcNAQEBBQADSgAwRwJATKIe3jfj1qY7zuX5Eg0JifAUOq6RUwLz
Ruiru4QKcvtW0Uh1KMp1GVt4MmKDiQksTok/pKbJsBFCZugFsS3AjQIDAQAB
-----END PUBLIC KEY-----
```

ciphertext.txt
```
249d72cd1d287b1a15a3881f2bff5788bc4bf62c789f2df44d88aae805b54c9a94b8944c0ba798f70062b66160fee312b98879f1dd5d17b33095feb3c5830d28
```

Từ file key.pem, chúng ta sẽ dùng nó để tìm n và e:
dưới đây là code:
```python
from Crypto.PublicKey import RSA
import base64

pem_data = '''
MFswDQYJKoZIhvcNAQEBBQADSgAwRwJATKIe3jfj1qY7zuX5Eg0JifAUOq6RUwLz
Ruiru4QKcvtW0Uh1KMp1GVt4MmKDiQksTok/pKbJsBFCZugFsS3AjQIDAQAB
''' # dữ liệu trong file key.pem đã xóa begin và end
decoded_data = base64.b64decode(pem_data)
rsa_key = RSA.import_key(decoded_data)
n = rsa_key.n

print(n)
```
Chúng ta có N sẽ là: 
```
4013610727845242593703438523892210066915884608065890652809524328518978287424865087812690502446831525755541263621651398962044653615723751218715649008058509
```
Đem đi phân tích thành 2 số nguyên tố cấu thành, ta được:
![image](https://hackmd.io/_uploads/By96Aux6A.png)
Đọc qua file mã nguồn đề cho, ta thấy có sử dụng OAEP để encode. 
```python
key = RSA.construct((n, e, d))
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(FLAG)

assert cipher.decrypt(ciphertext) == FLAG

exported = key.publickey().export_key()
with open("key.pem", 'wb') as f:
    f.write(exported)

with open('ciphertext.txt', 'w') as f:
    f.write(ciphertext.hex())
```
Có thể tận dụng dữ kiện này để viết code giải mã

**Dưới đây là đoạn code:**

```python
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Util.number import long_to_bytes

#Doc du lieu khoa trong file key.pem
key = RSA.importKey(open("key.pem", "rb").read())

e=  65537
n = 4013610727845242593703438523892210066915884608065890652809524328518978287424865087812690502446831525755541263621651398962044653615723751218715649008058509
p = 51894141255108267693828471848483688186015845988173648228318286999011443419469
q = 77342270837753916396402614215980760127245056504361515489809293852222206596161
phi = (p-1)*(q-1)
d = pow(e,-1,phi)
cp = "249d72cd1d287b1a15a3881f2bff5788bc4bf62c789f2df44d88aae805b54c9a94b8944c0ba798f70062b66160fee312b98879f1dd5d17b33095feb3c5830d28"
#tao khoa RSA tu n,e,d
key = RSA.construct((n, e, d))
cipher = PKCS1_OAEP.new(key) #Dùng với khóa RSA để thực hiện mã hóa và giải mã thông điệp theo chuẩn OAEP.
flag = cipher.decrypt(bytes.fromhex(cp))
print(flag)
```
Kết quả thu được là: **b'crypto{p00R_3570n14}'**
# Ron was wrong, whit is right
![image](https://hackmd.io/_uploads/BkfS-KxpC.png)
Down 2 file về ta thấy:
file zip:
![image](https://hackmd.io/_uploads/BkMPWKlaC.png)
(có một đống file trong này)

Chúng ta xem xét qua file mã nguồn đề cho:

```python
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA


msg = "???"

with open('21.pem') as f:
    key = RSA.importKey(f.read())

cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(msg)

with open('21.ciphertext', 'w') as f:
    f.write(ciphertext.hex())
```
Ta thấy trong code có yêu cầu mở file 21.pem và 21.ciphertext. Vậy hãy thử làm như bài trên xem có ra flag không
Code tính N:
```python
from Crypto.PublicKey import RSA
import base64

# PEM-formatted public key (Base64-encoded)
pem_data = '''
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA1dlvn9lQ5f+ZsWc1iPw6
HVY487KX7ASSJhZ4VMUGGkD+YVQnhTXLS7NWyL6qHu9tbx5pzyyC4jT65CjEeRaV
XTswGdH/kicZBLjBKUh0iayUfzASs4rYe3G62noWTDAtHs3+VBDMxGid+/TsgoxK
Qo/eTG7Evci9MdDUAgHhXAqQfM4Ot/HWlxogwikAs7SDyaZLNkxZFEKcqrS81udT
Nm0lsUceoNXBxb662iqFJN8Q7S4XYjYaDnScZdWc8HwhDnqStBJ1ATvVIXM9+AB3
rNlJ+GVG3kE7Azh59+1kKqdVRf9Zl0Ch65JUMLEpTKRQuBJxLzY2MbmbcxIv5bbB
EPz6a3iTQtquE49nqx07fEcxNoL1vCBa//MS4fBXYwTIT3W1irM8HQxB76MUlzp4
mSZnxHNWbLuA4kP79qwIzcxh1aUDYRYMp3mGlnJzLlUqhQJenFr5piNq03l1lRix
dCIjtso6eFgNv+MD1ndYsqL2ktFC0u6kvOVbyL4roW1m1STXcis5/BWTtnxe/o3m
TFClvzfvi6BWdK5m7vJ7Pp6bE8FEei81SBTGNX0B+K6W3DiaDOzwTr9amTaRzbSA
LtpXUBHbFEpKYlbBgCvX8uIB6L8IS5XQPtnPu+3dKXczLXu/hIRzJf6KQqwbL/xT
d6sSeXV/4t96dvtGoXh/fMR2CpHfSH5j3Akij9uQapvHwNyiL4t7Bd2+J3tYd0aX
94pg3wWtHhzXK5YEukLifyCh1Wf+T1EPD5d0sNKvCuFpzHHHPf6gGT2riWmgUv+Z
/eBrUJOSjEp7SD36JXML22T+rUT3ZGh76fzgjMpB1TUeY39OsmTPpNVEaymefxR8
8hxkpEed6PJTL58mj3ACFP+ZAX0DZMap6hReBqkZ+Y2KUbKmAeCDCMHwUGIekWZg
lRAKj0oqCyFpIv0abBc2SrEK1J9v5J2q/X4nk+uffHA+YhIt3q4r9kRryvzXc6+t
Qm1uggdgkrEM3zTtSPRhBsbqw2zjzTvy2naCUaFVKHoy/3clgR47zQUnYWp1epQg
cpPwjgQIipyA4d9gQx4eJq4pv/bal0zoDLFVwOMZINVl8S37lnffqjSmsmLMv6fa
pnPkcyXvxFWjtl8ltf7fzWPWGpJYdohtqxDr3Y1eXza53iSAnGUApQ/uwTPgTKhJ
DlF8M5lSLrUC2faYP229ySm/mf+u9XPudAZ26qW93aAQ8Seg9WCHWuCYXQapBiV6
wI1V6eU0TPXMKIElFe5qlBLrbuSm+i12qaMXuWC53yX4jLD/NILdrpvzELeM+426
BMUhR4Dvy+U64DjH+f9DjG9eI52ldA5lGLHS169mbQx+Zc108dyEc5MjRinPkXJu
jwIDAQAB
'''
decoded_data = base64.b64decode(pem_data)
rsa_key = RSA.import_key(decoded_data)
modulus_n = rsa_key.n

print("Modulus (n):", modulus_n)

```
có N thu được là: 
```
911155430397089868893710399679843124299455958854629791471074639340378853507919464565810613293797452094094419935791316019378845266444423939069591777393674738696600039645897332187483027169161226989463007958162660511833293293934680580795884835915313555665028500273978111975141483711972416976051841007136079560842930618009244952633494357039685233438172831394231820157810045590724112193897315806153435024753655632608473402805617714869872186030635147363770587791422138471720933891531786826222624075389616924907447441888709731985493341989380909384044148308972895318737298279201161927233884653041034925026221365261861897721220653242120761984486476073104852961087732061243614950426772704615616351403821143864605052161365099625909493963610940101256661638103038287477307037516480655622483809303973844914111675448758165915304217110383740650242709810054890529380273089938565187583433898011098193322584247150816917331201462582657698512259466266467891678088041219884140157617779080424490085443389141752344203813840060106563190054773064792934495477729541544277637486134526425276923313072437402635187015371607927851364757573804279682763676084186465911588299208965058610144991287224616962493760669148885986144273990509506917829875014575681080262558165579783076765660193031162935128415991494869107015989320398687972326200569107240071210145877231390571616043489752316478596708456751559975181688088516026334899322294703865900392081637370670610001746419748464485461186336107253585654909405811415364943187972977795714207432456907751605269930478002755232084922463849167034964311000757003822836396625765900984940363082552313118484509184504317922624334876645052025073648609570099819847985458003040099734106611690135903402566586049952555685885129167949699135190659447558932337919259697368802685025241864769010304936839822392261403853930937011037322345944122791531705024153346939404340299053282463816135162799746979069053739021760882877630867181836643699922817756581868559378190317154945587598406935787422788156408738900082828687918258191147242549110812512887371014023446801086634829279768440364090252588453227384663956539541609351183298197012676011524752900153903629441235349425281050546200540159001545754825292288245399374715709620586639621734512134963505768992518699532365136633077433424884644404975480104687269688186070343890063473871474522626591333445128238108321171232365531356095520991346873717177021044283092373174179512606967225038176778565236701000826596381944707372969518852801195663
```
Giờ đem đi phân tích ta sẽ được 2 số nguyên tố.
> 919031168254299342928662994540730760042229248845820491699169870943314884504551963184014786520812939038906152950817942941469675496074887272906954399256046690838233813273902630076899906873722574023918253104149453601408405078374008695616160025877687382663027910687942091698042309812910101246025081363544171351624307177908410700904833438480012985928358897861427063761678614898919524867442676631453135379994570031284289815099294504127712924001149921480778993635917803466637717023744788311275545126346774536416864472035644211758788016642401235014385037912224180351022196262011724157012443048941426178651665266181311662824205620324073087330858064769424755443807165558567191049013947419763315902476674266627953223373671797370373786249718677582213173537848582863398367624397247597103174897140005790273296171101569756006898658668311846034013183862374297777882433967015111727139360441681664840944403450472574336901043555319067050153928231938431298082827397506406624964952344826628463723499263165279281720105570577138817805451223334196017505528543229067732013216932022575286870744622250293712218581458417969597311485156075637589299870500738770767213366940656708757081771498126771190548298648709527029056697749965377697006723247968508680596118923, 991430390905926023965735525726256769345153760248048478891327804533279477721590201738061124861790305326884541900044434890157058142414306020739922709698601329762087825767461256626800629782378634339618941488765491437487541851308806651586976069659042714378353883168031522106709494592827914376213512564492771821921367377484213072867988877925314809325159382342584541006645302760204539354879391605736604946702073863673524002591877977949645618863730441482821840664748508050205004505250025193611888170440612737112479006348533153568103452396596042639466753099280111709882461562564978070397786887446291916733276692400981917025361391646188802038772976331121474570242334921390569285834250256522656433623912544555266998750630136756355560927237594975904642791712318215315246754105993145827690531584325461597482035600919501967088106457091199733024323755210212616553447076697617349235377466327471959683763796707566328536834402308887105044128592177681553611608618850780128709949316259039664054913946726480968288231015999572777436469163437066403964134928735809253108394078092917006632332098357725950865697047565284013456253933234017983509582245874130968218422573483012858388392588302838940565560162598810462310034964473576147200222580784694005333482381

Làm y hệt bài trên ta được:

```python
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Util.number import long_to_bytes

#Doc du lieu khoa trong file key.pem
key = RSA.importKey(open("21.pem", "rb").read())

e=  65537
n = 911155430397089868893710399679843124299455958854629791471074639340378853507919464565810613293797452094094419935791316019378845266444423939069591777393674738696600039645897332187483027169161226989463007958162660511833293293934680580795884835915313555665028500273978111975141483711972416976051841007136079560842930618009244952633494357039685233438172831394231820157810045590724112193897315806153435024753655632608473402805617714869872186030635147363770587791422138471720933891531786826222624075389616924907447441888709731985493341989380909384044148308972895318737298279201161927233884653041034925026221365261861897721220653242120761984486476073104852961087732061243614950426772704615616351403821143864605052161365099625909493963610940101256661638103038287477307037516480655622483809303973844914111675448758165915304217110383740650242709810054890529380273089938565187583433898011098193322584247150816917331201462582657698512259466266467891678088041219884140157617779080424490085443389141752344203813840060106563190054773064792934495477729541544277637486134526425276923313072437402635187015371607927851364757573804279682763676084186465911588299208965058610144991287224616962493760669148885986144273990509506917829875014575681080262558165579783076765660193031162935128415991494869107015989320398687972326200569107240071210145877231390571616043489752316478596708456751559975181688088516026334899322294703865900392081637370670610001746419748464485461186336107253585654909405811415364943187972977795714207432456907751605269930478002755232084922463849167034964311000757003822836396625765900984940363082552313118484509184504317922624334876645052025073648609570099819847985458003040099734106611690135903402566586049952555685885129167949699135190659447558932337919259697368802685025241864769010304936839822392261403853930937011037322345944122791531705024153346939404340299053282463816135162799746979069053739021760882877630867181836643699922817756581868559378190317154945587598406935787422788156408738900082828687918258191147242549110812512887371014023446801086634829279768440364090252588453227384663956539541609351183298197012676011524752900153903629441235349425281050546200540159001545754825292288245399374715709620586639621734512134963505768992518699532365136633077433424884644404975480104687269688186070343890063473871474522626591333445128238108321171232365531356095520991346873717177021044283092373174179512606967225038176778565236701000826596381944707372969518852801195663
p = 919031168254299342928662994540730760042229248845820491699169870943314884504551963184014786520812939038906152950817942941469675496074887272906954399256046690838233813273902630076899906873722574023918253104149453601408405078374008695616160025877687382663027910687942091698042309812910101246025081363544171351624307177908410700904833438480012985928358897861427063761678614898919524867442676631453135379994570031284289815099294504127712924001149921480778993635917803466637717023744788311275545126346774536416864472035644211758788016642401235014385037912224180351022196262011724157012443048941426178651665266181311662824205620324073087330858064769424755443807165558567191049013947419763315902476674266627953223373671797370373786249718677582213173537848582863398367624397247597103174897140005790273296171101569756006898658668311846034013183862374297777882433967015111727139360441681664840944403450472574336901043555319067050153928231938431298082827397506406624964952344826628463723499263165279281720105570577138817805451223334196017505528543229067732013216932022575286870744622250293712218581458417969597311485156075637589299870500738770767213366940656708757081771498126771190548298648709527029056697749965377697006723247968508680596118923
q = 991430390905926023965735525726256769345153760248048478891327804533279477721590201738061124861790305326884541900044434890157058142414306020739922709698601329762087825767461256626800629782378634339618941488765491437487541851308806651586976069659042714378353883168031522106709494592827914376213512564492771821921367377484213072867988877925314809325159382342584541006645302760204539354879391605736604946702073863673524002591877977949645618863730441482821840664748508050205004505250025193611888170440612737112479006348533153568103452396596042639466753099280111709882461562564978070397786887446291916733276692400981917025361391646188802038772976331121474570242334921390569285834250256522656433623912544555266998750630136756355560927237594975904642791712318215315246754105993145827690531584325461597482035600919501967088106457091199733024323755210212616553447076697617349235377466327471959683763796707566328536834402308887105044128592177681553611608618850780128709949316259039664054913946726480968288231015999572777436469163437066403964134928735809253108394078092917006632332098357725950865697047565284013456253933234017983509582245874130968218422573483012858388392588302838940565560162598810462310034964473576147200222580784694005333482381
phi = (p-1)*(q-1)
d = pow(e,-1,phi)
cp = "c62d91677825632cb8ac9d2fbee7490fca70b3f067bd8d811fa446a21001de7943cacafc429b2513d3f20c3224d212ca2937a4a4ea10792a1c498b791e978e4b050b525576bc68421e40d9f420c0b8a07778daf69edf2095bf48222896bb2d6581288ce7a2e7aec15a88a440ff1a1e48beb56f68b4f860d1f64a6ec8cafed90846b7d893bc482df69c8478d5a0d6fc2d043cdd97178740a9eb59d2576b5136200c8ea77e648c88e6c5104ca5d0c6add2fc2c8569ce909f8461e7fa3d901fe67eaeff656399d4751fedba9973e246427e0c7a217f5bdc3edcb5033f17b5ef53419e340355a809eb46f48f538e880abd6f72212b02d3dbf2c4f633a503e648d1a835c4574b23e329e1c51078ea7cbb7533e771899498d4a5760bc0799b7e046f268f098fe0b57de47cd70ccf01ad3c9daec5027f306141bfe7a6c0bd29ee6caf94c7433c25e34ee974005e2360337cb6b3cec5eaf5d31d19f01435f4cdcaa455a18e78dee078395b8ad14b9c3a0d817dc1e3109c7b8af35ab3a5950bf47d5e621f9373ef421540052aac307ecea91f9c29c14bfd81b41d4c5a9b34a8ec2fa1ae06c3d881f39286c3d8dbb1849602fecc27bb135f7dd443e2598d247d1182d350b04be1ac0a734cb0e852a36902d88066ac375a35e279b126e413a97aaa35a0ba933f7b8d574c298332ce428c181464b240709a414af1b77103441b6ccfd0790eccea5926844054903c83f4cb415d600a6b7bc771c9e7a86394a2b427ebe8edec08b8095f561827716898e11caf6f0fe562af8a69f7b6469f0e86bdcc32f429f10821c763b34307efc5b2ae7fd524a07e5d0b762c096f025a3f240fb7bd3554582dcce32c175867d93970b0422e17870ec58f2a305545a3d284b3abb2d21a45ad8fd5faed0dc66312a5aa2f994606a51cd6682acd48ea3fb883f0611e1e5c2fb4047b5c80815ba5d3bcfefaf121bfde4d5c91ee27bb899ef0d29fa5c6dc4223ac2bfcff0217d08579a13e9b02dc97aa2622df62eeaaa38bb3bd087cdd209f03e8926a951e90eaa0f678a252a067ac66402a4c85865931689ed3b33f9f6de0c499f140ef508dfba6007a607a271dcbec18a61f7488bba34d143f93bc259310ffbf23f3391734d8d8811a4be8abf6382e55c2ccbfd80b1559d907fd8d46e0431cdbcd8fdb06d57973437f7b8ff5efc5a53c80d552e8fe622971f7376eeea35f4df9b32ada93e531a52b63ba13f6b7bf61ab337d6d93feb0e8c8a309dfa7e5f50e8cf9655b73ae64822b50db5312f35f4718b0668305065ea283ddf8f0a4e8f486ee9d119ebc584be1837b3d959a25ace208ffac2fb703390a72d3027b64fdd1955b513c0403f09232efa1794a277e0be3f4f9f3a6fd23c6e52101e723cef5db7a2a18a107cd522379adb40c5ed36b26cdf53a1000d7d576f1157b42aac3d3ee011275"
#tao khoa RSA tu n,e,d
key = RSA.construct((n, e, d))
cipher = PKCS1_OAEP.new(key)
flag = cipher.decrypt(bytes.fromhex(cp))
print(flag)
```
đáp án ta thu được là: **b"crypto{3ucl1d_w0uld_b3_pr0ud} If you haven't already, check out https://eprint.iacr.org/2012/064.pdf"**

# RSA Backdoor Viability
![image](https://hackmd.io/_uploads/Bkg_VFxp0.png)
Nội dung tệp đề cho:
```python
#!/usr/bin/env python3

import random
from Crypto.Util.number import bytes_to_long, getPrime, isPrime

FLAG = b"crypto{????????????????????????????????}"

def get_complex_prime():
    D = 427
    while True:
        s = random.randint(2 ** 1020, 2 ** 1021 - 1)
        tmp = D * s ** 2 + 1
        if tmp % 4 == 0 and isPrime((tmp // 4)):
            return tmp // 4


m = bytes_to_long(FLAG)
p = get_complex_prime()
q = getPrime(2048)
n = p * q
e = 0x10001
c = pow(m, e, n)

print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
```
```
n = 709872443186761582125747585668724501268558458558798673014673483766300964836479167241315660053878650421761726639872089885502004902487471946410918420927682586362111137364814638033425428214041019139158018673749256694555341525164012369589067354955298579131735466795918522816127398340465761406719060284098094643289390016311668316687808837563589124091867773655044913003668590954899705366787080923717270827184222673706856184434629431186284270269532605221507485774898673802583974291853116198037970076073697225047098901414637433392658500670740996008799860530032515716031449787089371403485205810795880416920642186451022374989891611943906891139047764042051071647203057520104267427832746020858026150611650447823314079076243582616371718150121483335889885277291312834083234087660399534665835291621232056473843224515909023120834377664505788329527517932160909013410933312572810208043849529655209420055180680775718614088521014772491776654380478948591063486615023605584483338460667397264724871221133652955371027085804223956104532604113969119716485142424996255737376464834315527822566017923598626634438066724763559943441023574575168924010274261376863202598353430010875182947485101076308406061724505065886990350185188453776162319552566614214624361251463
e = 65537
c = 608484617316138126443275660524263025508135383745665175433229598517433030003704261658172582370543758277685547533834085899541036156595489206369279739210904154716464595657421948607569920498815631503197235702333017824993576326860166652845334617579798536442066184953550975487031721085105757667800838172225947001224495126390587950346822978519677673568121595427827980195332464747031577431925937314209391433407684845797171187006586455012364702160988147108989822392986966689057906884691499234298351003666019957528738094330389775054485731448274595330322976886875528525229337512909952391041280006426003300720547721072725168500104651961970292771382390647751450445892361311332074663895375544959193148114635476827855327421812307562742481487812965210406231507524830889375419045542057858679609265389869332331811218601440373121797461318931976890674336807528107115423915152709265237590358348348716543683900084640921475797266390455366908727400038393697480363793285799860812451995497444221674390372255599514578194487523882038234487872223540513004734039135243849551315065297737535112525440094171393039622992561519170849962891645196111307537341194621689797282496281302297026025131743423205544193536699103338587843100187637572006174858230467771942700918388
```
Có N ta đi phân tích 2 số nguyên tố:
```
p=20365029276121374486239093637518056591173153560816088704974934225137631026021006278728172263067093375127799517021642683026453941892085549596415559632837140072587743305574479218628388191587060262263170430315761890303990233871576860551166162110565575088243122411840875491614571931769789173216896527668318434571140231043841883246745997474500176671926153616168779152400306313362477888262997093036136582318881633235376026276416829652885223234411339116362732590314731391770942433625992710475394021675572575027445852371400736509772725581130537614203735350104770971283827769016324589620678432160581245381480093375303381611323
q=34857423162121791604235470898471761566115159084585269586007822559458774716277164882510358869476293939176287610274899509786736824461740603618598549945273029479825290459062370424657446151623905653632181678065975472968242822859926902463043730644958467921837687772906975274812905594211460094944271575698004920372905721798856429806040099698831471709774099003441111568843449452407542799327467944685630258748028875103444760152587493543799185646692684032460858150960790495575921455423185709811342689185127936111993248778962219413451258545863084403721135633428491046474540472029592613134125767864006495572504245538373207974181
```
Ta sẽ thử làm như bình thường, vì đây không có file pem hay gì cả.
```python
from Crypto.Util.number import long_to_bytes
n = 709872443186761582125747585668724501268558458558798673014673483766300964836479167241315660053878650421761726639872089885502004902487471946410918420927682586362111137364814638033425428214041019139158018673749256694555341525164012369589067354955298579131735466795918522816127398340465761406719060284098094643289390016311668316687808837563589124091867773655044913003668590954899705366787080923717270827184222673706856184434629431186284270269532605221507485774898673802583974291853116198037970076073697225047098901414637433392658500670740996008799860530032515716031449787089371403485205810795880416920642186451022374989891611943906891139047764042051071647203057520104267427832746020858026150611650447823314079076243582616371718150121483335889885277291312834083234087660399534665835291621232056473843224515909023120834377664505788329527517932160909013410933312572810208043849529655209420055180680775718614088521014772491776654380478948591063486615023605584483338460667397264724871221133652955371027085804223956104532604113969119716485142424996255737376464834315527822566017923598626634438066724763559943441023574575168924010274261376863202598353430010875182947485101076308406061724505065886990350185188453776162319552566614214624361251463
e = 65537
c = 608484617316138126443275660524263025508135383745665175433229598517433030003704261658172582370543758277685547533834085899541036156595489206369279739210904154716464595657421948607569920498815631503197235702333017824993576326860166652845334617579798536442066184953550975487031721085105757667800838172225947001224495126390587950346822978519677673568121595427827980195332464747031577431925937314209391433407684845797171187006586455012364702160988147108989822392986966689057906884691499234298351003666019957528738094330389775054485731448274595330322976886875528525229337512909952391041280006426003300720547721072725168500104651961970292771382390647751450445892361311332074663895375544959193148114635476827855327421812307562742481487812965210406231507524830889375419045542057858679609265389869332331811218601440373121797461318931976890674336807528107115423915152709265237590358348348716543683900084640921475797266390455366908727400038393697480363793285799860812451995497444221674390372255599514578194487523882038234487872223540513004734039135243849551315065297737535112525440094171393039622992561519170849962891645196111307537341194621689797282496281302297026025131743423205544193536699103338587843100187637572006174858230467771942700918388
p=20365029276121374486239093637518056591173153560816088704974934225137631026021006278728172263067093375127799517021642683026453941892085549596415559632837140072587743305574479218628388191587060262263170430315761890303990233871576860551166162110565575088243122411840875491614571931769789173216896527668318434571140231043841883246745997474500176671926153616168779152400306313362477888262997093036136582318881633235376026276416829652885223234411339116362732590314731391770942433625992710475394021675572575027445852371400736509772725581130537614203735350104770971283827769016324589620678432160581245381480093375303381611323
q=34857423162121791604235470898471761566115159084585269586007822559458774716277164882510358869476293939176287610274899509786736824461740603618598549945273029479825290459062370424657446151623905653632181678065975472968242822859926902463043730644958467921837687772906975274812905594211460094944271575698004920372905721798856429806040099698831471709774099003441111568843449452407542799327467944685630258748028875103444760152587493543799185646692684032460858150960790495575921455423185709811342689185127936111993248778962219413451258545863084403721135633428491046474540472029592613134125767864006495572504245538373207974181
phi=(p-1)*(q-1)
d=pow(e,-1,phi)
flag = pow(c, d, n)
print(long_to_bytes(flag))
```
may mắn sao, ta thu được output là:
**b'crypto{I_want_to_Break_Square-free_4p-1}'**