gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 10:55:31 25 4
gpt4 key购买 nike

我正在使用 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

由于 Codec.Crypto.RSA 的测试套件通过了,我的程序肯定有问题。

更换后 RSA.encrypt' RSA.UsePKCS1_v1_5RSA.encrypt (默认为 OAEP 1 )和 RSA.decrypt' RSA.UsePKCS1_v1_5RSA.decrypt ,故障不再触发。

有人看到这里有什么问题吗?

[1] 打算以后用OAEP,但是生成的密文不能用 echo ciphertext | openssl rsautl -oaep -inkey keypair.pem -decrypt解密出于某种原因,但这是另一个问题。

更新:
要使 OAEP 与 OpenSSL 一起工作,必须使用 SHA-1 作为散列函数:
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

最佳答案

您的代码没有问题,这是使用过的库中的错误。

问题是

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_Num 中的错误,有时会产生 0 字节:
        Right (bs, g') ->
let res = fromIntegral $ fromIntegral low + (bs2i bs .&. mask)
in if res > high then go g' else Right (res, g')

在这里, mask0xFF (255), low为1。如果生成的无限制字节为255,则
res = fromIntegral 256

这是 0,因此不是 > high .

该错误应该已在 monadcryptorandom 的下一个版本 (0.4.1) 中修复。这很快就会在hackage上到期。

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

关于haskell - Codec.Crypto.RSA : (decrypt . encrypt)/= id 当使用 PKCS#1 v1.5 填充时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10221858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com