Thursday, December 27, 2012

RSA parameters in PEM file...

If you've ever read anything about how RSA works you most probably know that RSA is based on arithmetic modulo some large integer. First, let N be a product of two, very large, primes p and q. N is n-bit number, those days minimally 1024 bits, and thus p and q are half that size, so that after multiplication we get required number of bits. Next, there are two numbers e and d that satisfy relation , where . is encryption key - or what's frequently referred to as a public key, while is decryption key, or a private key. The question now is: Given a PEM file with private key, how to find out those parameters for a specific public/private keys? In this post I'll show three ways to do it. The first two are using tools that are a standard part of OpenSSL/GnuTLS libraries. The third one is using Python.

OpenSSL/GnuTLS

Those two, especially OpenSSL, are very popular and complex cryptograhpic libraries. Both of them come with a very capable command line tools. In the case of OpenSSL the there is a single binary, openssl, that performs its function depending on the second argument. In this post, I'll use arguments rsa and genrsa that manipulate and generate, respectively, RSA keys. GnuTLS, on the other hand, has a several tools, of which we'll use certtool.

Now, first thing is to create RSA public/private key. You can do this using the following commands:
openssl genrsa -out key.pem 512
or, if you use GnuTLS, then:
certtool --generate-privkey --bits 512 --outfile key.pem
In both cases the generated RSA modulus (N) will have 512 bits, and the keys will be written into output file key.pem. You should note few things here:
  1. The output file contains both private and public keys!
  2. We didn't encrypt output file, which is recommended to do.
  3. 512 bits these days is a way insecure. Use minimally 1024 bits.
Ok, now we can request information about this RSA keys. Again, you can do that using openssl in the following way:
openssl rsa -in key.pem -noout -text
or, using GnuTLS:
certtool -k --infile key.pem
In both cases you'll receive the following output (GnuTLS is a bit more verbose):
Private-Key: (512 bit)
modulus:
    00:ba:b6:78:3b:1c:15:f1:d9:e3:48:16:5e:e7:8e:
    fd:a0:9d:2f:ee:1b:b8:9b:3d:d3:ea:f4:ad:fb:1b:
    6e:ef:b2:b5:cd:ee:38:e9:f8:6d:64:c9:ea:95:ae:
    87:13:5a:23:8b:2f:0b:e8:bb:c6:f8:c6:c4:ee:64:
    3c:d4:97:bd:a3
publicExponent: 65537 (0x10001)
privateExponent:
    39:6b:07:ca:55:b6:c1:eb:59:a3:bf:8d:6b:f4:63:
    36:d3:5f:fb:ff:76:63:f7:3d:86:51:bc:77:2e:56:
    8d:4b:87:73:e0:53:bd:17:e8:4a:e8:df:f5:86:14:
    65:60:f2:4f:03:02:3b:e9:23:c6:d3:ce:b3:1d:e9:
    13:1a:0f:b1
prime1:
    00:d6:b1:f9:53:8c:56:96:79:c0:bd:68:6c:b9:07:
    e7:9c:70:de:f5:61:ed:bb:51:12:1d:24:37:0f:cc:
    bf:8a:95
prime2:
    00:de:a2:52:be:a1:a4:eb:d7:48:24:95:c5:2c:05:
    bd:5f:7f:74:d5:12:bd:7c:5f:f1:8e:45:a2:50:26:
    ec:d1:57
exponent1:
    66:61:30:58:1b:10:1f:69:a7:f3:aa:9c:4e:0f:ea:
    ee:bb:14:57:47:7f:aa:57:9a:9f:b2:e9:5e:eb:70:
    5b:91
exponent2:
    22:2d:8f:40:5e:b6:5f:d2:5b:eb:e9:e6:2c:1c:f1:
    76:90:ad:91:ec:5f:94:91:72:16:e2:4f:c9:b8:40:
    10:df
coefficient:
    22:9c:f3:1f:85:68:a3:36:ab:07:87:ed:a4:c0:e5:
    ef:13:a8:28:02:55:35:c1:76:96:86:97:58:08:90:
    6e:70
In this output we see parameters N (modulus), e (publicExponent), d (privateExponent), p (prime1), and q (prime2). Also, what's written in there are values d mod (p-1) (exponent1),  d mod (q-1) (exponent2) and q-1 mod p (coefficient).

The interesting thing to note is the value of publicExponent, it is 65537. Namely, the size of public exponent isn't so important and by having such a low value it is relatively easy to encrypt messages (rising to this exponent requires 17 multiplications). This is very frequent value for encryption key, i.e. public exponent. privateExponent, on the other hand, has to be large and random, so that it isn't easy to guess.

Python

The recommended library to use to manipulate RSA keys is m2crypto which is a wrapper to OpenSSL library. There are many other libraries, of course, and you can find an older comparison here. Unfortunately, I was unable to find downloadable version on the Internet.

Anyway, to be able to manipulate RSA keys you have to import RSA module from M2Crypto, i.e.:
from M2Crypto import RSA
Then, to load RSA private/public key from a file use the following line:
rsa=RSA.load_key('key.pem')
You can also generate new RSA private key as follows:
rsa=RSA.gen_key(512, 65537)
In this case you are generating private key based on public key 65537 (we saw that this is very frequently used public key) and we require 512 bit modulus. You can find out modulus length using Python's len() function, i.e.:
>>> len(rsa)
512
To obtain N, you can inquire attribute n of the object holding RSA key, i.e.:
>>> rsa.n
To obtain pair (e,d), or public key, you can use the following method:
>>> RSA.pub()
Alternatively, you can find out only e in the following way:
>>> rsa.e
As far as I could see, there is no way to find other parameters besides N, e and bit length.

Tuesday, December 25, 2012

Controlling which congestion control algorithm is used in Linux

Linux kernel has a quite advanced networking stack, and that's also true for congestion control. It is a very advanced implementation who's primary characteristics are modular structure and flexibility. All the specific congestion control algorithms are separated into loadable modules. The following congestion control mechanisms are available in the mainline kernel tree:
Default, system wide, congestion control algorithm is Cubic. You can check that by inspecting the content of the file /proc/sys/net/ipv4/tcp_congestion_control:
$ cat /proc/sys/net/ipv4/tcp_congestion_control 
cubic
So, to change system-wide default you only have to write a name of congestion control algorithm to the same file. For example, to change it to reno you would do it this way:
# echo reno > /proc/sys/net/ipv4/tcp_congestion_control
# cat /proc/sys/net/ipv4/tcp_congestion_control
reno
Note that, to change the value, you have to be the root user. As the root you can specify any available congestion algorithm you wish. In the case the algorithm you specified isn't loaded into the kernel, via standard kernel module mechanism, it will be automatically loaded. To see what congestion control algorithms are currently loaded take a look into the content of the file /proc/sys/net/ipv4/tcp_available_congestion_control:
$ cat /proc/sys/net/ipv4/tcp_available_congestion_control
vegas lp reno cubic
It is also possible to change congestion control algorithm on a per-socket basis using setsockopt(2) system call. Here is the essential part of the code to do that:
...
int s, ns, optlen;
char optval[TCP_CA_NAME_MAX];
...
s = socket(AF_INET, SOCK_STREAM, 0);
...
ns = accept(s, ...);
...
strcpy(optval, "reno");
optlen = strlen(optval);
if (setsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, optlen) < 0) {
    perror("setsockopt");
    return 1;
}
In this fragment we are setting congestion control algorithm to reno. Note that that the constant TCP_CA_NAME_MAX (value 16) isn't defined in system include files so they have to be explicitly defined in your sources.

When you are using this way of defining congestion control algorithm, you should be aware of few things:
  1. You can change congestion control algorithm as an ordinary user.
  2. If you are not root user, then you are only allowed to use congestion control algorithms specified in the file /proc/sys/net/ipv4/tcp_allowed_congestion_control. For all the other you'll receive error message.
  3. No congestion control algorithm is bound to socket until it is in the connected state.
You can also obtain current control congestion algorithm using the following snippet of the code:
optlen = TCP_CA_NAME_MAX;
if (getsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, &optlen) < 0) {
    perror("getsockopt");
    return 1;
}
Here you can download a code you can compile and run. To compile it just run gcc on it without any special options. This code will start server (it will listen on port 10000). Connect to it using telnet (telnet localhost 10000) in another terminal and the moment you do that you'll see that the example code printed default congestion control algorithm and then it changed it to reno. It will then close connection.

Instead of the conclusion I'll warn you that this congestion control algorithm manipulation isn't portable to other systems and if you use this in your code you are bound to Linux kernel.

Monday, December 24, 2012

Pretjerivanje na temu genijalaca, nadarenosti i ostalih gluposti...


Svima nam je poznato proglašavanje genijalaca u osnovnim i srednjim školama, kao dijete se sjećam toga, a vjerujem da ni danas nije drugačije. Taj kult genijalaca se dovodi do te mjere da se svima ostalima, indirektno, govori kako su glupi i da je bolje da ne pokušavaju jer neće uspjeti, nisu genijalci! Istovremeno, "genijalcima" se kaže kako ne moraju ništa raditi i da će im sve ići lako. Taj način razmišljanja počeo se provlačiti i na fakultetima (da ne spomenem kojima) i to me je počelo izuzetno jako uzrujavati, i to je povod ovog posta.

Ali prvo, jedna zanimljivost. Za početak, genijalnost, odnosno nadarenost, po nekakvom uvriježenom mišljenju je genetska karakteristika, nešto što se dobija rođenjem i više se ne može promijeniti. Nadalje, genijalnost i nadarenost se na različite načine institucionalizira, primjerice nekakvim posebnim programima i slično. Da li je nekome palo na pamet da se na taj način na mala vrata u društvo uvodi sistem sličan indijskim kastama? A još zanimljivije, koliko se sjećam, Ustav jamči jednakost svima! Da li je jednakost ako se kaže da je nešto za nekog tko je nadaren, a za ostale nije i zbog svoje genetike oni to ne mogu?!

Ali dobro, idemo na bit, jer mene sve to proglašavanje genijalaca i slično, jako iritira. Mislim da je to jako štetno za društvo, a i za pojedince.

Relativno puno ljudi shvaća da vrhunski sportaš ne nastaje preko noći i također dosta ljudi sluti kako se radi o velikim odricanjima, iako, mislim da su rijetki svjesni o kolikima se radi i o tome bi se mogao pisati poseban post. Međutim, ja vjerujem da ista stvar vrijedi i za intelekt, naime, ne postaje se stručnjak preko noći već je potreban rad, upornost i odricanje. To mnogi ne shvaćaju! I onda misle da ako je netko nešto pokušavao tjedan, dva, mjesec, pa možda i godinu, i nije uspio, da je onda glup. A ne znaju da su potrebne godine rada. Koliko godina? Pa ovisi što ste prije toga radili, i kako!

Vrhunski stručnjak ne postaje se preko noći već su za to potrebne godine predanog rada! Ne vjerujete? Preporučam onda da pročitate članak  The Expert Mind iz Scientific Americana (ovdje imate besplatnu verziju). U tom članku se opisuje istraživanje kako nastaju šahovski velemajstori. Razlog zašto baš šahovski velemajstori je zbog toga što je relativno lako pratiti (mjeriti!) napredak. Rezultati tog istraživanja su fascinantni. Ja se sjećam od malena kako su oni koji igraju vrhunski šah proglašavani genijalcima! I igranje šaha je uvijek bilo identificirano s inteligencijom, odnosno, nadarenošću i genijalnosti. E pa, zaključak tog istraživanja je da šahovski velemajstori, kao i eksperti za druga područja, nastaju učenjem a ne rođenjem! Osim toga, danas imate šahovske programe koji su razine velemajstora, a neki su uspjeli potući i svjetskog prvaka. Da li su ti programi genijalci? Mislim da ćemo se svi složiti da nisu!

Sada se pitate zašto to uopće spominjem? Pa zato što je jedna od stvari koja me neopisivo uzrujava spominjanje nekakvih genijalaca, nadarenih i sličnih gluposti (namjerno kažem gluposti!). To kreće već negdje u osnovnoj školi i onda se provlači kroz cijelo školovanje. Samo po sebi to ne bi bilo loše da se na temelju toga onda ne radi diskriminacija, a i da se na neki način uništavaju ljudi, i one koji se proglašavaju genijalnima i one koje se ne proglašava genijalnima, odnosno, smatra ih se ispod prosječnim ili prosječnim! Neću ni spominjati tendenciju roditelja da svoju djecu proglašavaju novim genijalcima! Dakle, želite li da ponovim još jednom što tvrdim? Ovaj puta puno jasnije? Može, evo:
Proglašavanje ljudi genijalcima nema veze sa stvarnošću, a istovremeno uništava te ljude isto kao što uništava i omalovažava ljude koji se ne proglašavaju genijalcima. O onima koje se smatra nesposobnima, a pogotovo oni koji sebe smatraju nesposobnima, neću ni pričati! Taj isti pristup štetan je i za društvo u cjelini jer ono ne iskorištava sav potencijal koji ima na raspolaganju, a koji je vrlo dragocjen.
Sad već vas čujem kako vičete: Pa djeca se međusobno razlikuju, neki su bolji, neki lošiji! Da, to stoji, doista su različiti. I ja uopće ne tvrdim da su isti i u tome se slažemo! Međutim, ono u čemu se ne slažemo je što je uzrok tome! Naime, popularno mišljenje je da su genijalci u pitanju, a ja tvrdim da to nije istina! Naime, iz tih riječi, genijalac, nadareni i slično slijedi kako se radi o nečemu što je stečeno rođenjem (genetikom) te da se na to ne može utjecati, odnosno, da se može samo minorno korigirati.

Ja tvrdim da su značajne razlike u sljedećem:
  • motivacija i interes - nisu svi jednako motivirani za nešto, niti sve zanima sve. Ovo dvoje mislim da je vrlo isprepleteno, odnosno, može djelovati jedno na drugo.
  • rad i upornost - biti motiviran i zainteresiran nije dovoljno, treba rada i upornosti da se nešto postigne i to kroz dulji vremenski period.
  • napredak kroz rad - raditi samo po sebi nije dovoljno. Primjerice, ako se učenje stranog jezika obavlja ponavljanjem jedne te ista rečenica tisuću puta na dan, svaki dan, tko god tako radio koliko god motiviran i uporan bio, neće puno postići.
  • dostupnost potrebnih materijala - kakva korist od volje i svega, ako nema materijala iz kojih će se učiti i s pomoću kojih će se učiti. Tu bi još uvrstio pitanje kakav smo tip osobe i da li materijali odgovaraju tom tipu, primjerice, neki su više auditivni tipovi dok drugi vizualni.
  • pomoć stručnjaka - ako imate nekoga stručnjaka pri ruci, to može izuzetno puno pomoći, ali na žalost i isto toliko odmoći ako se tome ne pristupa na pravi način.
  • reakcija na pogreške i rezultate - većina ljudi pokušava što prije riješiti neki problem i pri tome uopće ne pokušavaju naučiti iz pogrešaka, već ih samo što prije ukloniti, dok kada se dobije rezultat zadovoljni su bez obzira što vide da bi moglo i bolje!
Tu se naravno, prikriveno u svim tim točkama, nalazi i poticaj okoline. U stvari, kada mi kao djeca stičemo prve navike od roditelja, oni se reflektiraju na sve te razlike i u konačnici nas oblikuju kao osobe u inicijalnoj - i vrlo bitnoj - fazi našeg života.

Kad se samo sjetim svoje osnovne i srednje škole, skoro da mi je zlo! Nekompetentni i nezainteresirani učitelji/nastavnici/profesori, koji su i sami gajili kult genijalaca i nisu pokušavali nama, meni, kao djeci, objasniti zablude koje smo imali. A kako i bi, kad su i oni sami vjerovali u te zablude. No, moram reći da je sustav tako napravljen da ih nije ni poticao da budu drugačiji, a osim toga ponekad nisu ni znali što mi mislimo - iako je to škakljiv argumnet jer može se reći da im je posao da to znaju. No bez obzira na sve, u konačnici, nekako mi se čini da je moje trenutno stanje posljedica djelovanja roditelja (moraš učiti, to ti je kruh!) i velike sreće, s čim se mnogi drugi ne mogu pohvaliti.

Zaključit ću tako što ću reći da je vjerojatno istina, kao i obično, negdje na sredini. Međutim, mislim da društvo pretjeruje s veličanjem IQ testova i genijalaca, i u tom smislu uništava mnoge ljude te šteti samome sebi.

Za kraj, evo Vam još tekstova za čitanje ako ste zainteresirani:
Sljedeće poveznice dodavane su dosta kasnije u odnosu na vrijeme nastanka ovog posta:

About Me

scientist, consultant, security specialist, networking guy, system administrator, philosopher ;)

Blog Archive