const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp'); const chai = require('chai'); chai.use(require('chai-as-promised')); const expect = chai.expect; /* eslint-disable no-unused-expressions */ /* eslint-disable no-invalid-this */ const native = openpgp.util.getWebCrypto() || openpgp.util.getNodeCrypto(); (!native ? describe.skip : describe)('basic RSA cryptography with native crypto', function () { it('generate rsa key', async function() { const bits = openpgp.util.getWebCryptoAll() ? 2048 : 1024; const keyObject = await openpgp.crypto.publicKey.rsa.generate(bits, "10001"); expect(keyObject.n).to.exist; expect(keyObject.e).to.exist; expect(keyObject.d).to.exist; expect(keyObject.p).to.exist; expect(keyObject.q).to.exist; expect(keyObject.u).to.exist; }); it('sign and verify using generated key params', async function() { const bits = openpgp.util.getWebCryptoAll() ? 2048 : 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const message = await openpgp.crypto.random.getRandomBytes(64); const hash_algo = openpgp.enums.write(openpgp.enums.hash, 'sha256'); const hashed = await openpgp.crypto.hash.digest(hash_algo, message); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const signature = await openpgp.crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed); expect(signature).to.exist; const verify = await openpgp.crypto.publicKey.rsa.verify(hash_algo, message, signature, n, e, hashed); expect(verify).to.be.true; }); it('encrypt and decrypt using generated key params', async function() { const bits = openpgp.util.getWebCryptoAll() ? 2048 : 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = openpgp.util.Uint8Array_to_str(await openpgp.crypto.generateSessionKey('aes256')); const encrypted = await openpgp.crypto.publicKey.rsa.encrypt(openpgp.util.str_to_Uint8Array(message), n, e); const result = new openpgp.MPI(encrypted); const decrypted = await openpgp.crypto.publicKey.rsa.decrypt(result.toUint8Array(), n, e, d, p, q, u); expect(decrypted).to.be.equal(message); }); it('decrypt nodeCrypto by bnCrypto and vice versa', async function() { if (!openpgp.util.getNodeCrypto()) { this.skip(); } const bits = 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = openpgp.util.Uint8Array_to_str(await openpgp.crypto.generateSessionKey('aes256')); const encryptedBn = await openpgp.crypto.publicKey.rsa.bnEncrypt(openpgp.util.str_to_Uint8Array(message), n, e); const resultBN = new openpgp.MPI(encryptedBn); const decrypted1 = await openpgp.crypto.publicKey.rsa.nodeDecrypt(resultBN.toUint8Array(), n, e, d, p, q, u); expect(decrypted1).to.be.equal(message); const encryptedNode = await openpgp.crypto.publicKey.rsa.nodeEncrypt(openpgp.util.str_to_Uint8Array(message), n, e); const resultNode = new openpgp.MPI(encryptedNode); const decrypted2 = await openpgp.crypto.publicKey.rsa.bnDecrypt(resultNode.toUint8Array(), n, e, d, p, q, u); expect(decrypted2).to.be.equal(message); }); it('compare webCrypto and bn math sign', async function() { if (!openpgp.util.getWebCrypto()) { this.skip(); } const bits = openpgp.util.getWebCrypto() ? 2048 : 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = await openpgp.crypto.random.getRandomBytes(64); const hashName = 'sha256'; const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashed = await openpgp.crypto.hash.digest(hash_algo, message); let signatureWeb; try { signatureWeb = await openpgp.crypto.publicKey.rsa.webSign('SHA-256', message, n, e, d, p, q, u, hashed); } catch (error) { openpgp.util.print_debug_error('web crypto error'); this.skip(); } const signatureBN = await openpgp.crypto.publicKey.rsa.bnSign(hash_algo, n, d, hashed); expect(openpgp.util.Uint8Array_to_hex(signatureWeb)).to.be.equal(openpgp.util.Uint8Array_to_hex(signatureBN)); }); it('compare webCrypto and bn math verify', async function() { if (!openpgp.util.getWebCrypto()) { this.skip(); } const bits = openpgp.util.getWebCrypto() ? 2048 : 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = await openpgp.crypto.random.getRandomBytes(64); const hashName = 'sha256'; const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashed = await openpgp.crypto.hash.digest(hash_algo, message); let verifyWeb; let signature; try { signature = await openpgp.crypto.publicKey.rsa.webSign('SHA-256', message, n, e, d, p, q, u, hashed); verifyWeb = await openpgp.crypto.publicKey.rsa.webVerify('SHA-256', message, signature, n, e); } catch (error) { openpgp.util.print_debug_error('web crypto error'); this.skip(); } const verifyBN = await openpgp.crypto.publicKey.rsa.bnVerify(hash_algo, signature, n, e, hashed); expect(verifyWeb).to.be.true; expect(verifyBN).to.be.true; }); it('compare nodeCrypto and bn math sign', async function() { if (!openpgp.util.getNodeCrypto()) { this.skip(); } const bits = 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = await openpgp.crypto.random.getRandomBytes(64); const hashName = 'sha256'; const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashed = await openpgp.crypto.hash.digest(hash_algo, message); const signatureNode = await openpgp.crypto.publicKey.rsa.nodeSign(hash_algo, message, n, e, d, p, q, u); const signatureBN = await openpgp.crypto.publicKey.rsa.bnSign(hash_algo, n, d, hashed); expect(openpgp.util.Uint8Array_to_hex(signatureNode)).to.be.equal(openpgp.util.Uint8Array_to_hex(signatureBN)); }); it('compare nodeCrypto and bn math verify', async function() { if (!openpgp.util.getNodeCrypto()) { this.skip(); } const bits = openpgp.util.getWebCrypto() ? 2048 : 1024; const keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsa_sign, bits); const n = keyParams[0].toUint8Array(); const e = keyParams[1].toUint8Array(); const d = keyParams[2].toUint8Array(); const p = keyParams[3].toUint8Array(); const q = keyParams[4].toUint8Array(); const u = keyParams[5].toUint8Array(); const message = await openpgp.crypto.random.getRandomBytes(64); const hashName = 'sha256'; const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashed = await openpgp.crypto.hash.digest(hash_algo, message); const signatureNode = await openpgp.crypto.publicKey.rsa.nodeSign(hash_algo, message, n, e, d, p, q, u); const verifyNode = await openpgp.crypto.publicKey.rsa.nodeVerify(hash_algo, message, signatureNode, n, e); const verifyBN = await openpgp.crypto.publicKey.rsa.bnVerify(hash_algo, signatureNode, n, e, hashed); expect(verifyNode).to.be.true; expect(verifyBN).to.be.true; }); });