funcool / buddy-core Goto Github PK
View Code? Open in Web Editor NEWCryptographic api for Clojure
Home Page: https://funcool.github.io/buddy-core/latest/
License: Apache License 2.0
Cryptographic api for Clojure
Home Page: https://funcool.github.io/buddy-core/latest/
License: Apache License 2.0
(nonce/random-nonce 8)
=> [0, 0, 1, 88, 4, -48, 62, -60]
(-> (nonce/random-nonce 8)
(codecs/bytes->str)
(codecs/str->bytes))
=> [0, 0, 1, 88, 4, -17, -65, -67, -17, -65, -67, -17, -65, -67]
This can't be right can it?
Warning: protocol #'buddy.core.mac.proto/IMac is overwriting function update
WARNING: update already refers to: #'clojure.core/update in namespace: buddy.core.mac.proto, being replaced by: #'buddy.core.mac.proto/update
Warning: protocol #'buddy.core.hash/IHash is overwriting function update
WARNING: update already refers to: #'clojure.core/update in namespace: buddy.core.hash, being replaced by: #'buddy.core.hash/update
Hi,
I can't really seem to figure out how to encrypt and decrypt strings using buddy-core.
(defn test []
(let [eng (crypto/block-cipher :twofish :cbc)
iv16 (nonce/random-nonce 16)
key32 (nonce/random-nonce 32)
data (codecs/str->bytes "00000000000000000000000000000000")]
(crypto/initialize! eng {:key key32 :iv iv16 :op :encrypt})
(let [r (crypto/process-bytes! eng data)]
(crypto/initialize! eng {:key key32 :iv iv16 :op :decrypt})
(codecs/bytes->str (crypto/process-bytes! eng data)))))
Doesn't actually return the string of zeroes, but some value that looks binary.
What am I doing wrong?
Hi,
I'm using a public key signing certificate for with auth0 when the service is set to use public / private key pair. In this scenario the buddy.core.keys/read-pem->pubkey
method fails as the object returned from the PEMParser
readObject is of type: org.bouncycastle.cert X509CertificateHolder
which the JcaPEMKeyConverter
cannot use directly, getSubjectPublicKeyInfo
must be called on the X509CertificateHolder first.
To support these X509 certificate public keys I use a modified read-pem->pubkey as follows:
;; buddy/core/keys.clj
;; also add import (org.bouncycastle.cert X509CertificateHolder)
(defn- read-pem->pubkey
[path-or-reader]
(with-open [reader (io/reader path-or-reader)]
(let [parser (PEMParser. reader)
keyinfo (.readObject parser)
converter (doto (JcaPEMKeyConverter.)
(.setProvider "BC"))]
(if (instance? X509CertificateHolder keyinfo)
(.getPublicKey converter (.getSubjectPublicKeyInfo keyinfo))
(.getPublicKey converter keyinfo)))))
This is similar to how the read-pem->privkey
does instance?
checked on the object returned by the PEMParser
. I am happy to make a pull request for this if desired but as I am relatively unfamiliar with the buddy codebase I wanted to see if the proposed solution is stylistically compatible with buddy or the solution should be coded more like read-pem->privkey
:
cond
instead of if
, particularly if there are other cases to considerThanks. Buddy is working really well for us.
After updating to Clojure 1.9.0-alpha11, I've started seeing the following warning:
WARNING: bytes? already refers to: #'clojure.core/bytes? in namespace: buddy.core.bytes, being replaced by: #'buddy.core.bytes/bytes?
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L5292-L5297
(defn bytes?
"Return true if x is a byte array"
{:added "1.9"}
[x] (if (nil? x)
false
(-> x class .getComponentType (= Byte/TYPE))))
https://github.com/funcool/buddy-core/blob/master/src/buddy/core/bytes.clj#L22-L29
(defn bytes?
"Test if a first parameter is a byte
array or not."
[x]
(if (nil? x)
false
(= (Class/forName "[B")
(.getClass x))))
Looks like the clojure.core/bytes?
and buddy.core.bytes/bytes?
are functionally equivalent.
CompilerException java.io.FileNotFoundException: Could not locate clojurewerkz/scrypt/core__init.class or clojurewerkz/scrypt/core.clj on classpath., compiling:(buddy/hashers.clj:1:1)
Here is my lein deps ๐ด
Possibly confusing dependencies found:
[lein-droid "0.4.4"] -> [org.clojure/data.zip "0.1.1"] -> [org.clojure/clojure "1.3.0-beta1"]
overrides
[lein-droid "0.4.4"] -> [de.ubercode.clostache/clostache "1.4.0"] -> [org.clojure/core.incubator "0.1.2"] -> [org.clojure/clojure "1.4.0"]
and
[lein-droid "0.4.4"] -> [de.ubercode.clostache/clostache "1.4.0"] -> [org.clojure/clojure "1.3.0"]
Consider using these exclusions:
[lein-droid "0.4.4" :exclusions [org.clojure/clojure]]
[lein-droid "0.4.4" :exclusions [org.clojure/clojure]]
[buddy/buddy-hashers "1.0.0"]
[cider/cider-nrepl "0.13.0"]
[clojure-complete "0.2.4" :exclusions [[org.clojure/clojure]]]
[com.lambdaworks/scrypt "1.4.0"]
[org.clojure/clojure "1.7.0"]
[org.clojure/tools.nrepl "0.2.12" :exclusions [[org.clojure/clojure]]]
As specified in RFC 8439 and used in the Lightning Protocol (BOLT-08).
Bouncycastle does not work on Android. Spongycastle fixes this. "The Android platform unfortunately ships with a cut-down version of Bouncy Castle - as well as being crippled, it also makes installing an updated version of the libraries difficult due to classloader conflicts."
Should work the same way. Its widely used in production software (bitcoinJ), so should be safe to switch.
The 1.69 release of Bouncy Castle added some BLAKE3 support. Would it be possible to add it to buddy as well? It should be much faster than the other hashing functions.
I appears that buddy only works with PEM-format keypairs at the moment. It would be very useful to have the ability to also work with DER-format keypairs.
This works ok on Linux but fails on Windows and I don't know why:
(def privkey (keys/private-key "privkey.pem" "superpass"))
The privkey file is the same and it seems to be ok.
java.lang.ExceptionInInitializerError
at clojure.main.<clinit>(main.java:20)
Caused by: org.bouncycastle.openssl.EncryptionException: exception using cipher
- please check password and data., compiling:(backend.clj:17:14)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3628)
at clojure.lang.Compiler$DefExpr.eval(Compiler.java:439)
at clojure.lang.Compiler.eval(Compiler.java:6787)
at clojure.lang.Compiler.load(Compiler.java:7227)
at clojure.lang.RT.loadResourceScript(RT.java:371)
at clojure.lang.RT.loadResourceScript(RT.java:362)
at clojure.lang.RT.load(RT.java:446)
at clojure.lang.RT.load(RT.java:412)
at clojure.core$load$fn__5448.invoke(core.clj:5866)
at clojure.core$load.doInvoke(core.clj:5865)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5671)
at clojure.core$load_lib$fn__5397.invoke(core.clj:5711)
at clojure.core$load_lib.doInvoke(core.clj:5710)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$load_libs.doInvoke(core.clj:5749)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$require.doInvoke(core.clj:5832)
at clojure.lang.RestFn.invoke(RestFn.java:436)
at appweb_api.controllers.auth$eval20083$loading__5340__auto____2008
.invoke(auth.clj:1)
[funcool/buddy-core "0.9.0"]
is still in the docs.
Cheers & thanks for this library! :)
Hi, having an exception when calling buddy from oracle-java8 to decrypt a private key with a passphrase
2016-12-05 15:50:52,424 INFO [kixi.heimdall.handler:36] - {:msg "Something went wrong", :fn "wrap-catch-exception"}
2016-12-05 16:02:22,896 ERROR [kixi.heimdall.handler:160] -
java.lang.Thread.run Thread.java: 745
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run QueuedThreadPool.java: 555
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob QueuedThreadPool.java: 635
org.eclipse.jetty.io.AbstractConnection$2.run AbstractConnection.java: 540
org.eclipse.jetty.server.HttpConnection.onFillable HttpConnection.java: 257
org.eclipse.jetty.server.HttpChannel.handle HttpChannel.java: 310
org.eclipse.jetty.server.Server.handle Server.java: 497
org.eclipse.jetty.server.handler.HandlerWrapper.handle HandlerWrapper.java: 97
ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle
ring.adapter.jetty/proxy-handler/fn jetty.clj: 24
kixi.heimdall.components.jettyserver/wrap-config/fn jettyserver.clj: 16
kixi.heimdall.components.jettyserver/wrap-components/fn jettyserver.clj: 10
...
ring.middleware.json/wrap-json-response/fn json.clj: 87
ring.middleware.json/wrap-json-params/fn json.clj: 72
ring.middleware.keyword-params/wrap-keyword-params/fn keyword_params.clj: 35
kixi.heimdall.handler/wrap-catch-exceptions/fn handler.clj: 158
kixi.heimdall.handler/wrap-record-metric/fn handler.clj: 133
kixi.heimdall.handler/wrap-record-metric/fn/fn handler.clj: 133
kixi.heimdall.handler/wrap-escape-html/fn handler.clj: 105
compojure.core/routes/fn core.clj: 156
clojure.core/apply core.clj: 659
...
compojure.core/routing core.clj: 148
compojure.core/routing core.clj: 151
clojure.core/some core.clj: 2674
compojure.core/routing/fn core.clj: 151
compojure.core/routes/fn core.clj: 156
clojure.core/apply core.clj: 659
...
compojure.core/routing core.clj: 148
compojure.core/routing core.clj: 151
clojure.core/some core.clj: 2674
compojure.core/routing/fn core.clj: 151
compojure.core/if-method/fn core.clj: 27
compojure.core/if-route/fn core.clj: 45
compojure.core/wrap-route-info/fn core.clj: 126
compojure.core/wrap-route-middleware/fn core.clj: 122
compojure.core/make-route/fn core.clj: 135
compojure.response/fn/G response.clj: 6
compojure.response/fn response.clj: 33
kixi.heimdall.handler/auth-token handler.clj: 45
kixi.heimdall.service/create-auth-token service.clj: 78
kixi.heimdall.service/make-token-pair! service.clj: 58
kixi.heimdall.service/make-refresh-token service.clj: 53
kixi.heimdall.service/private-key service.clj: 31
kixi.heimdall.service/absolute-or-resource-key service.clj: 27
kixi.heimdall.service/private-key/fn service.clj: 31
buddy.core.keys/private-key keys.clj: 96
buddy.core.keys/read-pem->privkey keys.clj: 60
...
org.bouncycastle.openssl.PEMEncryptedKeyPair.decryptKeyPair
org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder$1$1.decrypt
org.bouncycastle.openssl.jcajce.PEMUtilities.crypt
org.bouncycastle.openssl.jcajce.PEMUtilities.getKey (repeats 2 times)
org.bouncycastle.jcajce.util.DefaultJcaJceHelper.createSecretKeyFactory
javax.crypto.SecretKeyFactory.getInstance SecretKeyFactory.java: 160
javax.crypto.SecretKeyFactory.<init> SecretKeyFactory.java: 122
java.security.NoSuchAlgorithmException: PBKDF-OpenSSL SecretKeyFactory not available
org.bouncycastle.openssl.PEMException: Unable to create OpenSSL PBDKF: PBKDF-OpenSSL SecretKeyFactory not available
Code in question
(:require [buddy.core.keys :as ks])
...
(ks/private-key key-file (:passphrase auth-conf))
This started happening with the current build of Oracle java
$ java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
As far as I can tell, the exact same code with same dependencies (and buddy 1.0.0 or 1.2.0) worked on an older version of Hotspot, but stopped working recently.
lein nvd
reports CVE-2018-1000180 and CVE-2018-1000613 present in versions of Bouncycastle prior to 1.60, so it would be nice to bump up the Bouncycastle dependency version.
Version 1.59 addresses CVE-2017-13098.
I was wondering why my clojure app is sometimes taking ~10min to start up on this virtual machine I'm using. Looking at jstack (see below) shows that it's stuck in org.bouncycastle.crypto.generators.ECKeyPairGenerator.generateKeyPair()
, which gets run when buddy.core.jwk.keys.ec
is required, which is required (transitively) by e.g. buddy.sign.jwt
.
The key generation is probably slow because entropy is depleted, but I haven't been able to verify this yet.
I think a suitable fix would be to (delay ...)
the curve creation until they're actually used. I can provide a PR if this sounds reasonable.
Thread 23662: (state = IN_NATIVE)
- java.io.FileInputStream.readBytes(byte[], int, int) @bci=0 (Interpreted frame)
- java.io.FileInputStream.read(byte[], int, int) @bci=4, line=255 (Interpreted frame)
- sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(byte[]) @bci=19, line=539 (Interpreted frame)
- sun.security.provider.SeedGenerator.generateSeed(byte[]) @bci=4, line=144 (Interpreted frame)
- sun.security.provider.SecureRandom$SeederHolder.<clinit>() @bci=20, line=203 (Interpreted frame)
- sun.security.provider.SecureRandom.engineNextBytes(byte[]) @bci=21, line=221 (Compiled frame)
- java.security.SecureRandom.nextBytes(byte[]) @bci=5, line=468 (Compiled frame)
- org.bouncycastle.util.BigIntegers.createRandom(int, java.security.SecureRandom) @bci=29 (Interpreted frame)
- org.bouncycastle.util.BigIntegers.createRandomBigInteger(int, java.security.SecureRandom) @bci=7 (Interpreted frame)
- org.bouncycastle.crypto.generators.ECKeyPairGenerator.generateKeyPair() @bci=22 (Interpreted frame)
- org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC.generateKeyPair() @bci=26 (Interpreted frame)
- buddy.core.keys.jwk.ec$get_curve.invokeStatic(java.lang.Object) @bci=60, line=87 (Interpreted frame)
- buddy.core.keys.jwk.ec$get_curve.invoke(java.lang.Object) @bci=3, line=83 (Interpreted frame)
- buddy.core.keys.jwk.ec__init.load() @bci=386, line=91 (Interpreted frame)
- buddy.core.keys.jwk.ec__init.<clinit>() @bci=15 (Interpreted frame)
CVE-2024-29857 triggered using dependency-check.
Hopefully I'm doing something wrong here :) I was having trouble decrypting a JWT that was encrypted via https://github.com/jwt/ruby-jwe ... however I managed to get the same error to occur directly with buddy:
;; openssl genrsa 2048 > private-foobar.pem
;; openssl rsa -in private.pem -out public.pem -outform PEM -pubout
(-> {:a "b"}
(buddy.sign.jwt/encrypt (keys/public-key "public-foobar.pem") {:alg :rsa-oaep :enc :a128cbc-hs256})
(buddy.sign.jwt/decrypt (keys/private-key "private-foobar.pem") {:alg :rsa-oaep :enc :a128cbc-hs256}))
This returns the hash back successfully.
Adding :zip true
causes the following failure:
1. Unhandled java.lang.ClassCastException
clojure.core$bytes cannot be cast to [B
REPL: 38 buddy.util.deflate/uncompress
REPL: 38 buddy.util.deflate/uncompress
REPL: 80 buddy.sign.jwe/decode-payload
REPL: 77 buddy.sign.jwe/decode-payload
REPL: 252 buddy.sign.jwe/decrypt
REPL: 232 buddy.sign.jwe/decrypt
jwt.clj: 97 buddy.sign.jwt/decrypt
jwt.clj: 93 buddy.sign.jwt/decrypt
REPL: 78 blip-api.authentication/eval25585
REPL: 76 blip-api.authentication/eval25585
Compiler.java: 6927 clojure.lang.Compiler/eval
Compiler.java: 6890 clojure.lang.Compiler/eval
core.clj: 3105 clojure.core/eval
core.clj: 3101 clojure.core/eval
main.clj: 240 clojure.main/repl/read-eval-print/fn
main.clj: 240 clojure.main/repl/read-eval-print
main.clj: 258 clojure.main/repl/fn
main.clj: 258 clojure.main/repl
main.clj: 174 clojure.main/repl
RestFn.java: 137 clojure.lang.RestFn/applyTo
core.clj: 646 clojure.core/apply
core.clj: 641 clojure.core/apply
regrow.clj: 18 refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 646 clojure.core/apply
core.clj: 1881 clojure.core/with-bindings*
core.clj: 1881 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 85 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 55 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 222 clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
interruptible_eval.clj: 190 clojure.tools.nrepl.middleware.interruptible-eval/run-next/fn
AFn.java: 22 clojure.lang.AFn/run
ThreadPoolExecutor.java: 1142 java.util.concurrent.ThreadPoolExecutor/runWorker
ThreadPoolExecutor.java: 617 java.util.concurrent.ThreadPoolExecutor$Worker/run
This was in my REPL environment which is as follows:
;; Connected to nREPL server - nrepl://localhost:51290
;; CIDER 0.13.0snapshot (package: 20160602.809), nREPL 0.2.12
;; Clojure 1.8.0, Java 1.8.0_71
I ran dependency-check-maven
on the pom.xml generated by a tools.deps project using clj -Spom
. The report attached contains the results showing evidence that several pedestal dependencies related to jetty contains high/critical severity. The report is zipped because github do not accept html attachments.
dependency-check-report.html.zip
Current master should be fine but there is no releases after bouncy castle was updated.
I was attempting to decode a JWT from ruby-jwe that had been zipped.
This library falls through to Zlib::Deflate to handle compression. This creates a problem for buddy.util.deflate/uncompress, which gets an exception:
CompilerException java.util.zip.ZipException: invalid stored block lengths
The root cause is creating the Inflater with nowrap set to true. Setting this value to false results in correct decompression. But I spent more time looking at this than I should have :)
Reading the docs it's kind of confusing because it states:
If the parameter 'nowrap' is true then the ZLIB header and checksum fields will not be used.
This makes it sound like they're harmless to have left in there, but it clearly fails if set to true.
Then it goes on to say
Note: When using the 'nowrap' option it is also necessary to provide an extra "dummy" byte as input. This is required by the ZLIB native library in order to support certain optimizations.
You're using the nowrap option but you're not passing in any dummy bytes (that I saw). Yet this apparently doesn't break unwrapped input.
I spent some time fiddling but can't afford to go too far down the bit twiddling rabbit hole. So instead I have a "just try it again" patch that you might be ok with, or you might want to root cause further. Of course if there's anything I can do to help just let me know. Pull request incoming.
Did a search on this repository and wasn't able to find anything matching "illegal access". Just tried updating a project to use openjdk 12, and it looks like bouncy castle isn't playing nice.
WARNING: Illegal reflective access by org.bouncycastle.jcajce.provider.drbg.DRBG (file:<path-to-my-project>) to constructor sun.security.provider.Sun()
at org.bouncycastle.jcajce.provider.drbg.DRBG.findSource(Unknown Source)
at org.bouncycastle.jcajce.provider.drbg.DRBG.<clinit>(Unknown Source)
at org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings.configure(Unknown Source)
at org.bouncycastle.jce.provider.BouncyCastleProvider.loadAlgorithms(Unknown Source)
at org.bouncycastle.jce.provider.BouncyCastleProvider.setup(Unknown Source)
at org.bouncycastle.jce.provider.BouncyCastleProvider.access$000(Unknown Source)
at org.bouncycastle.jce.provider.BouncyCastleProvider$1.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at org.bouncycastle.jce.provider.BouncyCastleProvider.<init>(Unknown Source)
at buddy.core.dsa__init.load(Unknown Source)
at buddy.core.dsa__init.<clinit>(Unknown Source)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:415)
at clojure.lang.RT.classForName(RT.java:2207)
at clojure.lang.RT.classForName(RT.java:2216)
at clojure.lang.RT.loadClassForName(RT.java:2235)
at clojure.lang.RT.load(RT.java:453)
at clojure.lang.RT.load(RT.java:428)
at clojure.core$load$fn__6824.invoke(core.clj:6126)
at clojure.core$load.invokeStatic(core.clj:6125)
at clojure.core$load.doInvoke(core.clj:6109)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5908)
at clojure.core$load_one.invoke(core.clj:5903)
at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
at clojure.core$load_lib.invokeStatic(core.clj:5947)
at clojure.core$load_lib.doInvoke(core.clj:5928)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$load_libs.invokeStatic(core.clj:5985)
at clojure.core$load_libs.doInvoke(core.clj:5969)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
This is when building the project using lein uberjar. I'm using the following dependencies in the file that is invoking buddy functions:
[buddy.sign.jwt :as jwt]
[buddy.hashers :as bh]
I tried running the following but it appears there is no method implementation for :hmac-sha1
. Will this be added?
(mac/hash payload {:key my-secret :alg :hmac+sha1})
I get an exception:
No method in multimethod 'engine' for dispatch value: :hmac+sha1
And I see that the method does not exist in the source.
Exception is org.bouncycastle.crypto.InvalidCipherTextException: checksum failed
This can occur if the token passed in cannot be decrypted. I think the fix is probaly easy, but I'm not sure how this should be reported back to the application so that you can distinguish a bad token from a filed authenticaiton.
To reproduce this issue, you can use the jwe example.
My setup is using immutant/undertow configuration rather than a basic ring/jetty setup, but I don't think this should make a difference.
A possible approach would be to issue a 498 token expired/invalid error?
498 Token expired/invalid (Esri)
Returned by ArcGIS for Server. A code of 498 indicates an expired or otherwise invalid token
i recently tried to use buddy.sign together with buddy.core.keys to generate a JWT for google service account.
google service account you just get a JSON with a privatekey as string, passing it to buddy.core.keys/str->privatekey didnt work. using another lib did the job.
check out https://github.com/xsc/pem-reader for enhancing buddy.core.keys ;)
Using buddy version 0.11.0 buddy.core.codecs
the function (str->base64 "example")
would yield the result that I expected ZXhhbXBsZQ==
Now using version 0.12.1 buddy.core.codecs.base64
the function (encode "example")
which I assume is intended to be a comparable function returns #object[[B 0x26159658 [B@26159658]
certificates/not-before returns incorrect value.
actual result:
not-before = not after date.
expected result:
not-before = not before date.
See the issue in source code (certificates.clj):
(defn not-before
"Returns the first date this certificate is valid."
[cert]
(.getNotAfter cert))
as of now, if I were looking at various sources that your typical user would trust, I would get different version numbers:
Error building classpath. Could not find artifact buddy:buddy-core:jar:1.11.253 in central (https://repo1.maven.org/maven2/)
)https://travis-ci.org/github/funcool/buddy-core hasn't been building for the last 18 months, and https://app.travis-ci.com/github/funcool/buddy-core doesn't appear active currently.
Here's a certificate that I pulled from auth0 and tried to load as a public key for use with JWT and rs256 using buddy.core.keys/public-key
.
This is the error that I see:
java.lang.ClassCastException: org.bouncycastle.cert.X509CertificateHolder cannot be cast to org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-----BEGIN CERTIFICATE-----
MIIDADCCAeigAwIBAgIJXJPtHecVkezqMA0GCSqGSIb3DQEBBQUAMCcxJTAjBgNV
BAMTHGNvbnRhY3Qtc3VwcG9ydC5hdS5hdXRoMC5jb20wHhcNMTYwODMxMDgwNjIz
WhcNMzAwNTEwMDgwNjIzWjAnMSUwIwYDVQQDExxjb250YWN0LXN1cHBvcnQuYXUu
YXV0aDAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp6er9vY8
Ud5FI6bMHLYWUQxFO4jGi8SBh4I3zhOyYgnY1QVLbcJcLhlAN1SpP0xYCcp6SI7e
gLsHRNgiLyFzmJ4FQ6yU8suuz7+kHfMMdRgBMVf0luzQ9sx2LcqBK2cUGJADtclT
RtOnIDYkz9hVB5EaZv2pIR7pM3HLLGj5mv6mJju1848aqb3W8/bbK9amhGvhF0zJ
lA2GBk/lQy7a0bRR8dA95rTu3c8SfwAF9aCPbVngsY/O1VuoWoTVcbL0bs+mWvF2
qDxAVFLpk8KU6X49W5IEDi2XKEG3ogDMTEzBprVb7DLhOnPL6Hd5oolsice6hGLn
by2hgU4AIutphQIDAQABoy8wLTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBQkEEs+
j9VMN4JqxUu0l1ARs5BKOjANBgkqhkiG9w0BAQUFAAOCAQEADb/gA2sFQxbvRMqn
rwV88lB++NJ3Ck7QRw+7wDyeQGMjHQbtkF3xnID695R8j50Ie/Yz1SyzoT4+/Mw4
9RZWOAVGOvZ7ktewXkpHLK0cyCmaBd1J3LJRThH8mMBHoF3XnSKoYTXlUd12Ix+W
Tf+LiRKmJ7RkUkJMy5fi57iMyiFdpHq8/5+EZqwMecWFwkHosxOaM2jrYmvFQ/3I
ZONMj5NB/+fUA2n8JL31DiWEixNyRBjJJlUV8OdKhQYw4k7dMpbYSJ/SyzEFqHKv
MNIRWv8HBGMCeyQfNHhy3/pkeC5AVFVsHTJCwOhPwDdJJpuz66XqiXs7bWQ7hYst
FMj/iA==
-----END CERTIFICATE-----
I just switch from 0.13.0 to 1.0.0 and see now the following exception when doing lein repl
:
Exception in thread "main" java.lang.ExceptionInInitializerError
at clojure.main.<clinit>(main.java:20)
Caused by: java.lang.SecurityException: class "org.bouncycastle.crypto.digests.SHA3Digest"'s signer information does not match signer information of other classes in the same package, compiling:(buddy/core/hash.clj:1:1)
Here's the list of buddy libraries I'm using:
My clojure version is 1.8.0. Reverting buddy-core to 0.13.0 solves the problem.
PS: Thanks for the great work you're doing!
Hello,
First off, I want to say thank you for all of your hard work on buddy. It is much appreciated.
I have some code that I'd like to convert to buddy, and I was wondering if you (or one of the fine people reading this) could help me out:
(ns toy.crypto
(:require [buddy.core.bytes :as bytes]
[buddy.core.crypto :as crypto]
[buddy.core.codecs :as codecs]
[buddy.core.kdf :as kdf]
[buddy.core.nonce :as nonce]
[buddy.core.padding :as padding]
[buddy.core.hash :as hash]
[buddy.hashers :as hashers]
[clojure.data.codec.base64 :as b64]
[clojure.string :as str]
[byte-streams]
[byte-transforms]
[outpace.config :refer (defconfig!)])
(:import [java.io
ByteArrayInputStream
ByteArrayOutputStream]
[javax.crypto Cipher
SecretKeyFactory]
[javax.crypto.spec
IvParameterSpec
PBEKeySpec
SecretKeySpec]))
(def salt "this is some salt")
(def passcode "this is a passcode")
(defonce key-factory (SecretKeyFactory/getInstance "PBKDF2WithHmacSHA1"))
(defonce key-spec (PBEKeySpec. (.toCharArray passcode)
(.getBytes salt)
100000 ;; iterations
256)) ;; AES256
(defonce aes-key (-> key-factory
(.generateSecret key-spec)
(.getEncoded)
(SecretKeySpec. "AES")))
(defn decrypt [payload]
(let [[iv msg] (str/split payload #"--")
iv-spec (-> (byte-transforms/decode iv :base64)
IvParameterSpec.)
cipher (Cipher/getInstance "AES/CBC/PKCS5Padding") ;; I think I read that PKCS5Padding is synonymous with PKCS7Padding when used in this context, but I am not 100% sure on that.
_ (.init cipher Cipher/DECRYPT_MODE aes-key iv-spec)]
(.doFinal cipher (byte-transforms/decode msg :base64))))
(defn encrypt [msg]
(let [cipher (Cipher/getInstance "AES/CBC/PKCS5Padding")
_ (.init cipher Cipher/ENCRYPT_MODE aes-key)
params (.getParameters cipher)
iv (.getIV (.getParameterSpec params IvParameterSpec))
encrypted-msg (.doFinal cipher (.getBytes msg "UTF-8"))]
(format "%s--%s"
(String. (b64/encode iv) "UTF-8")
(String. (b64/encode encrypted-msg) "UTF-8"))))
Any help would be much appreciated!
^:deprecated
attribute is set on some functions, such as buddy.core.hash/sha1
, which constitute a part of public interface of this library.
While it is useful to discourage people from using deprecated cryptographical algorithms in new code, interoperability requirements with existing systems guarantee that these functions will be used for a long time, so ^:deprecated
attribute, which ought to signify deprecation of the code, not of the algorithms, is not really warranted.
Can these attributes be removed? They get in a way when, say, eastwood
is in use.
In buddy-sign there are the relevant RFC's and drafts quoted for JWS/JWT . In terms of buddy-core the following RFC's are relevant. Not entirely sure, perhaps could make sense to quote some of them in the documentation.
https://www.rfc-editor.org/rfc/rfc2104.txt (HMAC)
https://www.rfc-editor.org/rfc/rfc3174.txt (SHA1)
https://www.rfc-editor.org/rfc/rfc3537.txt (HMAC + DES)
https://www.rfc-editor.org/rfc/rfc4634.txt (SHA and HMAC-SHA)
https://www.rfc-editor.org/rfc/rfc4635.txt (HMAC SHA TSIG Algorithm Identifiers)
https://www.rfc-editor.org/rfc/rfc7519.txt (JWT)
https://www.rfc-editor.org/rfc/rfc7677.txt (SASL)
The buddy.core.codecs imports the org.apache.commons.codec.binary.Base64
class but doesn't use it at all.
It would be convenient if there were base64->bytes
and bytes->base64
functions doing conversion from/to base65 encoded string.
Can submit a patch if there's any interest in this.
I am trying out jwe with {:alg :rsa-oaep-256 :enc :a256cbc-hs512}
. It works only if the client and server both use buddy to perform encryption. But if I am using some other library, it does not. I tried with
https://bitbucket.org/connect2id/nimbus-jose-jwt/wiki/Home and https://bitbucket.org/b_c/jose4j/wiki/Home. In both the cases, the cipher is fine, but the auth tag is not compatible. On the other hand, the token generated by jose4j works with nimbus-jose-jwt.
On digging further, the auth token generator seems to be culprit
buddy code
(defn- generate-authtag
[{:keys [algorithm input authkey iv aad] :as params}]
(let [al (if aad
(aad->bytes aad)
(byte-array 0))
data (bytes/concat aad iv input al)
fulltag (mac/hash data {:key authkey :alg :hmac :digest algorithm})
truncatesize (quot (count fulltag) 2)]
(bytes/slice fulltag 0 truncatesize)))
nimbus code
byte[] al = AAD.computeLength(aad);
// Do MAC
int hmacInputLength = aad.length + iv.length + cipherText.length + al.length;
byte[] hmacInput = ByteBuffer.allocate(hmacInputLength).put(aad).put(iv).put(cipherText).put(al).array();
byte[] hmac = HMAC.compute(compositeKey.getMACKey(), hmacInput, macProvider);
byte[] authTag = Arrays.copyOf(hmac, compositeKey.getTruncatedMACByteLength());
jose4j code
Mac mac = MacUtil.getInitializedMac(this.getHmacJavaAlgorithm(), hmacKey, macProvider);
byte[] al = this.getAdditionalAuthenticatedDataLengthBytes(aad);
byte[] authenticationTagInput = ByteUtil.concat(new byte[][]{aad, iv, cipherText, al});
byte[] authenticationTag = mac.doFinal(authenticationTagInput);
authenticationTag = ByteUtil.subArray(authenticationTag, 0, this.getTagTruncationLength());
The Bouncy Castle dependency in buddy-core has the vulnerability CVE-2023-33201. As explained in the description here, Bouncy Castle did not properly check X.500 names for wildcards, leading to potential LDAP injection attacks by including special characters in these names.
Fixing the vulnerability would require updating Bouncy Castle to 1.7.4.
Passing the output of
(buddy.core.codecs/bytes->str (nonce/random-nonce 16)
to a field of type text in PostgreSQL results in the following error:
org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00
Using bytes->hex works, but that seems like a non-optimal way to go about solving the issue.
It seems like every run of (buddy.core.codecs/bytes->hex (nonce/random-nonce 16))
starts with the same sequence 000001549b, or as emacs interprets (buddy.core.codecs/bytes->str (nonce/random-nonce 16))
"^@^@^A".
I think that some base64 codecs are doing double work because apache commons codecs already encodes doing all the things.
I think it would be better to specify in the documentation that there is a dependency to [org.bouncycastle/bcprov-jdk15on "1.54"]
AES-128 requires a 16-byte key - why is the assertion forcing the key to be 32 bytes? The encryption part of the codebase I'm working with is using Java and I want to port it to Clojure. There are already existing encryption keys that were generated to be 128-bit and are stored in a database as base64. I decoded it to a byte array and got a 16-byte key as required, but I get the following error calling crypto/decrypt:
AssertionError Assert failed: (keylength? key 32) buddy.core.crypto/eval43723/fn--43725 (crypto.clj:415)
I used codecs/base64->str to do the decoding.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.