Skip to content

Instantly share code, notes, and snippets.

@postspectacular
Created October 21, 2014 21:22
Show Gist options
  • Save postspectacular/4c52474c40a58fa99597 to your computer and use it in GitHub Desktop.
Save postspectacular/4c52474c40a58fa99597 to your computer and use it in GitHub Desktop.
RSA keypair generator w/ Clojure (requires Bouncycastle & unlimited JCE). Based on bundled example (org.bouncycastle.openpgp.examples.RSAKeyPairGenerator)
;; usage:
;;
;; (-> (rsa-keypair 2048)
;; (generate-secret-key "alice@example.org" "hello")
;; (export-keypair "alice.pub" "alice.sec" true))
(import
'[java.util Date]
'[java.security SecureRandom KeyPair KeyPairGenerator]
'[org.bouncycastle.jce.provider BouncyCastleProvider]
'[org.bouncycastle.bcpg ArmoredOutputStream HashAlgorithmTags]
'[org.bouncycastle.openpgp
PGPEncryptedData
PGPKeyPair
PGPPublicKey
PGPSecretKey
PGPSignature]
'[org.bouncycastle.openpgp.operator.jcajce
JcaPGPContentSignerBuilder
JcaPGPDigestCalculatorProviderBuilder
JcaPGPKeyPair
JcePBESecretKeyEncryptorBuilder])
(require '[clojure.java.io :as io])
(Security/addProvider (BouncyCastleProvider.))
(defn rsa-keypair
[bits]
(let [gen (doto (KeyPairGenerator/getInstance "RSA" "BC")
(.initialize (int bits)))]
(.generateKeyPair gen)))
(defn generate-secret-key
[^KeyPair pair ident pass]
(let [sha1 (.. (JcaPGPDigestCalculatorProviderBuilder.)
(build)
(get HashAlgorithmTags/SHA1))
pair (JcaPGPKeyPair. PGPPublicKey/RSA_GENERAL pair (Date.))
sign (-> pair (.getPublicKey) (.getAlgorithm)
(JcaPGPContentSignerBuilder. HashAlgorithmTags/SHA1))
enc (-> (JcePBESecretKeyEncryptorBuilder. PGPEncryptedData/CAST5 sha1)
(.setProvider "BC")
(.build (char-array pass)))]
(PGPSecretKey.
PGPSignature/DEFAULT_CERTIFICATION
pair
ident
sha1
nil
nil
sign
enc)))
(defn export-keypair
[^PGPSecretKey skey out-pub out-sec armored?]
(let [op (io/output-stream out-pub)
os (io/output-stream out-sec)]
(with-open [op (if armored? (ArmoredOutputStream. op) op)
os (if armored? (ArmoredOutputStream. os) os)]
(-> skey (.encode os))
(-> skey (.getPublicKey) (.encode op)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment