Tags: polynomials rsa
## Decent RSA
> RSA can be decent as well!
> **Note** Although this task is very decent and solvable with focusing on the module number, you may use any tools, guessing, or whatever you know to solve it!
- See that when written in base 11, the modulus is mainly zeros
- Write the modulus as a polynomial in base 11 and factor the polynomial
- Solve RSA
All we are given is a RSA public key
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
and some encrypted data.
From the `.pem` we get
RSA Public Key [21:5d:61:5d:7e:ef:d0:58:12:d0:dc:14:bd:7c:e1:69:eb:77:01:f0]
public exponent: 10001
where the modulus is some `2048` bit integer. As we are given a `X.509` key, esrever suggested looking at a database of [predictable RSA keys](https://github.com/g0tmi1k/debian-ssh), which contains 30k public keys which were insecure. We downloaded these and looked for a common factor between our common modulus and one of these known, weak keys. We didnt have any luck though.
Another idea was that maybe this would be solved with Fermat factorisation, with "Decent RSA" being a pun for the infinite decent method. I let the algorithm run for a while but eventually killed it.
The solution came from looking at the modulus in various bases. My initial hope was that the primes might be Mersenne primes, which would be exposed by looking at the modulus in base 2, but it turns our the right base for the solve is base 11.
We can then write `N` as a polynomial in the following way
sage: poly = sum(e * x^i for i,e in enumerate(N.digits(11)))
x^592 + x^589 + 2*x^559 + x^547 + 2*x^501 + 2*x^498 + 2*x^492 + 2*x^475 + 2*x^472 + 4*x^468 + 2*x^456 + 4*x^444 + 4*x^442 + 2*x^430 + 2*x^420 + 4*x^401 + 4*x^375 + 8*x^353 + 4*x^329 + 8*x^327 + 2*x^311 + 4*x^303 + 6*x^296 + 2*x^293 + 4*x^263 + 2*x^251 + 4*x^220 + 8*x^205 + 4*x^196 + 4*x^194 + 8*x^179 + 8*x^148 + 4*x^124 + 4*x^15 + 8
Which sage very quickly can factor
(x^296 + x^293 + 2*x^263 + x^251 + 2*x^196 + 4*x^148 + 2*x^124 + 2*x^15 + 4)*(x^296 + 2*x^205 + 2*x^179 + 2)
Setting `x = 11` will return the primes `p*q = N`, solving the challenge.
from Crypto.PublicKey import RSA
from Crypto.Util.number import long_to_bytes, bytes_to_long
flag = bytes_to_long(open("flag.enc","rb").read())
key = RSA.import_key(open("mykey.pem").read())
n = Integer(key.n)
poly = sum(e * x^i for i,e in enumerate(Integer(key.n).digits(11)))
(p, _), (q, _) = poly.factor_list()
p, q = p(x=11), q(x=11)
assert p*q == n
d = inverse_mod(key.e, (p-1)*(q-1))
print(long_to_bytes(pow(flag, d, n)))