Explainer Technical

ECDSA signatures with node.js and Swift

In the process of de-risking some business model questions for Digamo, I went looking for an open source project that would allow us to generate and verify license keys. We’re not sure what our business model will be there, but understanding the technical costs of licensing is important to making decisions.

While this is a problem that has been solved, I didn’t find anything especially modern, well-maintained, or documented—and nothing in Swift or Node, which I’m using for everything right now.

Some research did suggest that asymmetric cryptography was the way to go, using a private key to sign a registration string, and a public key distributed with the app to verify the signature. This was also the approach used in the older projects that tried to solve this problem for Mac apps.

Still, I found precious little documentation or tutorials to walk me through the implementation. All the signing examples took place within the same context, rather than between client and server. Here’s an approach that appears to be working, using Node and a Swift Mac app.

Try the demo

Generate a signed message file here:

Download, build and run the macOS verification app here:

Once the app is running, you can double-click the signed message files from the Glitch app to automatically load them. File free to tamper with the content of the plaintext field by opening a file in your favorite text editor, then try to verify again. Tampering should cause the verification step to fail.

The public and private keys are included for your inspection and experimentation, as a “known-good” configuration. In your own projects you should use care to ensure your private key is not distributed.

Generate encryption keys

Per the instructions from IBM’s BlueECC project, here’s how you get started:

On macOS you can install OpenSSL using brew:

brew install openssl

Once you have installed OpenSSL, create your private key:

openssl ecparam -name prime256v1 -genkey -noout -out ec256priv.pem

Using the private key, create your public key:

openssl ec -in ec256priv.pem -pubout -out ec256pub.pem

It seems you want to use the prime256v1 curve—other algorithms have some cross-platform issues.

This will leave you with a private and public key. The private key goes on your server to generate signatures. The public key can be distributed with your app to verify those signatures.

Signing with Node.js

The npm module EC-Key will make it easy to load your key:

let ECKey = require("ec-key");

let pem = fs.readFileSync("./privatekey.pem");
let eccPrivateKey = new ECKey(pem, "pem")

Here my implementation gets a little clunky—there may be better ways to do this, but at least it seems pretty flexible. Create a JavaScript object with whatever keys and content you want:

var objectToSign = {}
objectToSign.message = message
let date = new Date().toJSON() = date

Convert that into a JSON string:

let outputString = JSON.stringify(objectToSign)

Then, create a signature from that string:

let signature = eccPrivateKey.createSign("SHA256").update(outputString).sign("base64")

And pack the plaintext string and signature into a second object:

let outputObject = {}
outputObject.plaintext = outputString
outputObject.signatureBase64 = signature

You can then convert the output to JSON and have the user download the file.

See the whole thing in action with this Glitch project.

Verification in Swift

Add the BlueECC package to your project. Install manually, or use the Swift Package Manager. In Xcode, choose File > Swift Packages > Add Package Dependency…

Search for “CryptorECC,” and pick “BlueECC.”

Add your public key file to your project, and import CryptorECC
to the file where you’re working. Then you can grab the public key like this:

let filepath = Bundle.main.path(forResource: "ec256pub", ofType: "pem")!

let keyString = try? String(contentsOfFile: filepath)

let publicKey = try ECPublicKey(key: keyString)

With the public key loaded from your bundle into memory, you can now verify a signature with it:

let signature = try ECSignature(asn1: Data(base64Encoded: signatureBase64)!)

(signatureBase64 is the output from createSign() above)

let verified = signature.verify(plaintext: plaintext, using: publicKey)

The constant verified will tell you if the plaintext and signature match.

Here’s a Mac app you can build and run to see this in action.


Is this a good approach? See anywhere it could work better? Drop me a line:


Review: RGB Mechanical Keyboard and Pioneer Mouse by VicTsing

A couple months ago, the folks at VicTsing reached out and offered to provide their keyboard and mouse for a review. I’m a sucker for input devices so I took them up on it.

Through their contact, Haven, I tried to learn more about the company’s origins and story. Haven was friendly but ultimately couldn’t share much with me. Who started this company? What are their goals?

The answers are a mystery.

Which is a shame. In a sea of commodity junk, VicTsing’s products stood out to me as both thoughtful and well-built. I’d love to understand their philosophy better. What I can tell you is what you can read yourself on their about page: they were founded in 2012 and they sell everything from computer and car accessories to humidifiers.

Checking out these two products can tell us a lot about how electronics commerce works in 2019. Faced with competition from better-known brands and contending with ever-dropping prices, the savvy move for new players is to differentiate through features. What we see here are a keyboard and mouse that do the basics well, but add a little something extra.

The keyboard

I cut my teeth as a spreadsheet jockey, so I grew attached to having a numeric keypad. The problem is, extended keyboards with keypads are huge, and these days I don’t need a numeric keypad that often. As a result I’ve trimmed down to the ten-keyless or “TKL” style in recent years. The typical TKL shaves off the numeric keypad, but keeps the clusters of arrow keys and Insert/Home/Page Up, etc.

Most of the time this is fine. But occasionally, I still miss the numeric keypad.

And I thought I just had to live with it.

But VicTsing came up with a clever alternative1. Using a key to switch modes, it overlaps the numeric keypad with the button clusters you typically find on the right of a TKL. You can have both.

QMK enthusiasts will recognize this trick at once: it’s using layers to shift part of the keymap. But thoughtful design also makes these feature easy to understand: when the numeric keypad is disabled, the light pattern changes to create the silhouette of a typical right-hand cluster.

in TKL mode
in numeric keypad mode

Indeed, the RGB color effects suggest QMK may be driving this under the hood. This would be smart—it lowers the cost of building interesting features like this variable-mode keypad.

More thoughtful touches: the keyboard comes with a blank key you can use to replace the “Win” key if you’re a Mac user, which I appreciated, and it’s stored on the case, which was nice. Alongside it was storage for an included keycap plucker, which is great for those who want to rearrange their keys.

Other than that, it’s an RGB mechanical keyboard. They’re blue switches, so the keyboard is loud and clicky. I think I prefer my Kaihua whites, but they’re perfectly fine switches.

My only gripe is with the shine-through, which has some weird stencil cutout effects. It’s a strictly aesthetic issue, but it makes this otherwise excellent keyboard feel a little cheap.

Still, it’s a pretty great buy, currently retailing at $43 on Amazon. Or, $40 if you don’t want the white frame. I actually liked the keyboard a lot better when I took the frame off, so save a few bucks if you want.

In the realm of budget mechanical keyboards, this one has some nice touches that separate it from the pack. Nice way to try out the mechanical life if you’re tired of rubber cup keyboard junk, too.

The mouse

Meanwhile, I just love the Pioneer mouse. It’s the best rechargeable mouse you can buy for $30, simple as that. You charge it with a USB micro cable, so no batteries to manage. It has scroll wheels for vertical and horizontal, along with some nice side buttons for forward/back in your web browser.

But the best part is: you can use it with three computers at once.

It includes a dongle for a wireless USB connection, but can also pair with up to two more devices via Bluetooth. This is very handy if you have, say, a Mac and a gaming PC, like I do.

But even if you don’t, the fact that you have the option of using a dongle but still have a perfectly useful mouse even if you (inevitably) lose that dongle is a fantastic touch.

The only issue I have with this mouse is its plastic pads, which feel a little rough against my work surface. Compared to my Logitech mice, which glide smoothly, the Pioneer feels like it’s gently scraping.

Still, it’s not a dealbreaker.

Mac users will want to use something like SensibleSideButtons to enable the back and forth buttons.

It’s a pretty good buy at $30. For similar prices, you can get a Logitech G602, which has adjustable DPI settings like the Pioneer, but requires AA batteries. Or you can get the Logitech Triathlon, which allows similar multi-device connectivity, but lacks DPI control and also requires AA’s.

The Pioneer gives you adjustable DPI, multiple devices and a rechargeable battery in one package at a competitive price. It is a right-handed mouse, though as a lefty I don’t find that a dealbreaker. As a hedge against RSI, I try to switch mousing hands every couple years2.

They’re good input devices, Bront

Despite so many competing options in both categories, I think both of these entries are pretty solid. VicTsing clearly has some product vision to help it stand out from the crowd. It’s worth checking these out if you need a keyboard or mouse soon.


Augmented reality and the exocortex

With Apple leaking their AR project timeline, CNBC has a roundup of all the players trying to make an entry in this category. Unanswered is why all of these companies are chasing a dream that, so far, hasn’t delivered.

In Charles Stross’s Accelerando, a partly tongue in cheek take on the road to a technological singularity, a primary component of the transhumanist future is the “exocortex,” a component of your mind that exists outside of the brain you were born with. While the point of science fiction is not, for me, to be predictive, I found Accelerando full of surprisingly plausible extrapolations.

The smartphone was the first meaningful step toward an exocortex. It “remembers” things for you, like meetings and tasks you mean to do in the future. It communicates and receives data on your behalf, amplifying the reach of your ideas. But the exocortex is not, in this example, mere local hardware. The smartphone connects you to cloud-based mapping platforms, extending your mind’s ability to navigate. Your exocortex, comprised of a suite of local and remote applications, allows you to “know” how to reach a particular place you’ve never visited.

So what we get from the smartphone is a meaningful expansion of our mind’s base abilities, in an interface which is nearly as portable as our mind itself.

The interface between our mind and our exocortex is, for now, our eyes. The eyes are the highest bandwidth channels into the brain our biology provides as stock—10 megabits of data per second. So if you want to get a large quantity of data back into the brain, the eyes are the ticket.

This is why so much effort has gone into screen technology since the advent of the iPhone, and why the iPhone was so category defining: the entire surface of the product could be directed toward information transmission to the brain via the eyes. Much more rewarding than the narrow windows standard to the Blackberry devices of the day.

But there are limits here: you have to hold the device to see the input, and you have to choose between the device’s input and data from the outside world. This creates friction.

AR is the inevitable next step to network our brains with a growing exocortex. We’re still far away from direct neurological interfaces, and we’re far from maxing out the potential of the optical channel.

This category will happen and will usher in all new ways of doing everything, as much as the smartphone did. The only questions are:

  • How long will it take to meaningfully miniaturize the hardware to solve this in an appealing way?
  • What is the level of software maturity needed to bring this into mainstream use? In other words, how far are we from killer apps?
  • What are the input devices needed to comfortably send data back out of your mind in the absence of your fingers on a screen?

“Smartphone” was a category before the iPhone. Blackberry, Palm, HTC, Danger and others had internet-enabled communicators years before 2007. Like today’s AR devices, though, these were sold in mostly niche, business-focused markets. It would take a breakthrough in miniaturization and interaction design to make this technology ubiquitous.

It seems we’re waiting on the same event for augmented reality.

By 2030, we all have AR headsets, though. I’m willing to bet anything on that.