Tags: python rsa 

Rating:

## RSA (crypto, 100p)

### PL Version
`for ENG version scroll down`

Zadanie polegało na odszyfrowaniu wiadomości szyfrowanej za pomocą RSA mając dostęp do klucza publicznego. Wiadomość to:

`kPmDFLk5b/torG53sThWwEeNm0AIpEQek0rVG3vCttc=`

A klucz:

-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALYtzp8lgWNXI9trGI8S8EacvuDLxdrL
NsNuDJa26nv8AgMBAAE=
-----END PUBLIC KEY-----

Zadanie wspomniało też, że klucz publiczny nie jest całkiem poprawny i brakuje mu jakiegoś bitu.
Dekodujemy klucz publiczny i uzyskujemy:

n = 82401872610398250859431855480217685317486932934710222647212042489320711027708
e = 65537

Widzimy od razu że wartość `n` jest niepoprawna bo nie jest iloczynem 2 liczb pierwszych (dzieli się przez 4). Zamieniamy więc ostatni bit z 0 na 1 uzyskując liczbę `82401872610398250859431855480217685317486932934710222647212042489320711027709`

Klucz jest bardzo krótki - ma tylko 256 bitów co oznacza, że jest podatny na faktoryzację. Dokonujemy jej za pomocą narzędzia `yafu`:

![](./rsa.png)

Na tej podstawie uzyskujemy liczby `p` oraz `q` potrzebne do odtworzenia klucza prywatnego. Dokonujemy tego za pomocą rozszerzonego algorytmu Euklidesa:

def egcd(a, b):
u, u1 = 1, 0
v, v1 = 0, 1
while b:
q = a // b
u, u1 = u1, u - q * u1
v, v1 = v1, v - q * v1
a, b = b, a - q * b
return a, u, v

q = 295214597363242917440342570226980714417
p = 279125332373073513017147096164124452877
e = 65537
n = 82401872610398250859431855480217685317486932934710222647212042489320711027709
phi = (p - 1) * (q - 1)
gcd, a, b = egcd(e, phi)
d = a
if d < 0:
d += phi
print("n: " + str(d))

Mając liczbę `d` możemy teraz dokonać dekodowania wiadomości. Zamieniamy wiadomość na liczbę:

`ct = 65573899802596942877560813284504892432930279657642337826069076977341847221975`

A następnie wykonujemy:

pt = pow(ct, d, n)
print("pt: " + long_to_bytes(pt))

I uzyskujemy flagę: `TMCTF{$@!zbo4+qt9=5}`

### ENG Version

The task was to crack RSA encoded message based on provided public key. The message was:

`kPmDFLk5b/torG53sThWwEeNm0AIpEQek0rVG3vCttc=`

And the key was:

-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALYtzp8lgWNXI9trGI8S8EacvuDLxdrL
NsNuDJa26nv8AgMBAAE=
-----END PUBLIC KEY-----

The task description mentioned that there is something wrong with public key and there is a bit missing.
We decode the public key and we get:

n = 82401872610398250859431855480217685317486932934710222647212042489320711027708
e = 65537

We can clearly see that the `n` is incorrect since it's not a product of 2 prime numbers (it is divisible by 4). We swtich last bit from 0 to 1 and we get `82401872610398250859431855480217685317486932934710222647212042489320711027709`

The key is very short - only 256 bits so we can factor it. We do it using `yafu`:

![](./rsa.png)

Based on this we get `p` and `q` numbers required for private key recovery. We do this with extended euclidean algorithm:

def egcd(a, b):
u, u1 = 1, 0
v, v1 = 0, 1
while b:
q = a // b
u, u1 = u1, u - q * u1
v, v1 = v1, v - q * v1
a, b = b, a - q * b
return a, u, v

q = 295214597363242917440342570226980714417
p = 279125332373073513017147096164124452877
e = 65537
n = 82401872610398250859431855480217685317486932934710222647212042489320711027709
phi = (p - 1) * (q - 1)
gcd, a, b = egcd(e, phi)
d = a
if d < 0:
d += phi
print("n: " + str(d))

With the `d` number we can now decode the message. We change the message into a number:

`ct = 65573899802596942877560813284504892432930279657642337826069076977341847221975`

Execute:

pt = pow(ct, d, n)
print("pt: " + long_to_bytes(pt))

And get the flag: `TMCTF{$@!zbo4+qt9=5}`

Original writeup (https://github.com/p4-team/ctf/tree/master/2015-09-26-trendmicro/rsa#eng-version).