Clojure技术集合

使用 Clojure 以及 Java 安全库,实现 PGP 主流

2016-05-14  本文已影响206人  BlindingDark

PGP Clojure


主要函数:

(defn md5-result
  "获取hash序列,参数为file类型,返回hash的byte数组"
  [file]
  (let [md5 (MessageDigest/getInstance "MD5")]
      (.update md5 (.getBytes (slurp file) "utf-8"))
      (.digest md5)))
;BASE64编码
(defn BASE64-encoder 
  "参数是要编码的byte数组,返回String"
  [file-byte]
  (.encodeBuffer (BASE64Encoder.) file-byte))

;BASE64解码
(defn BASE64-decoder
  "参数是要解码的file-string,返回解码后的byte"
  [file-string]
  (.decodeBuffer (BASE64Decoder.) file-string))
;生成公钥和私钥对,基于RSA算法
(defn generate-RSA-key-pair
  "生成公钥和私钥对,RSA算法,无参数,返回公钥-私钥对"
  []
  (let [key-pair-gen  (KeyPairGenerator/getInstance "RSA")]
    (.initialize key-pair-gen 1024)
    (let [key-pair (.generateKeyPair key-pair-gen)]
      (.getPublic key-pair)
      (map #(BASE64-encoder (.getEncoded %)) 
              [(.getPublic key-pair) (.getPrivate key-pair)]))))


(defn get-private-key-ob
  "得到private-key的对象,参数是私钥字符串"
  [private-key]
  (let [keyFactory  (KeyFactory/getInstance "RSA")]
    (.generatePrivate 
        keyFactory 
        (PKCS8EncodedKeySpec. (BASE64-decoder private-key)))))

(defn get-public-key-ob
  "得到public-key的对象,参数是公钥字符串"
  [public-key]
  (let [keyFactory  (KeyFactory/getInstance "RSA")]
    (.generatePublic
        keyFactory
        (X509EncodedKeySpec. (BASE64-decoder public-key)))))

(defn generate-DES-key
  "参数为密钥字符串,返回值为DES密钥key对象"
  [string-key]
  (let [key-gen  (KeyGenerator/getInstance "DESede")]
    (.init key-gen (SecureRandom. (.getBytes string-key)))
    (.generateKey key-gen)))
(defn encrypt
  "加密byte数组,第一个参数是算法名字符表示,第二个参数是key,第三个参数是要加密的byte数组"
  [algorithm  some-key some-byte]
  (let [cipher (Cipher/getInstance algorithm)]
     (.init cipher Cipher/ENCRYPT_MODE some-key)
     (.doFinal cipher some-byte)))

(defn decrypt
  "解密byte数组,第一个参数是算法名字符表示,第二个参数是key,第三个参数是要解密的byte数组"
  [algorithm  some-key some-byte]
  (let [cipher (Cipher/getInstance algorithm)]
     (.init cipher Cipher/DECRYPT_MODE some-key)
     (.doFinal cipher some-byte)))

主程序流程:

;创建hash文件。base64编码再保存,file-mail为mail文件,file-hash为摘要文件
(creat-hash-file file-mail file-hash)
;RSA加密(签名)hash文件;用私钥加密(签名)hash文件
(spit 
    file-signed-hash
    (RSA-encrypt-by-private-key
        (slurp file-private)
        (slurp file-hash)))

;压缩
(zip-2-files file-hash-mail-zip file-mail file-signed-hash)

;zip编码base64,保存为txt
(spit 
    file-hash-mail-BASE64ed 
     (BASE64-encoder 
     (FileUtils/readFileToByteArray file-hash-mail-zip)))

;一次性密钥加密
(let [DES-key (generate-random-DES-key)]
  (spit file-hash-mail-encrypted 
    (DES-encrypt-string 
        (second DES-key)
        (slurp file-hash-mail-BASE64ed)))
  (spit file-DES-key (first DES-key)))

;用公钥对DES-key加密(保密)
(spit
    file-DES-key-encrypted
    (RSA-encrypt-by-public-key 
            (slurp file-public)
            (slurp file-DES-key)))

;压缩
(zip-2-files 
    file-mail-ready-zip 
    file-hash-mail-encrypted
    file-DES-key-encrypted)

;zip编码base64,保存为txt
(spit 
    file-send
     (BASE64-encoder
        (FileUtils/readFileToByteArray file-mail-ready-zip)))

;解码发来的Email
(copy (BASE64-decoder (slurp file-receive)) file-mail-zip)
;解压
(unzip file-mail-zip (.getParent file-mail-zip))
;用私钥解密DES-key
(spit 
    file-DES-key-rec
        (RSA-decrypt-by-private-key
            (slurp file-private)
            (slurp file-DES-key-encrypted-rec)))

;用一次性密钥解密
(spit 
    file-hash-mail-BASE64ed-rec 
        (DES-decrypt-string 
            (generate-DES-key 
                (slurp file-DES-key-rec)) 
                (slurp file-hash-mail-encrypted-rec)))

;解码zip的base64
(copy 
    (BASE64-decoder 
        (slurp file-hash-mail-BASE64ed-rec))
    file-hash-mail-zip-rec)

;解压
(unzip 
    file-hash-mail-zip-rec
    (.getParent file-hash-mail-zip-rec))

;判断是否是本人
(=
  ;计算hash
  (BASE64-encoder (md5-result file-mail-rec))
  ;用对方公钥解密signed-hash
  (RSA-decrypt-by-public-key 
            (slurp file-public)
            (slurp file-signed-hash-rec)))

在github上查看完整代码


上一篇 下一篇

猜你喜欢

热点阅读