· 7 years ago · Sep 27, 2018, 06:52 AM
1(ns compojure.crypto
2 "Functions for cryptographically signing, verifying and encrypting data."
3 (:use compojure.encodings)
4 (:use clojure.contrib.def)
5 (:use clojure.contrib.java-utils)
6 (:import java.security.SecureRandom)
7 (:import javax.crypto.Cipher)
8 (:import javax.crypto.KeyGenerator)
9 (:import javax.crypto.Mac)
10 (:import javax.crypto.spec.SecretKeySpec)
11 (:import javax.crypto.spec.IvParameterSpec)
12 (:import java.util.UUID))
13
14(defvar hmac-defaults
15 {:algorithm "HmacSHA256"}
16 "Default options for HMACs.")
17
18(defvar encrypt-defaults
19 {:algorithm "AES"
20 :key-size 128
21 :mode "CBC"
22 :padding "PKCS5Padding"}
23 "Default options for symmetric encryption.")
24
25(defn- make-algorithm
26 "Return an algorithm string suitable for JCE from a map of options."
27 [options]
28 (str "AES/" (options :mode) "/" (options :padding)))
29
30(defn- make-cipher
31 "Create an AES Cipher instance."
32 [options]
33 (Cipher/getInstance (make-algorithm options)))
34
35(defn decrypt-bytes
36 "Decrypts a byte array with the given key and encryption options."
37 [options key data]
38 (let [options (merge encrypt-defaults options)
39 cipher (make-cipher options)
40 [iv data] (split-at (.getBlockSize cipher) data)
41 iv-spec (IvParameterSpec. (to-bytes iv))
42 secret-key (SecretKeySpec. key (options :algorithm))]
43 (.init cipher Cipher/DECRYPT_MODE secret-key iv-spec)
44 (.doFinal cipher (to-bytes data))))
45
46(defn decrypt
47 "Base64 encodes and encrypts a string with the given key and algorithm."
48 [options key data]
49 (String. (decrypt-bytes options key (base64-decode-bytes data))))