This is to create a code challenge and verifier for PKEC OAuth workflows.
The following seems like it should work (uses 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
But alas, it does not. So I will post the answer I finally solved after much pain and toil.
And the answer that OAuth workflows expect is... drum roll ~~~
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)
The problem in the OP code is it base64 encodes a String
, where as this code waits to convert the hash to a String
, so you actually base64 encode the hash directly as a ByteArray
.
Anyways, this kicked my butt, especially since the auth service I was using insisted that my error was invalid_grant
. It kept effing telling me that I had an invalid_grant
?! Anyways, I popped a couple gray hairs over this, so figured I'd help the next unfortunate soul.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.