Back

decrypt (clj)

(source)

function

(decrypt input key iv) (decrypt input key iv {:keys [algorithm alg], :or {alg :aes128-cbc-hmac-sha256}, :as options})
Decrypt data encrypted using the `encrypt` function. The input, key and iv parameters should be of any type that can be coerced to byte array.

Examples

funcool/buddy-core
(ns buddy.core.crypto-tests
  (:require [clojure.test :refer :all]
            [clojure.pprint :refer :all]
            [buddy.core.codecs :as codecs :refer :all]
            [buddy.core.bytes :as bytes]
            [buddy.core.keys :refer :all]
            [buddy.core.nonce :as nonce]
            [buddy.core.hash :as hash]
            [buddy.core.crypto :as crypto]
            [clojure.java.io :as io]))

        ;; Decrypt
        (crypto/initialize! engine {:iv iv16 :key key :op :decrypt})
        (let [result1 (crypto/process-block! engine expected1)
              result2 (crypto/process-block! engine expected2)]
          (is (bytes/equals? result1 block16))
          (is (bytes/equals? result2 block16)))))

        ;; Decrypt
        (crypto/initialize! engine {:iv iv16 :key key :op :decrypt})
        (let [result (crypto/process-block! engine expected)]
          (is (bytes/equals? result block16)))))

        (crypto/initialize! engine {:iv iv8 :key key :op :decrypt})
        (let [result1 (crypto/process-bytes! engine expected1)
              result2 (crypto/process-bytes! engine expected2)]
          (is (bytes/equals? result1 block3))
          (is (bytes/equals? result2 block6)))))
))

(deftest low-level-aead-mode-tests
  (let [key (hex->bytes "0000000000000000000000000000000000000000000000000000000000000000")
        data (nonce/random-bytes 256)
        iv16 (nonce/random-bytes 16)
        cipher (crypto/block-cipher :aes :gcm)]
    (crypto/initialize! cipher {:iv iv16 :key key :op :encrypt})
    (let [finalsize (crypto/get-output-size cipher (count data))]
      (is (= finalsize 272)))
    (let [output (byte-array 272)
          offset (crypto/process-block! cipher data 0 output 0)
          offset' (crypto/end! cipher output offset)]
      (crypto/initialize! cipher {:iv iv16 :key key :op :decrypt})
      (let [input output
            finalsize (crypto/get-output-size cipher (count input))]
        (is (= finalsize 256))
        (let [output (byte-array 256)
              offset (crypto/process-block! cipher input 0 output 0)
              offset' (crypto/end! cipher output offset)]
          (is (bytes/equals? output data)))))))

    ;; (testing "Experiment"
    ;;   (let [data (into-array Byte/TYPE [35 -117 48 0])
    ;;         encrypted (crypto/encrypt data key32 iv16)
    ;;         decrypted (crypto/decrypt encrypted key32 iv16)]
    ;;     (println 222 (vec data))
    ;;     (println 333 (vec decrypted))
    ;;     (is (bytes/equals? decrypted data))))

    (testing "Encrypt and decript using :aes128-cbc-hmac-sha256."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key32 iv16)
                decrypted (crypto/decrypt encrypted key32 iv16)]
            (is (bytes/equals? decrypted data))))))

    (testing "Encrypt and decript using :aes192-cbc-hmac-sha384."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key48 iv16 {:algorithm :aes192-cbc-hmac-sha384})
                decrypted (crypto/decrypt encrypted key48 iv16 {:algorithm :aes192-cbc-hmac-sha384})]
            (is (bytes/equals? decrypted data))))))

    (testing "Encrypt and decript using :aes256-cbc-hmac-sha512."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key64 iv16 {:algorithm :aes256-cbc-hmac-sha512})
                decrypted (crypto/decrypt encrypted key64 iv16 {:algorithm :aes256-cbc-hmac-sha512})]
            (is (bytes/equals? decrypted data))))))

    (testing "Encrypt and decript using :aes128-gcm."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key16 iv12 {:algorithm :aes128-gcm})
                decrypted (crypto/decrypt encrypted key16 iv12 {:algorithm :aes128-gcm})]
            (is (bytes/equals? decrypted data))))))

    (testing "Encrypt and decript using :aes192-gcm."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key24 iv12 {:algorithm :aes192-gcm})
                decrypted (crypto/decrypt encrypted key24 iv12 {:algorithm :aes192-gcm})]
            (is (bytes/equals? decrypted data))))))

    (testing "Encrypt and decript using :aes256-gcm."
      (dotimes [i 50]
        (doseq [i (range 1 100)]
          (let [data  (nonce/random-bytes i)
                encrypted (crypto/encrypt data key32 iv12 {:algorithm :aes256-gcm})
                decrypted (crypto/decrypt encrypted key32 iv12 {:algorithm :aes256-gcm})]
            (is (bytes/equals? decrypted data))))))
))
funcool/buddy-sign
(ns buddy.sign.jwe-tests
  (:require [clojure.test :refer :all]
            [clojure.test.check.clojure-test :refer (defspec)]
            [clojure.test.check.generators :as gen]
            [clojure.test.check.properties :as props]
            [clojure.string :as str]
            [buddy.core.codecs :as codecs]
            [buddy.core.crypto :as crypto]
            [buddy.core.bytes :as bytes]
            [buddy.core.nonce :as nonce]
            [buddy.core.keys :as keys]
            [buddy.sign.jwe :as jwe]
            [buddy.sign.util :as util]))

(deftest jwe-wrong-date-specific-test
  (let [token (str "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.."
                   "zkV7_0---NDlvQYfpNDfqw.hECYr8zURDvz9hdjz6s-O0HNF2"
                   "MhgHgXjnQN6KuUcgE.eXYr6ybqAYcQkkkuGNcNKA")]
    (try
      (jwe/decrypt token key32 {:enc :a128cbc-hs256})
      (throw (Exception. "unexpected"))
      (catch clojure.lang.ExceptionInfo e
        (let [cause (:cause (ex-data e))]
          (is (= cause :authtag)))))))

(defspec jwe-spec-alg-dir-enc-a256gcm 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key32 {:enc :a256gcm :alg :dir :zip zip})
         res2 (jwe/decrypt res1 key32 {:enc :a256gcm :alg :dir :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-dir-enc-a192gcm 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key24 {:enc :a192gcm :alg :dir :zip zip})
         res2 (jwe/decrypt res1 key24 {:enc :a192gcm :alg :dir :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-dir-enc-a128gcm 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key16 {:enc :a128gcm :alg :dir :zip zip})
         res2 (jwe/decrypt res1 key16 {:enc :a128gcm :alg :dir :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-dir-enc-a256cbc-hs512 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key64 {:enc :a256cbc-hs512 :zip zip})
         res2 (jwe/decrypt res1 key64 {:enc :a256cbc-hs512 :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-dir-enc-a192cbc-hs384 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key48 {:enc :a192cbc-hs384 :zip zip})
         res2 (jwe/decrypt res1 key48 {:enc :a192cbc-hs384 :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-dir-enc-a128cbc-hs256 1000
  (props/for-all
   [zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key32 {:enc :a128cbc-hs256 :zip zip})
         res2 (jwe/decrypt res1 key32 {:enc :a128cbc-hs256 :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-wrong-data 1000
  (props/for-all
   [data gen/string-ascii]
   (try
    (jwe/decrypt data secret)
    (throw (Exception. "unexpected"))
    (catch clojure.lang.ExceptionInfo e
      (let [cause (:cause (ex-data e))]
        (is (or (= cause :signature)
                (= cause :token)
                (= cause :authtag)
                (= cause :header))))))))

(defspec jwe-spec-wrong-token 1000
  (props/for-all
   [data1 gen/string-alphanumeric
    data2 gen/string-alphanumeric
    data3 gen/string-alphanumeric
    data4 gen/string-alphanumeric
    data5 gen/string-alphanumeric]
   (let [data (str data1 "." data2 "." data3 "." data4 "." data5)]
     (try
       (jwe/decrypt data secret)
       (throw (Exception. "unexpected"))
       (catch clojure.lang.ExceptionInfo e
         (let [cause (:cause (ex-data e))]
           (is (or (= cause :signature)
                   (= cause :token)
                   (= cause :authtag)
                   (= cause :header)))))))))

(defspec jwe-spec-alg-rsa 500
  (props/for-all
   [enc (gen/elements encs)
    alg (gen/elements rsa-algs)
    zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data rsa-pubkey {:enc enc :alg alg :zip zip})
         res2 (jwe/decrypt res1 rsa-privkey {:enc enc :alg alg :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-a128kw 1000
  (props/for-all
   [enc (gen/elements encs)
    zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key16 {:enc enc :alg :a128kw :zip zip})
         res2 (jwe/decrypt res1 key16 {:enc enc :alg :a128kw :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-a192kw 1000
  (props/for-all
   [enc (gen/elements encs)
    zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key24 {:enc enc :alg :a192kw :zip zip})
         res2 (jwe/decrypt res1 key24 {:enc enc :alg :a192kw :zip zip})]
     (is (bytes/equals? res2 data)))))

(defspec jwe-spec-alg-a256kw 1000
  (props/for-all
   [enc (gen/elements encs)
    zip gen/boolean
    data gen/bytes]
   (let [res1 (jwe/encrypt data key32 {:enc enc :alg :a256kw :zip zip})
         res2 (jwe/decrypt res1 key32 {:enc enc :alg :a256kw :zip zip})]
     (is (bytes/equals? res2 data)))))
babashka/pod-babashka-buddy
(require '[pod.babashka.buddy.core.crypto :as crypto])

(let [input "babashka rocks block encrypting!"
      input-bytes (codecs/str->bytes input)
      key "16e333b7321d3ae94299ce0dfdf6b5a5baf61f526337812744ac7aa998dd4b4163994da4d03dc93b477ed72a5627558405a065d47fff20b28d56baf673f16f3c"
      key-bytes(codecs/hex->bytes key)
      iv "81bdb9c095276c5e38a6cf380e4ea59b"
      iv-bytes (codecs/hex->bytes iv)
      options {:alg :aes256-cbc-hmac-sha512}
      output-bytes (crypto/block-cipher-encrypt input-bytes key-bytes iv-bytes options)
      output-hex (codecs/bytes->hex output-bytes)]
  (assert (= "e71d31c9d8a4c6090268048fcfda4db7ea0c2a882c8f28d0f13a0d467720106175231ba414594ff0a7388a3bb3a9c3a375e3033a23e94143f9a352917a1f4995afe94c2722a4e7ed0505e7f2b41a97df"
             output-hex))
  (assert (= (vec (crypto/block-cipher-decrypt output-bytes key-bytes iv-bytes options))
             (vec input-bytes)))
  (prn output-hex))

(let [input "babashka rocks stream encrypting!"
      input-bytes (codecs/str->bytes input)
      key "1c30156b954e528a4775e7c4e25ba9f3111b2f774dd2549bca6a7ba9bb13adfc"
      key-bytes (codecs/hex->bytes key)
      iv "8f9ba138cce6c79b"
      iv-bytes (codecs/hex->bytes iv)
      alg :chacha
      output-bytes (crypto/stream-cipher-encrypt input-bytes key-bytes iv-bytes alg)
      output-hex (codecs/bytes->hex output-bytes)]
  (assert (= "f775ed83775fada9f9db35225f6deff5076f9858e89c8ae9805797657ad71a88e3"
             output-hex))
  (assert (= (vec (crypto/stream-cipher-decrypt output-bytes key-bytes iv-bytes alg))
             (vec input-bytes)))
  (prn output-hex))

(let [jwt {:name "Babashka" :role "Ruler of your shell"}
      jwt-json (json/encode jwt)
      key "abcdefghijklmnopqrstuvwxyzABCDEF"
      jwe (jwe/encrypt jwt-json key)
      decrypted-jwe (-> jwe (jwe/decrypt key) codecs/bytes->str)]
  (prn jwe)
  (prn decrypted-jwe)
  (assert (= decrypted-jwe jwt-json)))

;; encode decode jwe
(doseq [enc [:a128gcm :a192gcm :a256gcm :a128cbc-hs256 :a192cbc-hs384 :a256cbc-hs512]]
  (let [data {:a 1 :b 2 :c 3 :d 4}
        res1 (jwt/encrypt data key16 {:alg :a128kw :enc enc :zip true})
        res2 (jwt/decrypt res1 key16 {:alg :a128kw :enc enc :zip true})]
    (assert (= res2 data))))