[ Pobierz całość w formacie PDF ]
Istnieje też drugi konstruktor, pozwalający przyspieszyć proces wymiany klucza. Kon-
struktor ten przyjmuje długość wartości prywatnej w bitach i ogranicza generowaną war-
tość do podanego rozmiaru. Wartość prywatna tworzona domyślnie w ramach procesu ge-
nerowania klucza jest krótsza od P, ale o nie więcej niż osiem bitów. Jeśli P ma 1024 bity,
to wyliczanie klucza publicznego dla potrzeb procesu uzgadniania klucza będzie (często
niepotrzebnie) dość powolne. Może się okazać, że w konkretnym zastosowaniu wystarczy
wartość prywatna o długości nieprzekraczającej 512 bitów. Przyjmując, że zmienne p1p24
i g1p24 odpowiadają 1024-bitowej liczbie pierwszej i jej generatorowi, można stworzyć
obiekt DHParaceterSpec postaci następującej:
DHParameterSpec dhSpec = new DHParameterSpec(p1024, g1024, 512);
Do generowania obiektów DHParaceterSpec można też wykorzystać dostawcę metodzie
tej przyjrzymy się nieco pózniej, przy okazji omawiania klasy AlgerithcParaceterGenerater.
Obiekty parametrów dla kluczy Diffiego-Hellmana
JCE udostępnia kilka obiektów pozwalających przenosić dane parametrów kluczy dla me-
tody Diffiego-Hellmana w sposób niezależny od konkretnego dostawcy. Używane są do tego
celu klasy javae.crypte.spec.DHPrivateKeySpec i javae.crypte.spec.DHPublicKeySpec, któ-
rych obiekty mogą przenosić informacje dla dowolnego algorytmu bazującego na tej metodzie.
Konstruktor DHPrivateKeySpec przyjmuje wartość prywatną X oraz niezbędne do jej uży-
wania wartości P i G. Przykładowe wywołanie konstruktora wygląda więc tak:
DHPrivateKeySpec dhPrivateSpec = new DHPrivateKeySpec(x, p, g);
Z kolei konstruktor DHPublicKeySpec przyjmuje wartość publiczną Y i użyte do jej stworze-
nia wartości P i G. W kodzie wygląda to po prostu tak:
DHPublicKeySpec dhPublicSpec = new DHPublicKeySpec(y, p, g);
Rozdział 4. Kryptografia asymetryczna 137
Podobnie jak w przypadku innych klas specyfikacji, obiekty DHPrivateKeySpec i DHPublic-
KeySpec są prostymi obiektami wartości, więc jedynymi ich metodami są metody get() po-
bierające poszczególne wartości.
Interfejsy dla kluczy Diffiego-Hellmana
W poprzednim przykładzie wykorzystana została klasa Key. Gdyby potrzebne było bezpiecz-
niejsze typowanie, można skorzystać z interfejsów javae.crypte.interjaces.DHPrivateKey,
javae.crypte.interjaces.DHPublicKey i ich interfejsu nadrzędnego javae.crypte.inter-
jaces.DHKey.
Interfejs DHKey deklaruje tylko jedną metodę DHKey.getParacs(), zwracającą obiekt DHPara-
ceterSpec zawierający klucz publiczny i prywatny.
DHPrivateKey również deklaruje tylko jedną metodę jest to DHPrivateKey.getD(), zwra-
cająca wartość prywatną nieprzesyłaną w procedurze uzgadniania klucza.
Wreszcie DHPublicKey też ma jedną metodę DHPublicKey.getY(). Zwraca ona wartość GX
mod P, gdzie X jest wartością zwracaną przez metodę getD() odpowiedniego klucza pry-
watnego, a G i P są wartościami pobranymi z obiektu DHParaceterSpec.
Diffie-Hellman bazujący na krzywych eliptycznych
Tradycyjny algorytm Diffiego-Hellmana nie jest jedyną metodą uzgadniania klucza to
samo zadanie można wykonać z pomocą kryptografii bazującej na krzywych eliptycznych.
Wykorzystanie krzywych eliptycznych w kryptografii opiera się na własnościach ciał skoń-
czonych. Jako metoda kryptograficzna została niezależnie opracowana przez Neala Koblitza
z University of Washington i Victora Millera z IBM w 1985 roku.
Ciało to struktura matematyczna pozwalająca wykonywać na swych elementach operacje
dodawania, odejmowania, mnożenia i dzielenia zwracające wyniki należące do tego ciała.
Mowa tu o ciałach skończonych, czyli posiadających skończoną liczbę elementów, dzięki
czemu mogą one być wykorzystane do operacji kryptograficznych korzystających z krzy-
wych nad takimi ciałami. Szczególnie istotne są tu dwie konstrukcje ciała: Fp zawiera
krzywe nad skończonym ciałem liczb pierwszych p, a F2m jest ciałem złożonym z krzywych
dających się wyprowadzić z tzw. optymalnej reprezentacji bazy normalnej, czyli wielomia-
nowej reprezentacji wyprowadzonej z ciągów m-bitowych. F2m jest przestrzenią o tyle cie-
kawą, że za sprawą swej binarnej natury może ona być bardzo wydajnie przetwarzana przez
komputery. Niestety algorytmy jej przetwarzania są objęte kilkoma patentami, więc dla po-
trzeb tej książki będziemy się zajmować przede wszystkim krzywymi nad Fp. Na przykła-
dach przekonamy się jednak, że z punktu widzenia JCE/JCA nie ma specjalnej różnicy
między korzystaniem z krzywych nad F2m i nad Fp.
Bezpieczeństwo metody opiera się na trudności rozwiązania problemu logarytmu dyskret-
nego na krzywej eliptycznej, który można pokrótce przedstawić następująco:
Dla danych dwóch punktów na krzywej P i Q znalezć taką liczbę k, że kP = Q.
138 Kryptografia w Javie. Od podstaw
Okazuje się, że dla dostatecznie dużego k znalezienie rozwiązania jest zadaniem bardzo
trudnym obliczeniowo. Zrozumienie zródeł bezpieczeństwa kryptosystemu na krzywej elip-
tycznej pozwoli też lepiej zrozumieć sam algorytm.
Załóżmy, że A i B uzgadniają pewną krzywą i wybierają punkt G, przy czym informacje te
nie muszą być utrzymywane w tajemnicy. Podobnie jak w przypadku algorytmu Diffiego-
-Hellmana, A i B wybierają następnie dwie tajne wartości x i y, dzięki którym możliwa bę-
dzie bezpieczna komunikacja:
1. A wysyła B xG (klucz publiczny A).
2. B wysyła A yG (klucz publiczny B).
3. Odbywa się wymiana danych szyfrowanych kluczem sesji opartym na xyG,
który każda ze stron wylicza niezależnie.
Istotną kwestią praktyczną jest znalezienie odpowiedniej krzywej. Na szczęście opisanych
zostało wiele takich krzywych, na przykład w dokumentach X9.62 i FIPS PUB 186-2. Po-
niższy przykład wykorzystuje właśnie jedną z tych standardowych krzywych.
Spróbuj sam: Diffie-Hellman na krzywej eliptycznej
Przyjrzyj się następującemu przykładowi:
package rozdzial4;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.spec.EiFieldFp;
import java.security.spec.EiParameterSpec;
import java.security.spec.EiPoint;
import java.security.spec.Ellipticiurve;
import javax.crypto.KeyAgreement;
/**
* Diffie-Hellman w kryptosystemie na krzywej eliptycznej.
*/
public class BasicEiDHExample
{
public static void main(String[] args) throws Exception
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EiDH", "Bi");
Ellipticiurve curve = new Ellipticiurve(
new EiFieldFp(new
BigInteger("fffffffffffffffffffffffffffffffeffffffffffffffff", 16)),
new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),
new BigInteger("64210519e59c80e70fa7e9ab7224e049feb8deecc146b9b1", 16));
EiParameterSpec ecSpec = new EiParameterSpec(
curve,
new EiPoint(
new BigInteger("188da80eb0e090f67cbf20eb4ea18800f4ff0afd82ff1012", 16),
[ Pobierz całość w formacie PDF ]