2

Clojure 是否有一个简单的文本加密器,只需要一个密码即可解密?我只想要加密之类的东西:

(encrypt "Some secret message" "Some secret key")

:并解密:

(decrypt (encrypt "Some secret message" "Some secret key") "Some secret key")

:将返回:

"Some secret message"
4

3 回答 3

3

我认为这个功能对我正在从事的项目很有帮助。

除了标准的clojure,它还需要commons-codec。

project.clj

(defproject <project> "VERSION"
  ... 
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [commons-codec "1.8"]])

<project>/src/crypt.clj

(ns <whatever>.crypt
  (:import (javax.crypto KeyGenerator SecretKey Cipher SecretKeyFactory)
           (javax.crypto.spec SecretKeySpec PBEKeySpec)
           (org.apache.commons.codec.binary Base64)))

(def ^:dynamic *salt* "BIND SALT IN APP")

(defn cipher- [] (. Cipher getInstance "AES"))
(defn aes-keyspec [rawkey] (new SecretKeySpec rawkey "AES"))

(defn encrypt-
  [rawkey plaintext]
  (let [cipher (cipher-)
        mode (. Cipher ENCRYPT_MODE)]
    (. cipher init mode (aes-keyspec rawkey))
    (. cipher doFinal (. plaintext getBytes))))

(defn decrypt-
  [rawkey ciphertext]
  (let [cipher (cipher-)
        mode (. Cipher DECRYPT_MODE)]
    (. cipher init mode (aes-keyspec rawkey))
    (new String(. cipher doFinal ciphertext))))

(defn passkey
  [password & [iterations size]]
  (let [keymaker (SecretKeyFactory/getInstance "PBKDF2WithHmacSHA1")
        pass (.toCharArray password)
        salt (.getBytes *salt*)
        iterations (or iterations 1000)
        size (or size 128)
        keyspec (PBEKeySpec. pass salt iterations size)]
    (-> keymaker (.generateSecret keyspec) .getEncoded)))

(defn encrypt
  [password plaintext]
  (encrypt- (passkey password) plaintext))

(defn decrypt
  [password cyphertext]
  (decrypt- (passkey password) cyphertext))

用法:

(binding [crypt/*salt* "THE SALT WE ARE USING"]
   (crypt/encrypt "password" "message")
   (crypt/decrypt "password" *1)))

如果您可以使用生成的密钥,那将更加安全:

(defn aes-keygen [] (. KeyGenerator getInstance "AES"))
(defn genkey
  [keygen]
  (. keygen init  128)
  (. (. keygen generateKey ) getEncoded))
(def generated (keygen aes-keygen))
(encrypt- generated plaintext)
(decrypt- generated *1)

这仅使用 jvm 提供的 vanilla 安全功能(commons-codec 仅用于 base-64 编码/解码,因此我们可以对任意输入进行操作,它不是安全设置的一部分)。

于 2013-08-19T17:24:05.547 回答
1

尝试simple-crypto

[org.clojars.tnoda/simple-crypto "0.1.0"]

它完全符合您的要求:

user=> (use 'org.clojars.tnoda.simple-crypto)
user=> (decrypt (encrypt "Some secret message" "Some secret key!") "Some secret key!")
"Some secret message"
于 2013-08-19T17:46:03.030 回答
0

我不知道有任何 Clojure 库主要这样做——我想说——因为使用javax.crypto、javax.crypto.spec 和 java.security包太容易了。

可以在 30 行内完成。

于 2013-08-18T10:00:15.340 回答