Browse files

initial commit of crypto lib

  • Loading branch information...
0 parents commit c30fe18ebea1665e7cf0e55a9170e84304b0eac1 Josh committed Jun 7, 2012
Showing with 130 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. +13 −0 README
  3. +14 −0 project.clj
  4. +93 −0 src/crypto/file.clj
10 .gitignore
@@ -0,0 +1,10 @@
+/pom.xml
+*jar
+/lib
+/classes
+/native
+/.lein-failures
+/checkouts
+/.lein-deps-sum
+.lein-plugins
+*~
13 README
@@ -0,0 +1,13 @@
+# clj-crypto
+
+FIXME: write description
+
+## Usage
+
+FIXME: write
+
+## License
+
+Copyright (C) 2012 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
14 project.clj
@@ -0,0 +1,14 @@
+(defproject clj-crypto "1.0.0-SNAPSHOT"
+ :description "Crypogrphy utilities"
+ :dev-dependencies [[swank-clojure "1.4.2"]]
+ :local-repo-classpath true
+ :plugins [[s3-wagon-private "1.1.1"]]
+ :repositories {"releases" "s3p://relay-maven-repo/releases/"
+ "snapshots" "s3p://relay-maven-repo/snapshots/"}
+ :dependencies [[org.clojure/clojure "1.2.0"]
+ [org.clojure/clojure-contrib "1.2.0"]
+ [swank-clojure/swank-clojure "1.4.2"]
+ [org.clojars.kyleburton/clj-etl-utils "1.0.48"]
+ [commons-lang "2.5"]
+ [commons-io/commons-io "2.3"]
+ [commons-codec "1.6"]])
93 src/crypto/file.clj
@@ -0,0 +1,93 @@
+(ns crypto.file
+ (:import [javax.crypto KeyGenerator SecretKey SecretKeyFactory Cipher CipherOutputStream CipherInputStream]
+ [javax.crypto.spec SecretKeySpec PBEKeySpec IvParameterSpec]
+ [java.io File FileOutputStream DataInputStream FileInputStream]
+ [org.apache.commons.codec.binary Base64]
+ [org.apache.commons.io IOUtils])
+ (:use
+ [clj-etl-utils.lang-utils :only [raise aprog1]]))
+
+(defn rand-salt [size]
+ (aprog1
+ (byte-array size)
+ (.nextBytes (java.security.SecureRandom.) it)))
+
+;; Defaults
+(def *pbe-iteration-count* 65536)
+(def *pbe-key-length* 256)
+(def *cipher-algorithm* "AES/CBC/PKCS5Padding")
+(def *key-factory-algorithm* "PBKDF2WithHmacSHA1")
+(def *key-encoding* "AES")
+
+(defn make-secret-key [password]
+ (let [key-factory (SecretKeyFactory/getInstance *key-factory-algorithm*)
+ key-spec (PBEKeySpec. (.toCharArray password)
+ (rand-salt 20)
+ *pbe-iteration-count*
+ *pbe-key-length*)]
+ (SecretKeySpec. (.getEncoded (.generateSecret key-factory key-spec)) *key-encoding*)))
+
+(defn get-init-vec-from-cipher [cipher]
+ (-> cipher
+ (.getParameters)
+ (.getParameterSpec IvParameterSpec)
+ (.getIV)))
+
+(defn make-cipher
+ ([mode secret-key]
+ (doto (Cipher/getInstance *cipher-algorithm*)
+ (.init mode secret-key)))
+ ([mode secret-key init-vec]
+ (doto (Cipher/getInstance *cipher-algorithm*)
+ (.init mode secret-key init-vec))))
+
+;; Adapted from: http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption
+(defn file-encrypt [infile outfile password]
+ (let [secret-key (make-secret-key password)
+ cipher (make-cipher Cipher/ENCRYPT_MODE secret-key)
+ init-vec (get-init-vec-from-cipher cipher)]
+ (with-open [istream (java.io.FileInputStream. infile)
+ ostream (CipherOutputStream. (java.io.FileOutputStream. outfile) cipher)]
+ (IOUtils/copy istream ostream))
+ {:skey (Base64/encodeBase64String (.getEncoded secret-key))
+ :ivec (Base64/encodeBase64String init-vec)}))
+
+
+;; Adapted from: http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption
+(defn file-decrypt [infile outfile secret-key init-vec]
+ (let [skey (if (Base64/isBase64 secret-key)
+ (Base64/decodeBase64 secret-key)
+ secret-key)
+ ivec (if (Base64/isBase64 init-vec)
+ (Base64/decodeBase64 init-vec)
+ init-vec)
+ cipher (make-cipher Cipher/DECRYPT_MODE (SecretKeySpec. skey *key-encoding*) (IvParameterSpec. ivec))]
+ (with-open [istream (CipherInputStream. (FileInputStream. infile) cipher)
+ ostream (java.io.FileOutputStream. outfile)]
+ (IOUtils/copy istream ostream))))
+
+(defn get-encryption-stream [infilename password]
+ (let [secret-key (make-secret-key password)
+ cipher (make-cipher Cipher/ENCRYPT_MODE secret-key)
+ init-vec (get-init-vec-from-cipher cipher)
+ stream (CipherInputStream. (FileInputStream. infilename) cipher)]
+ {:skey (Base64/encodeBase64String (.getEncoded secret-key))
+ :ivec (Base64/encodeBase64String init-vec)
+ :stream stream}))
+
+(defn get-decryption-stream [#^InputStream instream secret-key init-vec]
+ (let [skey (if (Base64/isBase64 secret-key)
+ (Base64/decodeBase64 secret-key)
+ secret-key)
+ ivec (if (Base64/isBase64 init-vec)
+ (Base64/decodeBase64 init-vec)
+ init-vec)
+ cipher (make-cipher Cipher/DECRYPT_MODE (SecretKeySpec. skey *key-encoding*) (IvParameterSpec. ivec))]
+ (CipherInputStream. instream cipher)))
+
+
+(comment
+ (def *crypt-info* (file-encrypt "/home/superg/foo.txt" "/home/superg/foo.enc"))
+
+ (file-decrypt "/home/superg/foo.enc" "/home/superg/foo.dec" (:skey *crypt-info*) (:ivec *crypt-info*))
+ )

0 comments on commit c30fe18

Please sign in to comment.