The number that stays in my head about keyboard sound is 95%. In 2023 Harrison, Toreini and Mehrnezhad put an iPhone next to a MacBook Pro and trained a network on the sound of the keys. It got 95% of keystrokes right and 93% on a Zoom recording made with the laptop’s own microphone. In 2025 Spata and coauthors got 98.3% on the same MacBook data, then recorded a mechanical keyboard and reported 99% on it. I have a small tool, earshot, that listens to the microphone and writes down speech. The same microphone hears every key I press. I had read the 95% several times and never asked what exactly it was measured on. Both datasets are public under MIT, so this time I downloaded them and looked.
The setup
Both sets are built the same way. 36 keys, the digits and the letters. Every key is its own WAV file with 25 presses in a row, about 1 second apart. Harrison has 2 recordings of the same MacBook. One is from the phone lying on a microfibre cloth, the other from Zoom at 32 kHz with noise suppression set to the minimum. The KAD set from Spata is a mechanical keyboard and a smartphone 17 cm away, plus 10 passwords typed key by key, one recording each.
I wanted to see how much a simple model takes, so no deep network. Python 3.12, numpy 2.5.3, scipy 1.18.1, scikit-learn 1.9.0 on 4 CPU cores. Each press is cut out by an energy threshold that adapts until the file gives exactly 25 presses. Then 330 ms of sound becomes a log mel spectrogram with 64 bands and a logistic regression looks at it. Chance with 36 keys is 2.8%.
For testing I split the presses by position in the file: presses 0 to 4 in one fold, 5 to 9 in the next and so on. A random split would put the time neighbours of most test presses into training. Here only the presses at the edge of a fold have one.
The result was 92.4% on the MacBook through the phone, 84.6% through Zoom and 99.3% on the mechanical keyboard. A linear model with no augmentation came within 3 points of Harrison’s network on the phone recording. On the mechanical keyboard it matched the 99% from Spata. I did not expect that. On Zoom it was 8 points behind. Spata also got 98.3% on the phone recording, 6 points more than mine. The papers split the data differently, so this is a rough comparison.
Where I stopped believing it
Then I looked again at the file layout and it bothered me. Every key lives in its own recording. Say the phone moved a little between the recording of a and the recording of b. Then the classifier can learn the file instead of the key. The test above will not notice, because test presses come from the same files.
So I trained the same model on the silence. From each press I took 200 ms that start 400 ms after it, where the sound is 24 to 36 dB below the press. Then I asked which key this piece of silence belongs to. On the MacBook through the phone the silence named the key 29.4% of the time, through Zoom 16.1%, on the mechanical keyboard 39.4%. That is 6 to 14 times chance.
The recording alone carries enough to name the key. The classifier on the presses may be using it too. How much, I cannot say from these files.
The KAD passwords are the check that the file cannot help with. There the keys follow each other inside one recording. I trained on all 900 presses from the key files and tested on the 100 presses inside the 10 passwords. I told the isolator how many characters each password has. 77 of 100 were right. In 93 of 100 the right key was in the top 5. 1 password of 10 came out whole, baseball47. The worst was position90, heard as ppsvtnpk00.
Of the 23 wrong guesses, 10 landed on a physical neighbour of the right key. For a random pair of keys on this layout it is 13%. With a dictionary that is a useful list of candidates, but a password with digits at the end still needs 10 right guesses in a row.
Spata did a test of the same kind, on 8 passwords recorded later on the same keyboard. Their network got 89.1% on average. Their passwords are not in the public set, so I cannot compare directly, but it is 12 points above my 77. Harrison’s paper has no test like this.
Where it breaks
Another recording of the same keyboard. I trained on the phone and tested on Zoom, same MacBook and same typist. It got 6.3%. The other direction gave 4.9%. I thought the reason was the different band, Zoom at 32 kHz against 44.1 kHz on the phone. So I kept only the mel bands below 8 kHz and subtracted the mean log mel spectrum of each recording as a crude equaliser. The best of it was 12%, 4 times chance. The change here is a different microphone, a different session and Zoom’s processing at once. I cannot separate them. The 92% and the 85% in the first figure are 2 separate models, each trained on its own recording.
Noise. This one I got wrong first. I added white noise 30 dB below the press and the MacBook model fell to chance. I spent some time looking for a bug in the noise code before I compared levels by band. Most of the room sound in the phone recording sits in the low bands. Above 1.1 kHz it is so quiet that even noise 60 dB below the press is louder than the room. This is so in 47 of 64 mel bands. With the last 5 presses of each file held out, the model had 88% on clean presses, 43% at 60 dB and 5.6% at 50 dB. My guess is that it leans on those nearly silent high bands.
Then I gave the training presses the same noise at the same level. The MacBook model holds 86% at 60 dB, 61% at 30 dB and 26% at 0 dB, where the noise is as loud as the press. The mechanical keyboard stays at 97% even at 0 dB. Each of these models knew the noise level in advance.
Training data. All of this needs labelled presses of exactly this keyboard in exactly this place. On the same held out presses, 1 labelled press per key gave the MacBook model 11%, 5 presses 41% and 20 presses 88%. The mechanical keyboard needs less, 50% from 1 press and 89% from 5. Somebody has to type every key into the microphone first or the attacker has to label the presses by other means. Papers that do it without labels use a language model. That is a separate piece of work and I did not repeat it.
What I did not check
I did not record my own keyboard. The measurement ran on a server without a microphone, so everything above is 2 public datasets and 3 recordings. Harrison’s set is one typist, KAD does not say. I did not try the deep networks from the papers, so the transfer between recordings may be better with them. I did not try typing at normal speed, where the presses overlap, because my isolator needs 200 ms between presses. On the MacBook recording the sound is still fading in the silence window, so a part of the 29% there may be the key itself. The password test does not depend on this. Every number here is 1 run. My models are deterministic and the noise has a fixed seed.
For me the result is narrower than the headline. The sound of a key does carry the key. On the password test my linear model got 77 of 100 and Spata’s network got 89.1% on theirs. But in both cases it is the same keyboard, the same room and the same microphone as in training. With my model another recording of the same MacBook brings it down to 5 or 6%. What part of the 95% on the MacBook comes from the file, I cannot tell from this dataset.