Estoy usando Codec.Crypto.RSA para cifrar una cadena aleatoria que se pasa a procesos externos sobre un socket en la representación de base64. El proceso externo (un programa ruby que usa openssl para descifrado) algunas veces no descifra el mensaje.Codec.Crypto.RSA: (descifrar. Encrypt)/= id cuando se usa PKCS # 1 v1.5 padding?
Para depurar esto configuré una secuencia de comandos simple en haskell que encripta y descifra un mensaje fijo, todo sin codificar/decodificar base64. Lo que me desconcierta es que este programa muy simple resulta en una falla después de algunas iteraciones. El texto cifrado descifrado no es igual al mensaje original, aunque el mensaje está contenido en el descifrado (después de algunos caracteres no imprimibles).
Aquí está el código:
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
A medida que el banco de pruebas para Codec.Crypto.RSA pasa, ciertamente debe haber un problema con mi programa.
Después de reemplazar RSA.encrypt' RSA.UsePKCS1_v1_5
con RSA.encrypt
(por defecto a OAEP ) y RSA.decrypt' RSA.UsePKCS1_v1_5
con RSA.decrypt
, el fracaso ya no se dispara.
¿Alguien ve lo que está mal aquí?
[1] Voy a utilizar OAEP más tarde, pero el texto cifrado generado no se puede descifrar con echo ciphertext | openssl rsautl -oaep -inkey keypair.pem -decrypt
por alguna razón, pero eso es otro problema.
Actualización: Para poner en funcionamiento OAEP con OpenSSL uno tiene que utilizar SHA-1 como la función hash:
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
Eso fue muy útil. ¡Gracias! – rekado
No he encontrado este error en el rastreador de errores para monadcryptorandom, ni he visto información allí en una próxima versión. ¿Sabía que próximamente el próximo lanzamiento del autor del paquete? – rekado
No, he enviado por correo el autor/mantenedor sobre el error. Como es algo bastante sustancial, estoy extrapolando que Thomas lo soluciona lo antes posible y saca la solución sin demora. Voy a agregarlo al rastreador de errores también, creo. –