I am trying to import an ECDSA public key generated using the ssh-keygen
command in order to verify signatures using the subtle crypto module. I am getting an error, but without any details.
The command I'm using to generate the key:
ssh-keygen -t ecdsa
And the public key looks like this:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNBCvx3dHLrP0cXR0Iev5laJombKI7N4ND4wXdnwACrs5q2x1zIT9Adf9QtyVkc61acE1xzQ6sqnELAzw511cBM=
Here's a minimal snippet to reproduce the issue. It's a file input that reads the public key as an ArrayBuffer and tries to load it using the importKey()
method.
const loadKey = async (data) => {
const key = await crypto.subtle.importKey(
'raw',
data,
{
name: 'ECDSA',
namedCurve: 'P-256',
},
false,
['verify']
)
return key
}
const awaitedFR = async (file) => new Promise((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('load', ({target}) => resolve(target.result))
reader.addEventListener('error', reject)
reader.readAsArrayBuffer(file)
});
(async () => {
const _main = document.querySelector('main')
const fileInput = document.createElement('input')
fileInput.type = 'file'
fileInput.addEventListener('change', async ({target}) => {
const file = target.files[0]
const res = await awaitedFR(file)
console.log(res)
try {
const key = await loadKey(res)
_main.innerHTML += 'Succesfully loaded public key'
} catch (error) {
_main.innerHTML += 'Failed to load public key: ' + JSON.stringify(error)
}
console.log(key)
})
_main.appendChild(fileInput)
})();
<main></main>
Using the browser devtools I can see that the ArrayBuffer is correctly loaded in memory and the curve is properly set in the importKey()
EcKeyImportParams.curve
parameter (ssh-keygen defaults to NIST-P256).
I have no clue as of why this does not work, the script just fails silently. I also tried to export the key as PKCS#8 (and changing the format
argument of the importKey()
method) but to no avail.
There is no problem using keypairs generated directly in the browser though, my guess so far would be a formatting issue.