{"id":"019d251d-446b-7853-9423-d0ba653b3d24","title":"Bruce: A Wrapper Around Java Cryptography","slug":"2026/03/bruce-a-wrapper-around-java-cryptography","renderedHtml":"<p>Mirko Caserta has released <a href=\"https://bruce.mirkocaserta.com/\" title=\"a thin Java wrapper around JCA that replaces boilerplate-heavy, mutable-state ceremony with clean, functional interfaces.\">Bruce</a> 2.0, a library that wraps <a href=\"/factoids/JCA\">JCA</a> with a clean API. As such, it attempts to address the same gap for <a href=\"/factoids/cryptography\">cryptography</a> that <a href=\"https://commons.apache.org/proper/commons-email/\">commons email</a> covers for <a href=\"/factoids/JavaMail\">JavaMail</a>: the underlying library is <em>technically</em> correct - the best kind of correct - but a bear to <em>use</em>, and that difficulty creates a barrier that prevents people who really <em>should</em> use the specification from being willing to lean into it.</p>\n<p>JCA works, of course. It's just that using it requires knowledge that casual practitioners aren't likely to have, and this means that we are forced into either learning the ins and outs of cryptography to have decent data security, <em>or</em> we cargo-cult security concerns. It'd be like asking someone to master physics when all they want to do is fly a remote control plane; airflow is important to those designing planes, but requiring a degree for such things is a little much, when even young children are able to come up with paper airplanes that fly well.</p>\n<p>Bruce takes the agony of all the nuts and bolts of security and, well, fixes it. From this, stolen shamelessly from &quot;<a href=\"https://mirkocaserta.com/posts/bruce-before-after/\">Digital signatures in Java: the hard way vs. the Bruce way</a>&quot;:</p>\n<pre><code class=\"language-java\">// Load the keystore\nKeyStore keystore = KeyStore.getInstance(&quot;PKCS12&quot;);\ntry (InputStream is = new FileInputStream(&quot;keystore.p12&quot;)) {\n    keystore.load(is, &quot;changeit&quot;.toCharArray());\n}\n\n// Extract keys\nPrivateKey privateKey = (PrivateKey)\n    keystore.getKey(&quot;alice&quot;, &quot;changeit&quot;.toCharArray());\nPublicKey publicKey =\n    keystore.getCertificate(&quot;alice&quot;).getPublicKey();\n\nbyte[] message = &quot;Transfer $500 to Alice&quot;.getBytes(&quot;UTF-8&quot;);\n\n// Sign\nSignature signer = Signature.getInstance(&quot;SHA256withRSA&quot;);\nsigner.initSign(privateKey);\nsigner.update(message);\nbyte[] signatureBytes = signer.sign();\n\n// Encode for transport\nString encoded = Base64.getEncoder().encodeToString(signatureBytes);\n\n// Decode and verify\nbyte[] decoded = Base64.getDecoder().decode(encoded);\nSignature verifier = Signature.getInstance(&quot;SHA256withRSA&quot;);\nverifier.initVerify(publicKey);\nverifier.update(message);\nboolean isValid = verifier.verify(decoded);\n</code></pre>\n<p>... to this:</p>\n<pre><code class=\"language-java\">var keystore   = keystore(\n    &quot;classpath:keystore.p12&quot;, \n    &quot;changeit&quot;.toCharArray(), \n    &quot;PKCS12&quot;);\nvar privateKey = privateKey(keystore, &quot;alice&quot;, &quot;changeit&quot;.toCharArray());\nvar publicKey  = publicKey(keystore, &quot;alice&quot;);\n\nvar signer = signerBuilder()\n        .key(privateKey)\n        .algorithm(&quot;SHA256withRSA&quot;)\n        .build();\n\nvar verifier = verifierBuilder()\n        .key(publicKey)\n        .algorithm(&quot;SHA256withRSA&quot;)\n        .build();\n\nvar message   = Bytes.from(&quot;Transfer $500 to Alice&quot;);\nvar signature = signer.sign(message);\nvar encoded   = signature.encode(BASE64);      // ready for transport\nvar isValid   = verifier.verify(message, Bytes.from(encoded, BASE64));\n</code></pre>\n<p>I'll be clear: I'm not a cryptographer, and the technical correctness of Bruce isn't something I can vouch for personally. Security libraries earn trust slowly and should - this is not the domain where &quot;looks good to me&quot; is sufficient due diligence. Read the documentation, examine the source, and run your tests. Run <em>all</em> your tests. Write new ones. The exposure surface for cryptographic code is meaningfully different from, say, a misbehaving email client.</p>\n<p>But the API design is immediately legible, the intent is clear, and the problem it solves is real. If it holds up under scrutiny - and that scrutiny is your job for your projects, not mine - Bruce looks like exactly the kind of thing the Java ecosystem needed someone to build.</p>","excerpt":"Mirko Caserta has released Bruce 2.0, a library that wraps JCA with a clean API. Bruce takes the agony of all the nuts and bolts of security and, well, fixes it. Security libraries earn trust slowly and should - this is not the domain where \"looks good to me\" is sufficient due diligence, but the reduced API surface might be a good thing for the normative case.","authorId":"019c5c8a-609d-7cd4-975b-50bbcc412a33","authorDisplayName":"dreamreal","status":"APPROVED","publishedAt":"2026-03-25T13:09:35.407Z","sortOrder":0,"createdAt":"2026-03-25T13:09:28.299082Z","updatedAt":"2026-03-25T15:08:42.081393Z","commentCount":0,"tags":["bruce","cryptography","java","jca"],"categories":[],"markdownSource":null}