Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我的RSA算法只适用于非常短的单词_Algorithm_Haskell_Encryption - Fatal编程技术网

Algorithm 我的RSA算法只适用于非常短的单词

Algorithm 我的RSA算法只适用于非常短的单词,algorithm,haskell,encryption,Algorithm,Haskell,Encryption,我的RSA算法对3个字母的单词(如“cat”)运行良好,但一旦单词变长,我会收到一条错误消息:Exception:decipher2.hs:(37,1)-(62,19):函数numToLet中的非穷举模式 我的程序按照以下步骤工作 用于加密 将一串字母转换为一串数字,其中每个字母都指定给特定的数字 将数字串组合成一个较大的数字 使用适当的p和q值,计算n,并选择一个与n共素的合适数字e(因为这是一个内部过程,保持p和q的秘密并不重要,但可以做到) 执行RSA算法以生成“密码” 破译 使用p

我的RSA算法对3个字母的单词(如“cat”)运行良好,但一旦单词变长,我会收到一条错误消息:Exception:decipher2.hs:(37,1)-(62,19):函数numToLet中的非穷举模式

我的程序按照以下步骤工作

用于加密

  • 将一串字母转换为一串数字,其中每个字母都指定给特定的数字
  • 将数字串组合成一个较大的数字
  • 使用适当的p和q值,计算n,并选择一个与n共素的合适数字e(因为这是一个内部过程,保持p和q的秘密并不重要,但可以做到)
  • 执行RSA算法以生成“密码”
破译

  • 使用p和q(其中φ(n)=(p-1)*(q-1))计算总和φ(n)
  • 将寻找两个数的最大公约数的欧几里德算法写入代码
  • 将后代换部分写入代码,使其交换形成扩展的欧几里德算法
  • 计算私钥
  • 包括某种存储私钥的选项,以便不必每次都执行此功能(以提高速度)
  • RSA加密的解密算法需要执行
  • 结果应该被分割成一个数字串(与加密过程第2阶段的组合方式相反)
  • 数字字符串应转换为字母字符串(使用加密过程中使用的相同值)
我选择不包括计算关键部分,因为它是一个单独的程序,必须是正确的(因为短单词可以被破译)。我尝试过使用较小的p和q值,但这也不起作用,有人知道为什么较长的单词不起作用(即使对于较小的素数)和/或我如何修复它吗

我的加密代码是:

import Data.List
letToNum c'' = (let (Just n) = elemIndex c'' ['a'..'z'] in n) + 10

combine = foldl addDigit 0
    where addDigit num i' = (10 ^ (floor $ log (fromIntegral i') / log 10 + 1))*num + i'

firstTwo xs = toInteger (combine (map letToNum xs))

p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
e' = 7

newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
  ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
                             | otherwise = undefined
  ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
                             | otherwise = undefined
  negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
  abs _ = undefined
  signum _ = undefined
  fromInteger _ = undefined

modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
  where a' = ModN (a, m)
        ModN (c, _) = a' ^ b

encipherA z' = modPow z' e' n'

encipher xs = encipherA (firstTwo xs)
p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
d'=149198411630450358098821815816660626082852035578197682912033354754850558281651065264118115990713936905841443816348466119712510491169399086751890869693052182563708139506244285477194512876340531187775438573122278032339474119913958963667476383477798088213829701243686243438754864105731229873495425397653296705562025639940130672903361904637280085880562426594784029436599468688448179303703337724326069153629191476697420768451884440453280134491448395404958914592441919126201747433884753502442027069825305163272842897505994155682996130741544296475635538035696205346055652365820232813677363525296188331517668300986037331017823989462119054758685224752255850280255541024098528388784743634162996954090230161430468033874779937253936100340449079832503240200984659315256173082971785802328581652375418902448324739292188909509903808503871246982928186837296358844444348158079557757543904495890483033995844854839625810784987612815774450940850973031117459144355531047129541648317845165848539683500066541165782574432790936862217277817101197569391139502130923768985262346549685855947859864917650782062626099395684514986479824104485607000960030713840667632064934158997031779846656288570984548383771118345091911988849410656041321592285731293207858515766711

newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
  ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
                             | otherwise = undefined
  ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
                             | otherwise = undefined
  negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
  abs _ = undefined
  signum _ = undefined
  fromInteger _ = undefined

modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
  where a' = ModN (a, m)
        ModN (c, _) = a' ^ b

decipherA c' = modPow c' d' n'

numToLet "10" = "a"  
numToLet "11" = "b"  
numToLet "12" = "c"
numToLet "13" = "d"
numToLet "14" = "e"
numToLet "15" = "f"
numToLet "16" = "g"
numToLet "17" = "h"
numToLet "18" = "i"
numToLet "19" = "j"
numToLet "20" = "k" 
numToLet "21" = "l"
numToLet "22" = "m"
numToLet "23" = "n"
numToLet "24" = "o"
numToLet "25" = "p"
numToLet "26" = "q"
numToLet "27" = "r"
numToLet "28" = "s"
numToLet "29" = "t"
numToLet "30" = "u"
numToLet "31" = "v"
numToLet "32" = "w"
numToLet "33" = "x"
numToLet "34" = "y"
numToLet "35" = "z"
output xs = putStrLn $ concat (map numToLet xs)

partition :: Int -> [a] -> [[a]]
partition _ [] = []
partition n xs = (take n xs) : (partition n (drop n xs))

decipher j' = map numToLet (partition 2 (show (decipherA j')))
我的解密代码是:

import Data.List
letToNum c'' = (let (Just n) = elemIndex c'' ['a'..'z'] in n) + 10

combine = foldl addDigit 0
    where addDigit num i' = (10 ^ (floor $ log (fromIntegral i') / log 10 + 1))*num + i'

firstTwo xs = toInteger (combine (map letToNum xs))

p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
e' = 7

newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
  ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
                             | otherwise = undefined
  ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
                             | otherwise = undefined
  negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
  abs _ = undefined
  signum _ = undefined
  fromInteger _ = undefined

modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
  where a' = ModN (a, m)
        ModN (c, _) = a' ^ b

encipherA z' = modPow z' e' n'

encipher xs = encipherA (firstTwo xs)
p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
d'=149198411630450358098821815816660626082852035578197682912033354754850558281651065264118115990713936905841443816348466119712510491169399086751890869693052182563708139506244285477194512876340531187775438573122278032339474119913958963667476383477798088213829701243686243438754864105731229873495425397653296705562025639940130672903361904637280085880562426594784029436599468688448179303703337724326069153629191476697420768451884440453280134491448395404958914592441919126201747433884753502442027069825305163272842897505994155682996130741544296475635538035696205346055652365820232813677363525296188331517668300986037331017823989462119054758685224752255850280255541024098528388784743634162996954090230161430468033874779937253936100340449079832503240200984659315256173082971785802328581652375418902448324739292188909509903808503871246982928186837296358844444348158079557757543904495890483033995844854839625810784987612815774450940850973031117459144355531047129541648317845165848539683500066541165782574432790936862217277817101197569391139502130923768985262346549685855947859864917650782062626099395684514986479824104485607000960030713840667632064934158997031779846656288570984548383771118345091911988849410656041321592285731293207858515766711

newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
  ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
                             | otherwise = undefined
  ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
                             | otherwise = undefined
  negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
  abs _ = undefined
  signum _ = undefined
  fromInteger _ = undefined

modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
  where a' = ModN (a, m)
        ModN (c, _) = a' ^ b

decipherA c' = modPow c' d' n'

numToLet "10" = "a"  
numToLet "11" = "b"  
numToLet "12" = "c"
numToLet "13" = "d"
numToLet "14" = "e"
numToLet "15" = "f"
numToLet "16" = "g"
numToLet "17" = "h"
numToLet "18" = "i"
numToLet "19" = "j"
numToLet "20" = "k" 
numToLet "21" = "l"
numToLet "22" = "m"
numToLet "23" = "n"
numToLet "24" = "o"
numToLet "25" = "p"
numToLet "26" = "q"
numToLet "27" = "r"
numToLet "28" = "s"
numToLet "29" = "t"
numToLet "30" = "u"
numToLet "31" = "v"
numToLet "32" = "w"
numToLet "33" = "x"
numToLet "34" = "y"
numToLet "35" = "z"
output xs = putStrLn $ concat (map numToLet xs)

partition :: Int -> [a] -> [[a]]
partition _ [] = []
partition n xs = (take n xs) : (partition n (drop n xs))

decipher j' = map numToLet (partition 2 (show (decipherA j')))

感谢您的帮助,我真的很感激。

由于RSA算法输出的数字小于模
n
,因此您显然不能加密超过
n
的不同消息(消息
0
n-1

对于长度超过特定长度的字符串,您将通过该阈值

典型的解决方案是仅使用RSA加密随机生成的会话密钥。然后使用此会话密钥对称加密消息(例如,使用)。另一方可以使用RSA重构会话密钥并解密消息

编辑:我刚刚看到,除了RSA算法本身不可避免的限制之外,您在字符串编码中引入了另一个bug。您的编码器和解码器不匹配:

*RSA> let encode = firstTwo
*RSA> let decode x = map numToLet (partition 2 (show x))
*RSA> decode (encode "catcatcatcat")
["x","g","f","c","*** Exception: RSA.hs:(41,1)-(66,19): Non-exhaustive patterns in function numToLet
问题是整数溢出:
combine
具有类型
[Int]->Int
,但
Int
最多只能保存值
2^31-1
,这对应于编码中的4个字符。您可以使用
Integer
修复此问题:

letToNum :: Char -> Integer
letToNum c'' = (let (Just n) = fmap toInteger (elemIndex c'' ['a'..'z']) in n) + 10

combine :: [Integer] -> Integer
combine = foldl addDigit 0
    where addDigit num i' = 100*num + i'

firstTwo xs = combine (map letToNum xs)

正如您所看到的,它有助于添加类型签名。我还删除了
log
表达式,我不知道它的作用是什么,但我猜它可能是不必要的,甚至是错误的…

“我收到一条错误消息:”它说了什么?对不起,它说的是异常:decipher2.hs:(37,1)-(62,19):函数numtolethanks中的非穷举模式,因此,如果我想加密和解密一个句子,那么我必须使用RSA加密AES加密的密钥,然后使用AES?这是没有办法的?如果我的问题看起来很愚蠢,我很抱歉,谢谢你的帮助@MichaelRad:使用RSA,您只能对消息进行加密,只要您的模数为。因此,使用1024位密钥,您最多只能加密128字节的数据。@MichaelRad:也就是说,如果这足够,您可以保留当前代码。不过它有一个bug。检查我的新编辑谢谢,我想因为我只使用了两位数字(a=10,b=11…z=35),所以
日志不一定是必需的,但我不确定该放什么位置?抱歉阅读困难,这是我的第一个完整程序(除了“hello world”等)。我很确定你给我的代码比我写的要好得多,但因为这是我的第一个程序,我宁愿尝试在帮助下修补它,而不是复制粘贴全新的代码,如果这有意义的话?谢谢lot@MichaelRad:这是有道理的。我仍然不知道日志的作用是什么,似乎它是错的。我通过删除日志和整数溢出修复了编码器