【问题标题】:How can I Base64 UrlEncode a SHA256 Hash of a string in Haskell?如何在 Haskell 中对字符串的 SHA256 哈希进行 Base64 UrlEncode?
【发布时间】:2019-07-12 05:21:01
【问题描述】:

这是为 PKEC OAuth 工作流程创建代码质询和验证程序。

以下似乎应该可以工作(使用cryptonite):

import System.Random (newStdGen, randomRs)
import Crypto.Hash (Digest, hash)
import Crypto.Hash.Algorithms (SHA256)

x = do
    gen <- newStdGen
    codeVerifier = C.pack . take 128 $ randomRs ('0', 'z') gen
    codeChallenge = show (hash codeVerifier :: Digest SHA256)
    print codeChallenge

但是很可惜,事实并非如此。因此,我将发布我在痛苦和辛劳后终于解决的答案。

【问题讨论】:

  • 显而易见的base64url函数that Hoogle suggests有什么问题?
  • base64url 是 jose 的镜头,需要 2 个额外的依赖项(那个,我没有意识到 :))

标签: security haskell hash oauth base64


【解决方案1】:

而 OAuth 工作流程所期望的答案是……鼓声~~~

import System.Random (newStdGen, randomRs)
import Data.ByteArray.Encoding
import Crypto.Hash.Algorithms
import Crypto.Hash

-- | This is a custom sort of urlEncode that simply replaces bad characters
urlEncode :: String -> String
urlEncode [] = ""
urlEncode ('=':xs) = urlEncode xs
urlEncode ('+':xs) = '-' : urlEncode xs
urlEncode ('/':xs) = '_' : urlEncode xs
urlEncode (x : xs) = x : urlEncode xs

codeVerifier = C.pack . take 128 $ randomRs ('a', 'z') gen
codeChallenge = urlEncode . C.unpack $ (convertToBase Base64 (hashWith SHA256 codeVerifier)  :: ByteString)

OP 代码中的问题在于它 base64 编码了 String,而此代码等待将散列转换为 String,因此您实际上 base64 将散列直接编码为 ByteArray

无论如何,这让我大吃一惊,尤其是因为我使用的身份验证服务坚持认为我的错误是 invalid_grant。它一直在告诉我我有一个invalid_grant?!无论如何,我在这上面弄出了几根白发,所以我想我会帮助下一个不幸的灵魂。

【讨论】:

  • 哪个导入应该是qualified as C
  • @JeremyList 我忘记了我在那里使用的东西。我认为这只是Data.ByteStringData.ByteString.Lazy,但限定词C 没有多大意义。 ByteString 应该可以工作。
猜你喜欢
  • 2016-09-04
  • 2017-08-07
  • 2021-11-19
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 2011-04-25
相关资源
最近更新 更多