Welcome to Weblog @ rebex.cz Sign in | Help

Temná zákoutí RSA implementace v .NETu?

Martin Vobr mě dnes ráno vyplašil odkazem na blog Michala Bláhy, kde prý upozorňuje na nějaký zásadní problém v implementaci RSA v .NETu. Po blížším zkoumání jsem však zjistil, že žádný problém ani chyba neexistuje a senzace se nekoná.

Michal upozorňuje na to, že třída RSACryptoServiceProvider nedokáže zašifrovat zprávu soukromým klíčem a dešifrovat ji veřejným klíčem. Ostuda? Ani ne... Toto není ani chyba, ani opomenutí, jak vysvětlím později. Tuto operace totiž neumí nejen CryptoAPI (RSA v .NETu je jen wrapper), ale ani žádná jiná implementace standardu PKCS #1 (základní standard pro RSA kryptografii) a Microsoft se v tomto případě opravdu nemá za co stydět - snad jen za to, že toto nebyl schopen sepsat místo mě. A že ani Honza Šeda nedokázal najít v MS nikoho, kdo by problém uvedl na pravou míru.

Klíčem k pochopení situace je drobný nesoulad mezi teorií a (nikoliv drsnou) praxí RSA, který se ale po blížším zkoumání ukáže být naprosto samozřejmý. Michal má samozřejmě pravdu v tom, že zprávu zašifrovanou pomocí privátního klíče P může dešifrovat kdokoliv s veřejným klíčem V, a naopak zprávu zašifrovanou pomocí veřejného klíče V může dešifrovat pouze a jenom vlastník privátního klíče P. Tolik teorie.

Ale zásadní otázka je - k čemu by nám zašifrování zprávy soukromým klíčem vlastně bylo? Veřejný klíč má k dispozici každý (je veřejný), proto každý by mohl naši zprávu dešifrovat. Existuje pouze jediný rozumný důvod k zašifrování zprávy soukromým klíčem, a to dokázat vlastnictví soukromého klíče. Jenže k tomuto účelu je přeci určen elektronický podpis! Který - jak jinak - spočívá právě v zašifrování zprávy (resp. jejího hashe) soukromým klíčem...

A praxe této úvaze odpovídá - zašifrování pomocí privátního klíče a dešifrování pomocí veřejného se opravdu používá vyhradně pro účely elektronického podpisu.

Zbytek tohoto příspěvku už není třeba číst, vše podstatné již bylo řečeno. Další řádky jen blíže přibližují praxi.

Základním dokumentem, který definuje co a jak, je PKCS #1 (jinak též znám jako např. RFC 3447), jehož autorem je RSA Laboratories. A ten definuje pouze čtyři operace:

  1. RSAEP - zašifrování - zašifrování zprávy veřejným klíče
  2. RSADP - dešifrování - dešifrování zprávy soukromým klíče
  3. RSASP1 - podpis - vytvoření podpisu zprávy (hashe) soukromým klíčem (odpovídá zašifrování soukromým klíčem)
  4. RSAVP1 - ověření - získání původní zprávy (hashe) z podpisu (odpovídá dešifrování veřejným klíčem)

Následně jsou zde definována různá schémata formátování vstupních dat pro RSAEP a pro RSASP1, pomocí kterých se data připraví do podoby vhodné k zašifrování - v žádném případě není možné zašifrovat nebo dešifrovat neformátovaná data, a to z bezpečnostních důvodů, které zde nemá smysl podrobněji rozebírat. Operace RSADP a RSAVP1 zas naopak po dešifrování tato formátovaná data převedou do jejich původní podoby. Při podpisu se například nezašifruje pouze hash zprávy, ale i ID algoritmu, pomocí kterého byl tento hash vytvořen.

Za povšimnutí také stojí, že když cpete třídě RSACryptoServiceProvider privátní klíč, tak jí cpete zárověň veřejný klíč, protože ten je součástí té stejné struktury.

Abych to shrnul - žádná implementace RSA dle PKCS #1 / RFC 3447 operaci "zašifrování dat soukromým klíčem" umět nemůže, protože standard nic takového nedefinuje. A to z pochopitelných důvodů uvedených výše.

A na závěr otázka pro Michala Bláhu, na kterou bych opravdu rád znal odpověď: K čemu vlastně potřebujete šifrovat data soukromým klíčem? :-)

Published 23. dubna 2007 11:38 by lukasp
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Temná zákoutí RSA implementace v .NETu?

23. dubna 2007 15:58 by Michal

# re: Temná zákoutí RSA implementace v .NETu?

Jo, jeste doplneni : ja to neprezentoval jako zasadni problem, spise jako neduslednost, ktera pro jistotu neni ani zdokumentovana.

A tu neuplnou dokumentaci (ci neduslednou) MS vycitam stale.

Preci jenom RFC nestuduje kazdy....

23. dubna 2007 15:59 by Michal

# Michal??v z??pisn????ek : Temná zákoutí RSA implementace v .NET 2.0

# re: Temná zákoutí RSA implementace v .NETu?

Ten problem tam je. Pokud nebude uvazovat s ohledem na digitalni podpis ale na nove metody zpusobu ochrany digitalnich dat, tak tento koncept se zacina objevovat. Digitalni podpis, jak uz jsem psal, je vam v tomto ohledu na nic. PKCS#1 je standardni dokument kolem sifrovani, ale vubec to nic nema spolecneho s pristupnostim k implementaci. Jine frameworky toto umoznuji a jak jsem napsal, pouziti privatniho klice muze mit opodstatneni ve chvili, kdy napr. potrebujeme pouzit jak podpis tak zaroven sifrovat i obsah. Problem jen jen, ze k tomuto jiz nepouzijete RSA na sifrovani onech binarnich dat. Koncept je mnohem slozitejsi a neni pro jeden blog a prispevek do nej, napr. DRM tohle resi urcitou obfuskaci klicu v pameti + kombinace certikatu a digitalniho podpisu (opet je to zavisle na implementaci daneho vyrobce jako MS nebo Applet atd). Ale rozhodne model pouziti privatniho klice na sifrovani se prave v objevuje v pracich nekterych kryptologu a to prave u DRM modelu (ale zduraznuji, neni to jen privatni klic!!!).

23. dubna 2007 16:29 by Honza S.

# re: Temná zákoutí RSA implementace v .NETu?

Michale, jako zásadní problém jste to neprezentoval vy, ale Martin Vobr, když mi o tom psal - a to ani ne tím, co psal, ale právě a jen tím, že mi o tom napsal, přestože se vidíme každý den v kanceláři. Takže to byl spíš takový můj subjektivní dojem a proto jsem tam dal to slůvko "prý" - omlouvám se za nešťastnou formulaci.

A v názoru na nedůslednost a neúplnost Microsoftí dokumentace se shodneme - RSACryptoServiceProvider opravdu není možné bez studia CryptoAPI a příslušných RFC pochopit.

24. dubna 2007 12:52 by Lukáš Pokorný

# re: Temná zákoutí RSA implementace v .NETu?

Honzo, nesouhlasím tak úplně s tím, že omezovat funkčnost je v tomto případě špatně. Ano některí jiné frameworky toto umožňují (i ten, který jsem psal já), ale v případě CryptoAPI, které slouží jakožto šifrovací jádro operačního systému, k tomu jsou dle mého názoru dobré důvody.

Protože jakou funkčnost to vlastně omezujeme? Budoucí, experimentální nebo málo rozšířené proprietární způsoby formátování dat pro RSA jistě smysl explicitně přidávat nemá - ani to nejde, když je ještě neznáme. Pokud bychom tedy chtěli zpřístupnit opravdu všechny budoucí možnosti, je jen jediný způsob, jak to provést - umožnit přímo provádění m^e mod n a c^d mod n a starost o nějaký rozumný padding přesunout na aplikaci. Toto by se vám opravdu zamlouvalo? U veřejného klíče to nevadí (pokud je skutečně veřejný), ale u soukromého ano, protože pokud umožníme c^d mod n:

1. Dešifrováním zprávy "1" získáme soukromý klíč. To jde přímo proti filozofii CryptoAPI, která je založena mimo jiné na tom, že funguje jako černá skřínka schopná na vyžádání šifrovat/dešifrovat i bez možnosti získat soukromý klíč, pokud je označen jakožto neexportovatelný. CryptoAPI rozlišuje operace "podpis", "dešifrování" a "export soukromého klíče", které mohou podléhat jiné urovni zabezpečení (a vyžadovat souhlas uživatele), a pokud umožníme c^d mod n, už nejsme schopni tyto operace od sebe rozlišit. Pak stačí spustit něakou cizí aplikaci, která se tváří, že podpisuje data, ačkoliv ve skutečnosti nám krade soukromý klíč.

2. Mnozí naivní programátoři by si jistě vytvořili vlastní způsoby paddingu dat, které by nebyly vůbec bezpečné. Pokud by pak k šifrování používali klíče ze stávajících certifikátů, otevřela by se tím zadní vrátka i do slušných aplikací. Vždyť dokonce i původní standard PKCS #1 používal algoritmus, který nebyl příliš bezpečný a brzy byl nahrazen novým.

Pokud nějaké jiné použití RSA bude v budoucnu zcela zásadní, jistě bude jeho podpora do CryptoAPI i do .NETu přidána. A čekal bych, že když už si někdo implementuje vlastní DRM, tak ho nemožnost použít RSA z CryptoAPI nepálí - funkci ModPow implementovánu jistě má, protože ani tu CryptoAPI přímo nenabízí, a RSA vlastně o ničem jiném než o několika voláních ModPow není (když odhlédnu od generování klíčů, ale to CryptoApi zas umí).

24. dubna 2007 13:00 by Lukáš Pokorný

# re: Temná zákoutí RSA implementace v .NETu?

Kvalitní čtivo...díky

14. července 2010 11:16 by Petr

Leave a Comment

(required) 
required 
(required)