2012-04-19 7 views
7

Używam Codec.Crypto.RSA do szyfrowania losowego ciągu, który jest przekazywany do procesów zewnętrznych przez gniazdo w reprezentacji base64. Proces zewnętrzny (program ruby ​​używający openssl do odszyfrowania) czasami nie odszyfrowuje wiadomości.Codec.Crypto.RSA: (odszyfruj szyfrowanie)/= id, gdy używane jest wypełnianie PKCS # 1 v1.5?

Do debugowania tego skonfigurowałem prosty skrypt w haskell, który szyfruje i odszyfrowuje stałą wiadomość, wszystko bez kodowania/dekodowania base64. Co mnie zaskakuje to, że ten bardzo prosty program powoduje niepowodzenie po kilku iteracjach. Odszyfrowany tekst zaszyfrowany nie jest równy oryginalnemu komunikatowi, chociaż wiadomość jest zawarta w odszyfrowaniu (po niektórych niedrukowalnych znakach).

Oto kod:

import Crypto.Random 
import qualified Codec.Crypto.RSA as RSA 
import qualified Data.ByteString.Lazy.Char8 as L 

m :: L.ByteString 
m = L.pack "11111222223333344444555556666600" 

main = do 
    gen <- newGenIO :: IO SystemRandom 
    let (pub, priv, _) = RSA.generateKeyPair gen 1024 
    doStuff pub priv 

doStuff pub priv = do 
    gen <- newGenIO :: IO SystemRandom 
    let (e,_) = RSA.encrypt' RSA.UsePKCS1_v1_5 gen pub m 
    let d = RSA.decrypt' RSA.UsePKCS1_v1_5 priv e 

    if (m == d) 
    then do 
     putStrLn "SUCCESS" 
     doStuff pub priv 
    else do 
     putStrLn "FAILED" 
     putStrLn $ "expected: " ++ show m 
     putStrLn $ "got:  " ++ show d 

Jako zestaw testowy dla Codec.Crypto.RSA przechodzi, tam na pewno musi być problem z moim programie.

Po wymianie RSA.encrypt' RSA.UsePKCS1_v1_5 z RSA.encrypt (domyślnie na OAEP ) i RSA.decrypt' RSA.UsePKCS1_v1_5 z RSA.decrypt, brak jest już uruchomiony.

Czy ktoś widzi, co jest nie tak?


[1] Planuję użyć OAEP później, ale wygenerowany szyfrogram nie można odszyfrować z echo ciphertext | openssl rsautl -oaep -inkey keypair.pem -decrypt z jakiegoś powodu, ale to już inny problem.

Aktualizacja: Aby praca OAEP z jednym OpenSSL musi używać SHA-1 jako funkcji skrótu:

cryptOptions :: RSA.EncryptionOptions 
cryptOptions = RSA.UseOAEP sha1' (RSA.generate_MGF1 sha1') BS.empty 
    where sha1' = bytestringDigest . sha1 

-- then, to encrypt 
enc = RSA.encrypt' cryptOptions gen pubkey 

Odpowiedz

11

Nie ma nic złego w kodzie, jest to błąd w używanej biblioteki.

Problemem jest to, że

generate_random_bytestring :: CryptoRandomGen g => g -> Int64 -> (ByteString, g) 
generate_random_bytestring g 0 = (BS.empty, g) 
generate_random_bytestring g x = (BS.cons' first rest, g'') 
where 
    (rest, g') = generate_random_bytestring g (x - 1) 
    (first, g'') = throwLeft $ crandomR (1,255) g' 

która ma wygenerować losowy ByteString o określonej długości bez 0-bajtowego, nie.

Hakowanie źródła Codec.Crypto.RSA, aby go przetestować, konsekwentnie otrzymuję błąd 0-bajtowy już wkrótce.

Oznacza to, że zdekodowana wiadomość jest uważana za dłuższą niż jest w rzeczywistości, a przed nią znajdują się śmieci.

Beton bug jest crandomR czasami daje 0-bajt z powodu błędu w crandomR_Num:

 Right (bs, g') -> 
       let res = fromIntegral $ fromIntegral low + (bs2i bs .&. mask) 
       in if res > high then go g' else Right (res, g') 

tutaj mask jest 0xFF (255), low to 1. Jeżeli generowany nieograniczony bajt jest 255 , następnie

res = fromIntegral 256 

która wynosi 0, a zatem nie jest to > high.

Błąd powinny być został rozwiązany w następnej wersji (0.4.1) z monadcryptorandom który jest powodu wkrótce już na hackage.

Metody OAEP nie mają wpływu, o ile widzę, ponieważ używają innego schematu dopełnienia do wypełnienia porcji do wymaganej długości.

+0

To było bardzo pomocne. Dziękuję Ci! – rekado

+0

Nie znalazłem tego błędu na liście błędów w monadcryptorandom, ani nie widziałem żadnych informacji na nadchodzącym wydaniu. Czy wiesz, że kolejne wydanie ma wkrótce zostać napisane przez autora pakietu? – rekado

+2

Nie, wysłałem autora/opiekuna o błędzie. Ponieważ jest to dość znacząca rzecz, ekstrapoluję, że Thomas naprawia ją jako najszybciej i bezzwłocznie wypuszcza poprawkę. Zamierzam też dodać to do modułu do śledzenia błędów. –