forked from yogsototh/clj-jwt
-
Notifications
You must be signed in to change notification settings - Fork 3
/
sign.clj
77 lines (67 loc) · 2.97 KB
/
sign.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(ns clj-jwt.sign
(:require
[clj-jwt.base64 :refer [url-safe-encode-str url-safe-decode]]
[crypto.equality :refer [eq?]])
(:import
(java.security PublicKey PrivateKey)))
; HMAC
(defn- hmac-sign
"Function to sign data with HMAC algorithm."
[alg ^String key ^String body & {:keys [^String charset] :or {charset "UTF-8"}}]
(let [hmac-key (javax.crypto.spec.SecretKeySpec. (.getBytes key charset) alg)
hmac (doto (javax.crypto.Mac/getInstance alg)
(.init hmac-key))]
(url-safe-encode-str (.doFinal hmac (.getBytes body charset)))))
(defn- hmac-verify
"Function to verify data and signature with HMAC algorithm."
[alg ^String key ^String body signature & {:keys [^String charset] :or {charset "UTF-8"}}]
(eq? signature (hmac-sign alg key body :charset charset)))
; RSA
(defn- rsa-sign
"Function to sign data with RSA algorithm."
[alg ^PrivateKey key ^String body & {:keys [^String charset] :or {charset "UTF-8"}}]
(let [sig (doto (java.security.Signature/getInstance alg)
(.initSign key (java.security.SecureRandom.))
(.update (.getBytes body charset)))]
(url-safe-encode-str (.sign sig))))
(defn- rsa-verify
"Function to verify data and signature with RSA algorithm."
[alg ^PublicKey key ^String body signature & {:keys [^String charset] :or {charset "UTF-8"}}]
(let [sig (doto (java.security.Signature/getInstance alg)
(.initVerify key)
(.update (.getBytes body charset)))]
(.verify sig (url-safe-decode signature))))
; ECDSA
(defn- ec-sign
[alg ^PrivateKey key ^String body & {:keys [^String charset] :or {charset "UTF-8"}}]
(let [sig (doto (java.security.Signature/getInstance alg)
(.initSign key)
(.update (.getBytes body charset)))]
(url-safe-encode-str (.sign sig))))
(def ^:private signature-fns
{:HS256 (partial hmac-sign "HmacSHA256")
:HS384 (partial hmac-sign "HmacSHA384")
:HS512 (partial hmac-sign "HmacSHA512")
:RS256 (partial rsa-sign "SHA256withRSA")
:RS384 (partial rsa-sign "SHA384withRSA")
:RS512 (partial rsa-sign "SHA512withRSA")
:ES256 (partial ec-sign "SHA256withECDSA")
:ES384 (partial ec-sign "SHA384withECDSA")
:ES512 (partial ec-sign "SHA512withECDSA")})
(def ^:private verify-fns
{:HS256 (partial hmac-verify "HmacSHA256")
:HS384 (partial hmac-verify "HmacSHA384")
:HS512 (partial hmac-verify "HmacSHA512")
:RS256 (partial rsa-verify "SHA256withRSA")
:RS384 (partial rsa-verify "SHA384withRSA")
:RS512 (partial rsa-verify "SHA512withRSA")
:ES256 (partial rsa-verify "SHA256withECDSA")
:ES384 (partial rsa-verify "SHA384withECDSA")
:ES512 (partial rsa-verify "SHA512withECDSA")})
(defn- get-fns [m alg]
(if-let [f (get m alg)]
f
(throw (Exception. "Unkown signature"))))
(def get-signature-fn (partial get-fns signature-fns))
(def get-verify-fn (partial get-fns verify-fns))
(def supported-algorithm? (set (keys verify-fns)))