Haskell Codec.Crypto.RSA:(decrypt.encrypt)/=使用PKCS#1 v1.5填充时的id?

Haskell Codec.Crypto.RSA:(decrypt.encrypt)/=使用PKCS#1 v1.5填充时的id?,haskell,encryption,rsa,padding,Haskell,Encryption,Rsa,Padding,我正在使用Codec.Crypto.RSA对通过base64表示的套接字传递给外部进程的随机字符串进行加密。外部进程(使用openssl进行解密的ruby程序)有时无法解密消息 为了调试这一点,我在haskell中设置了一个简单的脚本,对固定消息进行加密和解密,而不使用base64编码/解码。让我困惑的是,这个非常简单的程序在经过几次迭代后导致失败。解密的密文不等于原始消息,尽管消息包含在解密中(在一些无法打印的字符之后) 代码如下: import Crypto.Random import qu

我正在使用Codec.Crypto.RSA对通过base64表示的套接字传递给外部进程的随机字符串进行加密。外部进程(使用openssl进行解密的ruby程序)有时无法解密消息

为了调试这一点,我在haskell中设置了一个简单的脚本,对固定消息进行加密和解密,而不使用base64编码/解码。让我困惑的是,这个非常简单的程序在经过几次迭代后导致失败。解密的密文不等于原始消息,尽管消息包含在解密中(在一些无法打印的字符之后)

代码如下:

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

你的代码没有问题,只是旧库中的一个bug

问题是

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'
它应该生成一个给定长度的随机
ByteString
,但没有0字节

破解
Codec.Crypto.RSA
的源代码来测试它,我很快就会得到一个0字节的错误

这意味着解码后的信息被认为比实际长度长,你会在它前面看到一些垃圾

具体的错误是,
crandomR
有时由于
crandomR\u Num
中的错误而产生0字节:

        Right (bs, g') ->
                let res = fromIntegral $ fromIntegral low + (bs2i bs .&. mask)
                in if res > high then go g' else Right (res, g')
这里,
mask
0xFF
(255),
low
是1。如果生成的非限制字节为255,则

res = fromIntegral 256
它是0,因此不是高的

这个错误应该已经在下一个版本(0.4.1)中修复,该版本很快将在hackage上发布


据我所见,OAEP方法没有受到影响,因为它们使用不同的填充方案将块填充到所需的长度。

这非常有用。非常感谢。我没有在monadcryptorandom的bug跟踪器中找到这个bug,也没有在即将发布的版本中看到任何信息。你知道软件包的作者很快就会发布下一个版本吗?不知道,我已经给作者/维护者发了关于这个bug的邮件。因为这是一件相当重要的事情,我推断Thomas会尽快修复它,并毫不拖延地推出修复程序。我想我也会把它添加到bug追踪器中。多亏了你们两位,修复并上传为monadcryptorandom-0.4.1!提问者的程序现在打印了无数行非常无聊的“成功”。这就是我所说的答案!
res = fromIntegral 256