And The 12th Day of Christmas, IETF Gave To Me … A New Set of Keys for Testing

And, so, the IETF has dropped an early Christmas present for those involved in cybersecurity [here]:

♫ And On The 12th Day of Christmas, IETF Gave To Me … A New Set of Keys for Testing ♫

On the 1st day of Cyber Christmas, Eve gave to me … one malware backdoor.

On the 2nd day of Cyber Christmas, Eve gave to me … two backdoor trojans.

On the 3rd day of Cyber Christmas, Eve gave to me … three phishing emails.

On the 4th day of Cyber Christmas, Eve gave to me … four calling APIs.

On the 5th day of Cyber Christmas, Eve gave to me … five magic numbers.

On the 6th day of Cyber Christmas, Eve gave to me … six obuscated programs.

On the 7th day of Cyber Christmas, Eve gave to me … seven public keys.

On the 8th day of Cyber Christmas, Eve gave to me … eight reverse toolkits.

On the 9th day of Cyber Christmas, Eve gave to me … nine wireless scanners.

On the 10th day of Cyber Christmas, Eve gave to me … ten encrypted backdoors.

On the 11th day of Cyber Christmas, Eve gave to me … eleven trojan timebombs.

But, the the 12th day of Cyber Christmas, the IETF gave to me 12 keys for testing.

And, so, the IETF has dropped an early Christmas present for those involved in cybersecurity [here]:

For this, RFC 9500, defines RSA, DLP (Discrete Logarithm Problem) and ECDLP (Elliptic Curve DLP) keys for testing. With DLP, we have discrete log methods such as the Diffie-Hellman method and ElGamal, and with ECDLP, we have elliptic curve methods, such as for ECDH and ECDSA. In this article, we will use the RSA keys and see if they work for the parameters defined.

RSA theory

Overall, Bob generates two random prime numbers (p and q), and create a public modulus of:

N=p.q

Next Bob computes φ:

φ=(p−1).(q−1)

Bob then picks a public exponent of e and which does not share a factor with φ, and computes the private exponent as:

d=e^{-1} (mod φ)

Bob will then use a public exponent (e) to cipher a message (M) with:

C=M^e (mod N)

To decrypt we use the private exponent (d) to decipher the ciphertext:

M=C^d (mod N)

Bob’s public key is [e,N] and his private key is [d,N]. Normally we select e=0x010001 (65537), and so can just compute with:


e= 0x010001
n=p*q
PHI=(p-1)*(q-1)
d=pow(e,-1,PHI)

C = pow(M,e,n)
Plain = pow(C,d,n)

Testing

The RFC defines three sets of RSA test keys, and defines the parameters for p, q, N, e, and d. Overall, we just need the values of p, q and e, and can construct the key pair from there. The testRSA1024 key is:

and which has the p and q value of:

We can then add p, q and e, and compute the other values:


p=0xE9D86E4DC34A985A7EC75A6F54A75CE45139E45240B386AB711DB791BCD98718A13BAF218C24493646680756CB50A6CBEE158E2521449912301C0D4149111845
q=0xC191FA3B550B391A7CB0728376277295E61C654F0BEF2F58DCE5C962A10B7DD75F06015465E55076E466263EEBCAED20D2EBAB39313E8BC567320FE8B2DC62B3

e= 0x010001
n=p*q
PHI=(p-1)*(q-1)
d=pow(e,-1,PHI)

print("=== RSA Private key ===")
print (f"p={p}\nq={q}\d={d}\nN={n}")
print (f"\nBit length of p and q is {p.bit_length()}")
print (f"Bit length of N is {n.bit_length()}")


C = pow(M,e,n)
Plain = pow(C,d,n)

Finally, we can view the PEM file for the key pair can test against the published one:

We can now produce our program with a PEM export [here]:



import sys
from Crypto.PublicKey import RSA
from Crypto.Util.number import *

msg="hello"
test=1


if (len(sys.argv)>1):
msg=sys.argv[1]
if (len(sys.argv)>2):
test=int(sys.argv[2])

try:
M= bytes_to_long(msg.encode('utf-8'))

print(f"M={M}\n")


if (test==1):
p=0xE9D86E4DC34A985A7EC75A6F54A75CE45139E45240B386AB711DB791BCD98718A13BAF218C24493646680756CB50A6CBEE158E2521449912301C0D4149111845
q=0xC191FA3B550B391A7CB0728376277295E61C654F0BEF2F58DCE5C962A10B7DD75F06015465E55076E466263EEBCAED20D2EBAB39313E8BC567320FE8B2DC62B3
elif (test==2):
p=0xDD105702382F232B3681F53791E22617C7BF4E9ACB81ED48DAF6D6995DA3EAB642839AFF012D2EA628B90AF279FD3E6F7C93CD80F072F01FF2443B3EE8F24ED469A79613A41BD24020F92FD11059BD1D0F301B5BA7A9D3637CA8D65C1A9815417D8EAB734B0B4F3A2C661D9A1A82F3AC734C40530669AB8E473045A58E65539D
q=0xCCF1E5BB90C8E9781EA75BEBF10BC252E11EB023A0260F1887552A56863F4A6421E8C600BF523D6CB1B0ADBDD65BFEE4A88A037E3D1A415E5BB95648DA5A0CA26B54F4A63948522C3D5F89B94A72EFFF95134D5940CE45758F308980908956588EEF575B3E4BC4C368CFE813EE9C252C2B02E0DF91F1AA01938D38685D60BA6F

e= 0x010001
n=p*q
PHI=(p-1)*(q-1)
d=pow(e,-1,PHI)

print("=== RSA Private key ===")
print (f"p={p}\nq={q}\d={d}\nN={n}")
print (f"\nBit length of p and q is {p.bit_length()}")
print (f"Bit length of N is {n.bit_length()}")



C = pow(M,e,n)
Plain = pow(C,d,n)
print (f"\nMessage={msg} ({M})")
print (f"Cipher={C}")
print (f"Decrypt={long_to_bytes(Plain).decode()}")


print("\n=== Private Key PEM format ===")
rsaKey = RSA.construct( ( n, e,d ) )
pubKeyPEM = rsaKey.exportKey()
print(pubKeyPEM.decode('ascii'))



except Exception as e:
print(e)

And then test to see if we get the same PEM output [here]:

=== RSA Private key ===
p=12247479110638677755006895685292383938869968447801678697985070722715761107234923761151478498897073403331761752633108460282473931019601399842965881751672901
q=10138095276694782246202662171361003801557508450601288242196414844672242494972243383075875829566498578855752497012485563974824462328158407661799412592304819\d=50688009982610032565568554607644427510266281155982377292175432720373472282026776914137016120191064125477913776281008795045481723506326155003985409349075135333555250930208896999943793436402173025416065009528317001623325861083349036647037001868439386253544446323125514634028814260359707199682725199871422345873
N=124166110122983991337731418229841999167986890488136991126459644695937663637108054071234119214658061209219033982063559594860422206527401406163421984469998420544922913916890534314339062844667145883359856186081887902775389730749339136775309884506601471604371451873922100276327703518816242681897912234232574009919

Bit length of p and q is 512
Bit length of N is 1024

Message=hello (448378203247)
Cipher=50889533777527123179957625461574044544134686739988149936839946231310678236697613436471696923335039917374072837968103924664591712492743232735134054013658209708528792088308322901151966745787270146521167213253534388775529118021950292735628818063074148946916318268724829574664710373465212884680216994559702559115
Decrypt=hello

=== Private Key PEM format ===
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg
+xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566d
fTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPwIDAQAB
AoGASC6fj6TkLfMNdYHLQqG9kOlPfys4fstarpZD7X+fUBJ/H/7y5DzeZLGCYAIU
+QeAHWv6TfZIQjReW7Qy00RFJdgwFlTFRCsKXhG5x+IB+jL0Grr08KbgPPDgy4Jm
xirRHZVtU8lGbkiZX+omDIU28EHLNWL6rFEcTWao/tERspECQQDp2G5Nw0qYWn7H
Wm9Up1zkUTnkUkCzhqtxHbeRvNmHGKE7ryGMJEk2RmgHVstQpsvuFY4lIUSZEjAc
DUFJERhFAkEAwZH6O1ULORp8sHKDdidyleYcZU8L7y9Y3OXJYqELfddfBgFUZeVQ
duRmJj7ryu0g0uurOTE+i8VnMg/ostxiswJBAOc64Dd8uLJWKa6uug+XPr91oi0n
OFtM+xHrNK2jc+WmcSg3UJDnAI3uqMc5B+pERLq0Dc6hStehqHjUko3RnZECQEGZ
eRYWciE+Cre5dzfZkomeXE0xBrhecV0bOq6EKWLSVE+yr6mAl05ThRK9DCfPSOpy
F6rgN3QiyCA9J/1FluUCQQC5nX+PTU1FXx+6Ri2ZCi6EjEKMHr7gHcABhMinZYOt
N59pra9UdVQw9jxCU9G7eMyb0jJkNACAuEwakX3gi27b
-----END RSA PRIVATE KEY-----

As you can see, the PEM matches the specification. You can test the 1,024 bit and 2,048 bit keys here:

https://asecuritysite.com/rsa/rsa_test

The test for a 2,048 bit key pair:

=== RSA Private key ===
p=155236298955972139484595473523663093070697857120573485005692454286759164189514268114152760977878297368071745567268784191831978694605424407915827821192476888069335235204241230455016300344923723230915186335030828985888088464705748830808396040873856135248607610244707355088071383405139483743842648587692381918109
q=143917211240048630525138493142218592699883532606552853080393382511003484909715427688227813443622833401143009028755339632909831230215419955313351483892783330890818448425750384602973428285439009637824616014359642687383062942197676572297693858666163949020561180119583885724274853424468568756552235067548612213359\d=8217592658643978395997469378914326216595598803460138758086645470203545100648474263629071088174145378103504638758780939800822702035396445460728040010833924003787822785259174775807619147389183683625685598203487649961105700636188473461030071150676931839456089728514133365696903678073785230264058174743049064962696985044915187600743135034483617818421217726928239411724806656538923353815737207112632856938970946205897264329582282281723692355598090101749654502387466678372954858330548665262004875552293175782015807440211911760436836186346017138953033809327210101787334924828167642256786911827389967001121554700537277793105
N=22341175228969983080498056528910155034307880145290264406733779315553378215431803609701254123689909800247630611065055440625840762602413376178533707715507461936291485185328571197299590809858331165426721855532314366361112764564584916004958424168336268230417064321647339184753919204759050138381132522945955636375486754476287726145845743290276304857008918159398412587410264624219625249241184783437849733353274917440412340772404860317620164936387758450940417466661938377946644289720142111833730769411522521354011932616094531286800933749248025305021172317273255313707340572014653091413152834375101135855265178619528373818131

Bit length of p and q is 1024
Bit length of N is 2048

Message=hello (448378203247)
Cipher=9372005576434786005563371427934485712316192806016862958155161258288844381138722800318326994688916586286825428540040137933142761562060020221241826839084941419140919055534309138329601075688268668012187775735361122264153032090041010151458912011296617130893526644679808695451573580453411261800313141111865172807513843853499245823700673036528684233688297982204873507426109450875479805204135304870184476834620975642936313842066412833265490740251434854250394764483809956779248765283783142916188812534942679106764303641923921287045798938563380106147689484888789845036072921973103174268757384091476852808584114177093405563737
Decrypt=hello

=== Private Key PEM format ===
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAsPnoGUOnrpiSqt4XynxA+HRP7S+BSObI6qJ7fQAVSPtRkqso
tWxQYLEYzNEx5ZSHTGypibVsJylvCfuToDTfMul8b/CZjP2Ob0LdpYrNH6l5hvFE
89FU1nZQF15oVLOpUgA7wGiHuEVawrGfey92UE68mOyUVXGweJIVDdxqdMoPvNNU
l86BU02vlBiESxOuox+dWmuVV7vfYZ79Toh/LUK43YvJh+rhv4nKuF7iHjVjBd9s
B6iDjj70HFldzOQ9r8SRI+9NirupPTkF5AKNe6kUhKJ1luB7S27ZkvB3tSTT3P59
3VVJvnzOjaA1z6Cz+4+eRvcysqhrRgFlwI9TEwIDAQABAoIBAEEYiyDP29vCzx/+
dS3LqnI5BjUuJhXUnc6AWX/PCgVAO+8A+gZRgvct7PtZb0sM6P9ZcLrweomlGezI
FrL0/6xQaa8bBr/ve/a8155OgcjFo6fZEw3Dz7ra5fbSiPmu4/b/kvrg+Br1l77J
aun6uUAs1f5B9wW+vbR7tzbT/mxaUeDiBzKpe15GwcvbJtdIVMa2YErtRjc1/5B2
BGVXyvlJv0SIlcIEMsHgnAFOp1ZgQ08aDzvilLq8XVMOahAhP1O2A3X8hKdXPyrx
IVWE9bS9ptTo+eF6eNl+d7htpKGEZHUxinoQpWEBTv+iOoHsVunkEJ3vjLP3lyI/
fY0NQ1ECgYEA3RBXAjgvIys2gfU3keImF8e/TprLge1I2vbWmV2j6rZCg5r/AS0u
pii5CvJ5/T5vfJPNgPBy8B/yRDs+6PJO1GmnlhOkG9JAIPkv0RBZvR0PMBtbp6nT
Y3yo1lwamBVBfY6rc0sLTzosZh2aGoLzrHNMQFMGaauORzBFpY5lU50CgYEAzPHl
u5DI6Xgep1vr8QvCUuEesCOgJg8Yh1UqVoY/SmQh6MYAv1I9bLGwrb3WW/7kqIoD
fj0aQV5buVZI2loMomtU9KY5SFIsPV+JuUpy7/+VE01ZQM5FdY8wiYCQiVZYju9X
Wz5LxMNoz+gT7pwlLCsC4N+R8aoBk404aF1gum8CgYAJ7VTq7Zj4TFV7Soa/T1eE
k9y8a+kdoYk3BASpCHJ29M5R2KEA7YV9wrBklHTz8VzSTFTbKHEQ5W5csAhoL5Fo
qoHzFFi3Qx7MHESQb9qHyolHEMNx6QdsHUn7rlEnaTTyrXh3ifQtD6C0yTmFXUIS
CW9wKApOrnyKJ9nI0HcuZQKBgQCMtoV6e9VGX4AEfpuHvAAnMYQFgeBiYTkBKltQ
XwozhH63uMMomUmtSG87Sz1TmrXadjAhy8gsG6I0pWaN7QgBuFnzQ/HOkwTm+qKw
AsrZt4zeXNwsH7QXHEJCFnCmqw9QzEoZTrNtHJHpNboBuVnYcoueZEJrP8OnUG3r
UjmopwKBgAqB2KYYMUqAOvYcBnEfLDmyZv9BTVNHbR2lKkMYqv5LlvDaBxVfilE0
2riO4p6BaAdvzXjKeRrGNEKoHNBpOSfYCOM16NjL8hIZB1CaV3WbT5oY+jp7Mzd5
7d56RZOE+ERK2uz/7JX9VSsM/LbH9pJibd4e8mikDS9ntciqOH/3
-----END RSA PRIVATE KEY-----

Merry Christmas when it comes along, and a Happy Crypto New Year!