How to crack a 4096 RSA private key

The Fermat’s Factorization Algorithm, attributed to the renowned French mathematician Pierre de Fermat, is a historical method specifically designed for breaking down the product of two large prime numbers into its prime factors.
Let’s say we have the following 4096 Bit RootCA-Certificate (or any other RSA certificate):
'-----BEGIN CERTIFICATE-----\n\
MIIFcTCCA1mgAwIBAgIIKHPI3kXlIHEwDQYJKoZIhvcNAQENBQAwRjELMAkGA1UE\
BhMCREUxGjAYBgNVBAoMEVNvbWVfT3JnYW5pemF0aW9uMRswGQYDVQQDExJNYXJj\
byBTdGllZ2VsbWFpZXIwHhcNMjMwMjA4MTI0NTAwWhcNMzMwMjA4MTI0NTAwWjBG\
MQswCQYDVQQGEwJERTEaMBgGA1UECgwRU29tZV9Pcmdhbml6YXRpb24xGzAZBgNV\
BAMTEk1hcmNvIFN0aWVnZWxtYWllcjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\
AgoCggIBAM32Y07HDEe6hYMO5iX9LOhFh14hhiffA6KEmIYZUP0F8SREGCs8EnSt\
sNnQ7EEFge8Ka7EGjD13uaTb39MPYK+zobiK+3oP6ZgNsEhydDY9JeXy17asVh+e\
Mp2yrEQsyTTiQ86pJo6XE6PpEZdGjxMjdSt9n50ydqKIVXJ+v0M3Szm98ZymjQxq\
5qGgJOtmO6KVUYczYdqYetBLZvT9zvzQmFL/lynSveGMfJxNVroUEDpZdUw91nXF\
c4htiixMzMk3u859OhJm5SXvNrWOVhcokWEZIRJIrReR2pMr6Qp6qoIIlJWDH5MA\
gNP8z6ytBHKCAaKNn8vvcm/8NoE8VXRNj5HbcN+Q7UuIytWJs77Ea8iK56xfi0Nc\
0fITRGeiKrDvtmbHUzuBrceadehuZjl97MJo2qr59wZiH383xqYhGCZQGLIpXIEt\
0nweKchuQfWnwaiSZMKIGWcLZhOGSsAU+mPkS28J2Cm4QSyq8WR2v5ANoAlO7zAe\
cR5fVB+l38rThcBZZZjGrBGshwo2cIp0T1o5LjkddwFrL3ZoVjO9j3Xd+RUwPabK\
NC4JqGQUvSeJcXJ7wz1DSvfTSPDZhxApWtsVfNc7dDtvRoSfVAqnAbtx1ShPNlsw\
EUnWT5pEQyebJy0K0QCFlxSY/kbw/DTgVhHyqxZEjuMRGbAvpYBrAgMBAAGjYzBh\
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPrQA9VIbDTIu28JqXaLiB2EKiJT\
MB8GA1UdIwQYMBaAFPrQA9VIbDTIu28JqXaLiB2EKiJTMA4GA1UdDwEB/wQEAwIB\
BjANBgkqhkiG9w0BAQ0FAAOCAgEAG4cutTc2EGNoOW+J0IHD0eXJ1QiMgnEBpVGg\
VYYmshyQZhFmZPzDjyGRS4Xobl3/cZiiTwYfpkpbgIyB9HTIdG/YLDGTCtO8cJmq\
wAmtEA4CFpMRcQHMMM56TG73q+hNlf0QwAT4+7gk+Bcxd5GlOr1C+XHdwaRU92Kg\
EGgDQ3pIKAmLPSVSj317g8aPnc++P//A7yJ2lC1D+Si3i3+fi33DHh1kS7Fy5FE5\
PLcll7kW06W6q7oEbkDOS+2fUxV/3hdvBizrm4goVY5PjWQjbf+9PSwgt257ag4p\
dihW5yInQkf1UpQ+sfMQIInkkQDYPIIfRD031pRdeOnMgef/0uNPsNmSXO9pU1cj\
8pll8IZNUaw9u63u+yANnG6bf3DHVOh8lzeLKEdrk2YcgTRXPW157x5jX7RE2d8Y\
IwE8nfIOTEqxRB4hbGVx4LWRFwxwpZ2XZ9u2a72kG0pdDu9AfvBt8slS1rRl9a/U\
fmcUa+wVokhOdGuzpwo+Z8J9rgO4cxSlOV4GtW9s8bFUlSxQY0/dhkVX9VIfsjlc\
iPnyAj5nXaXob9Xrkrfgw/eQT6T1GaPepIepgGWhMPPiFc8I/nsk8YhzR4v7qxXz\
r2cKANf9YWvhEfTzRZNBCHKQgD1iN//s5HxbsLC8xiCNJTkNPUcGkAzSbEURKGAs\
opoKuec=\n\
-----END CERTIFICATE-----'
Certificate:
 Data:
 Version: 3 (0x2)
 Serial Number:
 28:73:c8:de:45:e5:20:71
 Signature Algorithm: sha512WithRSAEncryption
 Issuer: C = DE, O = Some_Organization, CN = Marco Stiegelmaier
 Validity
 Not Before: Feb 8 12:45:00 2023 GMT
 Not After : Feb 8 12:45:00 2033 GMT
 Subject: C = DE, O = Some_Organization, CN = Marco Stiegelmaier
 Subject Public Key Info:
 Public Key Algorithm: rsaEncryption
 Public-Key: (4096 bit)
 Modulus:
 00:cd:f6:63:4e:c7:0c:47:ba:85:83:0e:e6:25:fd:
 2c:e8:45:87:5e:21:86:27:df:03:a2:84:98:86:19:
 50:fd:05:f1:24:44:18:2b:3c:12:74:ad:b0:d9:d0:
 ec:41:05:81:ef:0a:6b:b1:06:8c:3d:77:b9:a4:db:
 df:d3:0f:60:af:b3:a1:b8:8a:fb:7a:0f:e9:98:0d:
 b0:48:72:74:36:3d:25:e5:f2:d7:b6:ac:56:1f:9e:
 32:9d:b2:ac:44:2c:c9:34:e2:43:ce:a9:26:8e:97:
 13:a3:e9:11:97:46:8f:13:23:75:2b:7d:9f:9d:32:
 76:a2:88:55:72:7e:bf:43:37:4b:39:bd:f1:9c:a6:
 8d:0c:6a:e6:a1:a0:24:eb:66:3b:a2:95:51:87:33:
 61:da:98:7a:d0:4b:66:f4:fd:ce:fc:d0:98:52:ff:
 97:29:d2:bd:e1:8c:7c:9c:4d:56:ba:14:10:3a:59:
 75:4c:3d:d6:75:c5:73:88:6d:8a:2c:4c:cc:c9:37:
 bb:ce:7d:3a:12:66:e5:25:ef:36:b5:8e:56:17:28:
 91:61:19:21:12:48:ad:17:91:da:93:2b:e9:0a:7a:
 aa:82:08:94:95:83:1f:93:00:80:d3:fc:cf:ac:ad:
 04:72:82:01:a2:8d:9f:cb:ef:72:6f:fc:36:81:3c:
 55:74:4d:8f:91:db:70:df:90:ed:4b:88:ca:d5:89:
 b3:be:c4:6b:c8:8a:e7:ac:5f:8b:43:5c:d1:f2:13:
 44:67:a2:2a:b0:ef:b6:66:c7:53:3b:81:ad:c7:9a:
INTERNAL
 75:e8:6e:66:39:7d:ec:c2:68:da:aa:f9:f7:06:62:
 1f:7f:37:c6:a6:21:18:26:50:18:b2:29:5c:81:2d:
 d2:7c:1e:29:c8:6e:41:f5:a7:c1:a8:92:64:c2:88:
 19:67:0b:66:13:86:4a:c0:14:fa:63:e4:4b:6f:09:
 d8:29:b8:41:2c:aa:f1:64:76:bf:90:0d:a0:09:4e:
 ef:30:1e:71:1e:5f:54:1f:a5:df:ca:d3:85:c0:59:
 65:98:c6:ac:11:ac:87:0a:36:70:8a:74:4f:5a:39:
 2e:39:1d:77:01:6b:2f:76:68:56:33:bd:8f:75:dd:
 f9:15:30:3d:a6:ca:34:2e:09:a8:64:14:bd:27:89:
 71:72:7b:c3:3d:43:4a:f7:d3:48:f0:d9:87:10:29:
 5a:db:15:7c:d7:3b:74:3b:6f:46:84:9f:54:0a:a7:
 01:bb:71:d5:28:4f:36:5b:30:11:49:d6:4f:9a:44:
 43:27:9b:27:2d:0a:d1:00:85:97:14:98:fe:46:f0:
 fc:34:e0:56:11:f2:ab:16:44:8e:e3:11:19:b0:2f:
 a5:80:6b
 Exponent: 65537 (0x10001)
 X509v3 extensions:
 X509v3 Basic Constraints: critical
 CA:TRUE
 X509v3 Subject Key Identifier:
 FA:D0:03:D5:48:6C:34:C8:BB:6F:09:A9:76:8B:88:1D:84:2A:22:53
 X509v3 Authority Key Identifier:
 FA:D0:03:D5:48:6C:34:C8:BB:6F:09:A9:76:8B:88:1D:84:2A:22:53
 X509v3 Key Usage: critical
 Certificate Sign, CRL Sign
 Signature Algorithm: sha512WithRSAEncryption
 Signature Value:
 1b:87:2e:b5:37:36:10:63:68:39:6f:89:d0:81:c3:d1:e5:c9:
 d5:08:8c:82:71:01:a5:51:a0:55:86:26:b2:1c:90:66:11:66:
 64:fc:c3:8f:21:91:4b:85:e8:6e:5d:ff:71:98:a2:4f:06:1f:
 a6:4a:5b:80:8c:81:f4:74:c8:74:6f:d8:2c:31:93:0a:d3:bc:
 70:99:aa:c0:09:ad:10:0e:02:16:93:11:71:01:cc:30:ce:7a:
 4c:6e:f7:ab:e8:4d:95:fd:10:c0:04:f8:fb:b8:24:f8:17:31:
 77:91:a5:3a:bd:42:f9:71:dd:c1:a4:54:f7:62:a0:10:68:03:
 43:7a:48:28:09:8b:3d:25:52:8f:7d:7b:83:c6:8f:9d:cf:be:
 3f:ff:c0:ef:22:76:94:2d:43:f9:28:b7:8b:7f:9f:8b:7d:c3:
 1e:1d:64:4b:b1:72:e4:51:39:3c:b7:25:97:b9:16:d3:a5:ba:
 ab:ba:04:6e:40:ce:4b:ed:9f:53:15:7f:de:17:6f:06:2c:eb:
 9b:88:28:55:8e:4f:8d:64:23:6d:ff:bd:3d:2c:20:b7:6e:7b:
 6a:0e:29:76:28:56:e7:22:27:42:47:f5:52:94:3e:b1:f3:10:
 20:89:e4:91:00:d8:3c:82:1f:44:3d:37:d6:94:5d:78:e9:cc:
 81:e7:ff:d2:e3:4f:b0:d9:92:5c:ef:69:53:57:23:f2:99:65:
 f0:86:4d:51:ac:3d:bb:ad:ee:fb:20:0d:9c:6e:9b:7f:70:c7:
 54:e8:7c:97:37:8b:28:47:6b:93:66:1c:81:34:57:3d:6d:79:
 ef:1e:63:5f:b4:44:d9:df:18:23:01:3c:9d:f2:0e:4c:4a:b1:
 44:1e:21:6c:65:71:e0:b5:91:17:0c:70:a5:9d:97:67:db:b6:
 6b:bd:a4:1b:4a:5d:0e:ef:40:7e:f0:6d:f2:c9:52:d6:b4:65:
 f5:af:d4:7e:67:14:6b:ec:15:a2:48:4e:74:6b:b3:a7:0a:3e:
 67:c2:7d:ae:03:b8:73:14:a5:39:5e:06:b5:6f:6c:f1:b1:54:
 95:2c:50:63:4f:dd:86:45:57:f5:52:1f:b2:39:5c:88:f9:f2:
 02:3e:67:5d:a5:e8:6f:d5:eb:92:b7:e0:c3:f7:90:4f:a4:f5:
 19:a3:de:a4:87:a9:80:65:a1:30:f3:e2:15:cf:08:fe:7b:24:
 f1:88:73:47:8b:fb:ab:15:f3:af:67:0a:00:d7:fd:61:6b:e1:
 11:f4:f3:45:93:41:08:72:90:80:3d:62:37:ff:ec:e4:7c:5b:
 b0:b0:bc:c6:20:8d:25:39:0d:3d:47:06:90:0c:d2:6c:45:11:
 28:60:2c:a2:9a:0a:b9:e7
To get to the RSA Private Key we simply execute the following python script:
import gmpy2
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric.rsa import rsa_crt_dmp1,rsa_crt_dmq1, rsa_crt_iqmp, RSAPrivateNumbers, RSAPublicNumbers
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography import x509
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed

rootCA_cert_pem = b'-----BEGIN CERTIFICATE-----\n\
MIIFcTCCA1mgAwIBAgIIKHPI3kXlIHEwDQYJKoZIhvcNAQENBQAwRjELMAkGA1UE\
BhMCREUxGjAYBgNVBAoMEVNvbWVfT3JnYW5pemF0aW9uMRswGQYDVQQDExJNYXJj\
byBTdGllZ2VsbWFpZXIwHhcNMjMwMjA4MTI0NTAwWhcNMzMwMjA4MTI0NTAwWjBG\
MQswCQYDVQQGEwJERTEaMBgGA1UECgwRU29tZV9Pcmdhbml6YXRpb24xGzAZBgNV\
BAMTEk1hcmNvIFN0aWVnZWxtYWllcjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC\
AgoCggIBAM32Y07HDEe6hYMO5iX9LOhFh14hhiffA6KEmIYZUP0F8SREGCs8EnSt\
sNnQ7EEFge8Ka7EGjD13uaTb39MPYK+zobiK+3oP6ZgNsEhydDY9JeXy17asVh+e\
Mp2yrEQsyTTiQ86pJo6XE6PpEZdGjxMjdSt9n50ydqKIVXJ+v0M3Szm98ZymjQxq\
5qGgJOtmO6KVUYczYdqYetBLZvT9zvzQmFL/lynSveGMfJxNVroUEDpZdUw91nXF\
c4htiixMzMk3u859OhJm5SXvNrWOVhcokWEZIRJIrReR2pMr6Qp6qoIIlJWDH5MA\
gNP8z6ytBHKCAaKNn8vvcm/8NoE8VXRNj5HbcN+Q7UuIytWJs77Ea8iK56xfi0Nc\
0fITRGeiKrDvtmbHUzuBrceadehuZjl97MJo2qr59wZiH383xqYhGCZQGLIpXIEt\
0nweKchuQfWnwaiSZMKIGWcLZhOGSsAU+mPkS28J2Cm4QSyq8WR2v5ANoAlO7zAe\
cR5fVB+l38rThcBZZZjGrBGshwo2cIp0T1o5LjkddwFrL3ZoVjO9j3Xd+RUwPabK\
NC4JqGQUvSeJcXJ7wz1DSvfTSPDZhxApWtsVfNc7dDtvRoSfVAqnAbtx1ShPNlsw\
EUnWT5pEQyebJy0K0QCFlxSY/kbw/DTgVhHyqxZEjuMRGbAvpYBrAgMBAAGjYzBh\
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPrQA9VIbDTIu28JqXaLiB2EKiJT\
MB8GA1UdIwQYMBaAFPrQA9VIbDTIu28JqXaLiB2EKiJTMA4GA1UdDwEB/wQEAwIB\
BjANBgkqhkiG9w0BAQ0FAAOCAgEAG4cutTc2EGNoOW+J0IHD0eXJ1QiMgnEBpVGg\
VYYmshyQZhFmZPzDjyGRS4Xobl3/cZiiTwYfpkpbgIyB9HTIdG/YLDGTCtO8cJmq\
wAmtEA4CFpMRcQHMMM56TG73q+hNlf0QwAT4+7gk+Bcxd5GlOr1C+XHdwaRU92Kg\
EGgDQ3pIKAmLPSVSj317g8aPnc++P//A7yJ2lC1D+Si3i3+fi33DHh1kS7Fy5FE5\
PLcll7kW06W6q7oEbkDOS+2fUxV/3hdvBizrm4goVY5PjWQjbf+9PSwgt257ag4p\
dihW5yInQkf1UpQ+sfMQIInkkQDYPIIfRD031pRdeOnMgef/0uNPsNmSXO9pU1cj\
8pll8IZNUaw9u63u+yANnG6bf3DHVOh8lzeLKEdrk2YcgTRXPW157x5jX7RE2d8Y\
IwE8nfIOTEqxRB4hbGVx4LWRFwxwpZ2XZ9u2a72kG0pdDu9AfvBt8slS1rRl9a/U\
fmcUa+wVokhOdGuzpwo+Z8J9rgO4cxSlOV4GtW9s8bFUlSxQY0/dhkVX9VIfsjlc\
iPnyAj5nXaXob9Xrkrfgw/eQT6T1GaPepIepgGWhMPPiFc8I/nsk8YhzR4v7qxXz\
r2cKANf9YWvhEfTzRZNBCHKQgD1iN//s5HxbsLC8xiCNJTkNPUcGkAzSbEURKGAs\
opoKuec=\n\
-----END CERTIFICATE-----'

rootCA_cert = x509.load_pem_x509_certificate(rootCA_cert_pem, default_backend())
public_key = rootCA_cert.public_key()
n = public_key.public_numbers().n
e = public_key.public_numbers().e

def fermat_factor(n):
    assert n % 2 != 0
    a = gmpy2.isqrt(n)
    b2 = gmpy2.square(a) - n
    while not gmpy2.is_square(b2):
    
        a = a + 1
        b2 = gmpy2.square(a) - n
        p = a + gmpy2.isqrt(b2)
        q = a - gmpy2.isqrt(b2)
        
    return int(p), int(q)
def get_private_exponent(p,q):

    def gcd(a, b):
        while a != 0:
            a, b = b % a, a
        return b

    def findModInverse(a, m):
        if gcd(a, m) != 1:
            return None
        u1, u2, u3 = 1, 0, a
        v1, v2, v3 = 0, 1, m
        while v3 != 0:
            q = u3 // v3
            v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
        return u1 % m
    d = findModInverse(e, (p - 1) * (q - 1))
    return d

def get_RSAPrivateKey(p,q,d,e):
    iqmp = rsa_crt_iqmp(p,q)
    dmp1 = rsa_crt_dmp1(d,p)
    dmq1 = rsa_crt_dmq1(d,q)
    public_numers = RSAPublicNumbers(e,n)
    private_numers = RSAPrivateNumbers(p,q,d,dmp1,dmq1,iqmp,public_numers)
    private_key = private_numers.private_key()
    private_key_pem = private_key.private_bytes(Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption())
    print(private_key_pem.decode())
    return(private_key_pem)

if __name__ == "__main__":
    (p, q) = fermat_factor(n)
    d = get_private_exponent(p,q)
    private_key_hacked = get_RSAPrivateKey(p,q,d,e)

    msg = b"Hello World!"
    
    signature = load_pem_private_key(private_key_hacked,None).sign(msg,padding.PSS(padding.MGF1(hashes.SHA256()),padding.PSS.MAX_LENGTH), hashes.SHA256())
    public_key = x509.load_pem_x509_certificate(rootCA_cert_pem).public_key()
    
    try:
        public_key.verify(signature,msg,padding.PSS(padding.MGF1(hashes.SHA256()),padding.PSS.MAX_LENGTH), hashes.SHA256())
        print("Signature verification sucessfull")
    except:
        print("Signature verification not sucessfull")
And finally we get the corresponding RSA PrivateKey. That was easy.
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

Signature verification sucessfull
Is RSA compromised by this?

Well, normally things won’t be that easy. At least as long some calculation rules were taken into account. The problem in this scenario was caused by the values p and q which weren’t chosen carefully:

p:=289871264333692713557237978898560107750718046497342527288049689817884773773167498117
404738139191876364798265939451736775134351787159570630809411693721244431885676800200
054619600178416630320124908403741484091070035060263459131278252185295587843626377868
348354412294706597930580066926754960268723063495432646924179361367381168683702911660
596798946524346457147054154899999075086923771763685491589381092180535791067655428505
143658838601017333799164192753650854338227651167412915287495444186304947737141792978
158809305006204673801771776120333954863247594900190475586056298851772688681005567604
24771955107447873594482799487

q:=28987126433369271355723797889856010775071804649734252728804968981788477377316
74981174047381391918763647982659394517367751343517871595706308094116937212444
31885676800200054619600178416630320124908403741484091070035060263459131278252
18529558784362637786834835441229470659793058006692675496026872306349543264692
41793613673811686837029116605967989465243464571470541548999990750869237717636
85491589381092180535791067655428505143658838601017333799164192753650854338227
65116741291528749544418630494773714179297815880930500620467380177177612033395
486324759490019047558605629885177268868100556760424771955107447873594482800917
The PRIME values for p and q are very close to each other. One could say, that they are PRIME-neighbors. Of course this didn’t happened
coincidentally in this case:
import random

key_size = 2048

def miller_rabin_qrounds(n, q):
    if n<=3:
        raise Exception('n should b greater than 3.')
    
    if n % 2 == 0:
        return False
    
    u = n - 1
    k = 0

    while (u % 2 == 0):
        u //= 2
        k+=1

        for _ in range(q):
            a = random.randint(2,n-2)
            b = pow(a,u,n)

            if b==1 or b ==n-1:
                continue
            
            for _ in range (k-1):
                b= (b*b) % n
                
                if b==n-1: break
                else:
                    return False
    return True

def get_prime():
    
    while True:

        rnd_value = random.randrange(2**(key_size-1), 2**key_size)
        
        if miller_rabin_qrounds(rnd_value,1):
            if miller_rabin_qrounds(rnd_value,30):
                return rnd_value

first_prime = get_prime()

def get_next_prime(first_prime):
    next_prime = first_prime

    while True:
        next_prime = next_prime + 1

        if miller_rabin_qrounds(next_prime,1):
            if miller_rabin_qrounds(next_prime,30):
                return next_prime

next_prime = get_next_prime(first_prime)

def get_weak_prime_numbers():
    first_prime = get_prime()
    next_prime = get_next_prime(first_prime)
    return first_prime,next_prime
    
The problem with Prime values p and q being close to each other or even being PRIME neighbors is a certain vulnerability being exploited
with the so called Fermat’s factorization method. (see https://en.wikipedia.org/wiki/Fermat%27s_factorization_method).

Utilizing this method makes it possible to reverse engineer the RSAPrivateKey as shown. This is no science-fiction as it really happened in
the past (see https://support.yubico.com/hc/en-us/articles/360021803580-Infineon-RSA-Key-Generation-Issue-Customer-Portal)

So the good advice at this point – Always utilize proven libraries for RSAKeyPair generation and maybe it is worth to have a look inside a
PKI’s Certification Policy to get some insights into the PKI’s operating and Chapter 6 – Security Controls.

If you are honest, then the weakness is completely hidden from a human’s eye as the 4096 Bits imply a kind of security, but the impression
could be deceptive.