const { subtle } = require('node:crypto').webcrypto; const authentication = require('../src/authentication'); const stringutils = require("../src/stringutils"); describe('authentication module', () => { it('conversion between pem and hex', async () => { let pemKey = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----'; let hexKey = stringutils.pemToHex(pemKey); let pemKeyFromHex = stringutils.hexToPem(hexKey); expect(pemKeyFromHex).toBe(pemKey); }); it('should convert a pemkey to hex', async () => { const { publicKey, privateKey } = await crypto.subtle.generateKey( { name: "Ed25519", }, true, ["sign", "verify"], ); const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey); const exportedBuffer = Buffer.from(exportedPubkey); const exportedAsBase64 = exportedBuffer.toString('base64'); let pemKey = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`; let hexKey = stringutils.pemToHex(pemKey); let importedKey = await stringutils.hexToKey(hexKey); const exportedPubkeyAgain = await crypto.subtle.exportKey("spki", importedKey); const exportedBufferAgain = Buffer.from(exportedPubkeyAgain); const exportedAsBase64Again = exportedBufferAgain.toString('base64'); let pemKeyAgain = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64Again}\n-----END PUBLIC KEY-----`; expect(pemKeyAgain).toBe(pemKey); }); it('should return the public key if the signature is verified successfully', async () => { const { publicKey, privateKey } = await crypto.subtle.generateKey( { name: "Ed25519", }, true, ["sign", "verify"], ); const exportedPubkey = await crypto.subtle.exportKey("spki", publicKey); const exportedBuffer = Buffer.from(exportedPubkey); const exportedAsBase64 = exportedBuffer.toString('base64'); let pemKey = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`; let hexKey = stringutils.pemToHex(pemKey); const publicKeys = [hexKey,]; const msg = 'test message'; const encoder = new TextEncoder(); const encodedData = encoder.encode(msg); const signature = await crypto.subtle.sign( { name: "Ed25519", }, privateKey, encodedData, ); const result = await authentication.verifySignature(encodedData, signature, publicKeys); expect(result).toBe(hexKey); let fakeKey = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=\n-----END PUBLIC KEY-----` let fakeKeyHex = stringutils.pemToHex(fakeKey); const result2 = await authentication.verifySignature(encodedData, signature, [fakeKeyHex,]); expect(result2).toBe(null); }); it('encoding and decoding test', async () => { const testkey = '-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILXfcMirlUiI/o/r+8rK7ZIP0fyAMynxYzJXCI6BJHPk\n-----END PRIVATE KEY-----'; const base64 = testkey.replace(`-----BEGIN PRIVATE KEY-----`, '').replace(`-----END PRIVATE KEY-----`, '').trim(); const derBuffer = Buffer.from(base64, 'base64'); let privkey = await crypto.subtle.importKey( "pkcs8", derBuffer, { name: "Ed25519", }, true, ["sign"], ); const msg2 = '12f4b99e3784ac2e8b95427533a3dbc4'; const encoder2 = new TextEncoder(); const encodedData2 = encoder2.encode(msg2); const signature2 = await crypto.subtle.sign( { name: "Ed25519", }, privkey, encodedData2, ); const signatureBase64 = Buffer.from(signature2).toString('base64'); const sig = Buffer.from(signatureBase64, 'base64'); let pemKey2 = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----'; let hexKey2 = stringutils.pemToHex(pemKey2); const publicKeys2 = [hexKey2,]; const result3 = await authentication.verifySignature(encodedData2, sig, publicKeys2); expect(result3).toBe(hexKey2); }); });