RSA is supported in crypto-js-wasm now!
We support all kinds of traditional usage of RSA, including generation of keys, encryption, decryption, digest, sign and verify.
Configurations of RSA should be a object consisting of:
- encryptPadding
- Type:
string - Default:
OAEP - Valid values:
OAEP/PKCS1V15
- Type:
Padding mode for encrypt and decrypt. Case insensitive.
- signPadding
- Type:
string - Default:
PSS - Valid values:
PSS/PKCS1V15
- Type:
Padding mode for sign and verify. Case insensitive.
- hashAlgo
- Type:
string - Default:
SHA256 - Valid values:
MD5/SHA1/SHA224/SHA256/SHA384/SHA512/RIPEMD160
- Type:
Hasher for encrypt, decrypt, sign and verify. Case insensitive.
- key
- Type:
string|number - Default:
1024
- Type:
When key is a string: path to the RSA key file, or the content of RSA key.
- Content of RSA key: should be a string starting with
-----BEGIN PRIVATE KEY-----or-----BEGIN PUBLIC KEY-----. Supported inbrowserandnodejs. - Path to the RSA key file: strings not starting with
-----BEGIN PRIVATE KEY-----or-----BEGIN PUBLIC KEY-----will be parsed as a file path. Only supported innodejs.
When key is a number: size of RSA key. We will generate a new pair of RSA public key and private key according to the key size.
- isPublicKey
- Type:
boolean - Default:
false
- Type:
True if the key is the public key of RSA. Should be used along with key.
Please note that RSA public key can be generated from RSA private key. So if a RSA private key is specified, a corresponding RSA public key will be generated. But RSA private key can NOT be generated from RSA public key.
RSA private key is used in decrypt and sign. Therefore decrypt, sign, generateKeyFile(when generating pairs/private) and getKeyContent(when getting private key) will throw error if no private key is specified.
Configurations can be updated like this:
import C from '@originjs/crypto-js-wasm';
// await the loading wasm
await C.RSA.loadWasm();
const config = {
encryptPadding: 'OAEP',
signPadding: 'PSS',
hashAlgo: 'md5',
key: '/home/user/rsa_private_key.pem',
isPublicKey: false
}
// configurations can be passed with updateConfig
C.RSA.updateConfig(config);
// and can be passed along with other apis like encrypt/decrypt/digest/sign/verify
const encryptedMessage = C.RSA.encrypt('message', {
encryptPadding: 'PKCS1V15'
key: '/home/user/rsa_private_key.pem',
});
const digest = C.RSA.digest('message', {
hashAlgo: 'sha256'
});
const signature = C.RSA.sign('message', {
signPadding: 'pkcs1v15'
});import C from '@originjs/crypto-js-wasm';
// like other algorithms in crypto-js-wasm, you can create a RSA instance
const rsa = new C.algo.RSA();
rsa.loadWasm();
let keyContent = rsa.getKeyContent('private', 'pem');
let encrypted = rsa.encrypt('mesage');
// or you can use the shortcut of RSA
keyContent = C.RSA.getKeyContent('private', 'pem');
encrypted = C.RSA.encrypt('mesage');By default, a pair of private key and public key will be generated with size of 1024. You can change the default keys using updateConfig or updateRsaKey.
import C from '@originjs/crypto-js-wasm';
await C.RSA.loadWasm();
// you can get the key content in string
const privateKeyContent = C.RSA.getKeyContent('private', 'pem');
const publicKeyContent = C.RSA.getKeyContent('public', 'pem');
// you can generate another RSA key
C.RSA.updateRsaKey(2048);
// and you can specify an existing RSA key
C.RSA.updateConfig({
key: '/home/rsa_private_key.pem'
});
// you can generate the RSA key files
// private key file will be generated in ./keys/key.dem
C.RSA.generateKeyFile('private');
// public key : /home/lee/my_rsa_keys/my_rsa_keys_public.pem
// private key : /home/lee/my_rsa_keys/my_rsa_keys_private.pem
C.RSA.generateKeyFile('pairs', 'pem', 'my_rsa_keys', '/home/lee/my_rsa_keys');import C from '@originjs/crypto-js-wasm';
await C.RSA.loadWasm();
const msg = 'testMessage';
const encrypted = C.RSA.encrypt(msg, {encryptPadding: 'pkcs1v15',});
const decrypted = C.RSA.decrypt(encrypted, {encryptPadding: 'pkcs1v15',});
expect(new TextDecoder().decode(decrypted)).toBe(msg);You can get the digest using hash algorithms like md5, sha1 or other ones by yourself. But it's recommended to use RSA.digest, because the hasher you used in digest must be the same with the ones in sign and verify. By using RSA.digest, we can assure the consistency of the hasher in digest, sign and verify.
import C from '@originjs/crypto-js-wasm';
await C.RSA.loadWasm();
const message = 'test message';
const digest = C.RSA.digest(message, {hashAlgo: 'md5',});
const signature = C.RSA.sign(digest, {signPadding: 'pkcs1v15',});
expect(C.RSA.verify(digest, signature)).toBe(true);
const errorDigest = C.RSA.digest('another message', {hashAlgo: 'md5',});
expect(C.RSA.verify(errorDigest, signature)).toBe(false);The implementations of initFromKeyFile and generateKeyFile depends on fs in nodejs(as they are designed to read from or write to files), which means they cannot be used in browser. We will throw an error if the runtime is not nodejs, but the usage of fs still may report in webpack like this:
Module not found: Error: Can't resolve 'fs' in '...\node_modules\@originjs\crypto-js-wasm\lib'For webpack > 5, you can add this in your webpack.config.js to avoid the error report(check this issue for details):
module.exports = {
...
resolve: {
fallback: {
fs: false
},
}
}