-
Notifications
You must be signed in to change notification settings - Fork 1
/
algo_java.clj
56 lines (52 loc) · 1.88 KB
/
algo_java.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
(ns uniformity.internals.crypto.algo-java
(:import [javax.crypto Cipher]
[javax.crypto SecretKeyFactory]
[javax.crypto.spec SecretKeySpec]
[javax.crypto.spec PBEKeySpec]
[javax.crypto.spec GCMParameterSpec]))
(defn pbkdf2-hmac-sha256
^bytes
[^String password
^bytes salt
^long iterations
^long key-length]
{:pre [(>= (count salt) 16)
(>= iterations 1000)]
:post [(= key-length (* 8 (count %)))]}
(let [pw-chars (.toCharArray password)
kdf (SecretKeyFactory/getInstance "PBKDF2WithHmacSHA256")
key-spec (PBEKeySpec. pw-chars salt iterations key-length)
secret-key (.generateSecret kdf key-spec)]
(.getEncoded secret-key)))
(defonce ^:private gcm-tag-length 128)
(defonce ^:private gcm-nonce-length (/ 96 8))
(defn aes-gcm-encrypt
^bytes
[^bytes plaintext
^bytes key
^bytes nonce
& {:keys [^bytes aad] :or {aad nil}}]
{:pre [(contains? #{16 24 32} (count key))
(= gcm-nonce-length (count nonce))]}
(let [key-spec (SecretKeySpec. key "AES")
gcm-spec (GCMParameterSpec. gcm-tag-length nonce)
cipher-instance (Cipher/getInstance "AES/GCM/NoPadding")]
(.init cipher-instance Cipher/ENCRYPT_MODE key-spec gcm-spec)
(when (not (nil? aad))
(.updateAAD cipher-instance aad))
(.doFinal cipher-instance plaintext)))
(defn aes-gcm-decrypt
^bytes
[^bytes ciphertext
^bytes key
^bytes nonce
& {:keys [^bytes aad] :or {aad nil}}]
{:pre [(contains? #{16 24 32} (count key))
(= gcm-nonce-length (count nonce))]}
(let [key-spec (SecretKeySpec. key "AES")
gcm-spec (GCMParameterSpec. gcm-tag-length nonce)
cipher-instance (Cipher/getInstance "AES/GCM/NoPadding")]
(.init cipher-instance Cipher/DECRYPT_MODE key-spec gcm-spec)
(when (not (nil? aad))
(.updateAAD cipher-instance aad))
(.doFinal cipher-instance ciphertext)))