Can't use crypto on Ionic

Hello guys,

I’m currently developing an Ionic App that needs to use some crypto stuff. I used npm to install some packages like js-crypto-aes , js-crypto-ec, …
I created a folder scritps inside src on which I added all my .ts files that use crypto. When I import the functions from those files to my home.page.ts , the editor (vscode) detects all the functions and everything goes well. When i run the scripts with ts-node or tsc, it all goes well.
However, when i start the server I can’t use my crypto functions, because Ionic can’t use the packages properly. It gives me errors like: Error: FailedBothNativeAndPureJSEnvs: UnsupportedJWKType.

Can anyone here help me, please ?
Here is a part of the code:

import hkdf from 'js-crypto-hkdf';
import ec from 'js-crypto-ec';
import keyutil from 'js-crypto-key-utils';
import aes from 'js-crypto-aes';
import hmac from 'js-crypto-hmac';
import {WebApi,Oidc,TransferMethods,NfcOptions,BleOptions,WifiOptions,Security,SessionData, SessionEstablishment} from './deviceEngagement';
import {KeyTypes, KeyCrv, HeaderParameters} from './cose_parameters';
import { encryptEc } from './jscu/packages/js-crypto-utils/dist/pkcec';

async function encrypt_msg(msg,publicKey, iv, salt, { privateKey, hash, encrypt='AES-GCM', keyLength=32, info=''}) {
    hash = 'SHA-256'
    const sharedSecret = await ec.deriveSecret(publicKey, privateKey);
    const hkdfOutput = await hkdf.compute(sharedSecret, hash, keyLength, info, salt); // use HKDF for key derivation
    const aad = new TextEncoder().encode('');
    const aditional_data = await hmac.compute(sharedSecret, aad, hash); // authenticate message

    let data;
    if(encrypt =='AES-GCM') {
        data = await aes.encrypt(msg, hkdfOutput.key, {name: encrypt, iv, additionalData: aditional_data, tagLength: 16}); // no specification of tagLength and additionalData
        return {data, salt: hkdfOutput.salt, iv};
    }
};

The error occurs when I call the encrypt_msg function, and it brokes on the first line it calls the library: const sharedSecret = await ec.deriveSecret(publicKey, privateKey);

Again, when I run the script with ts-node there is no problems.

Insert the standard disclaimer that it is a really bad idea to roll your own cryptographic protocols, so I would strongly urge you to look into finding an existing protocol that fits your needs.

That being said, WebCrypto is an alternative that can be used in Ionic applications without any of the problems you are running into.

1 Like

Thanks! This is working well :slight_smile:

I have to roll my own protocols because I’m following the requirements of an ISO. Just one question (I couldn’t find a straight answer online), can I use it offline ?

Yes. The only caveat that I have run into (and this may no longer be relevant, but keep it in mind) is that the Promises coming out of WebCrypto may not be Angular zone-aware. The easiest way I found to deal with this was to wrap the first one in a chain in an explicit Promise.resolve, like:

Promise.resolve(window.crypto.subtle.encrypt(...)).then();

See diafygi/webcryto-examples for more code samples.