profile
viewpoint

Ask questionsOpenPGP.js and LiquidCore in Android

Hi guys, I use LiquidCore (Node.js virtual machine) inside my Android App (java). And I'm trying to use openpgp.js under Node. But it doesn't work. The problem is described in more detail here https://github.com/openpgpjs/openpgpjs/issues/1080

How to convince LiquidCore build system to treat openpgp.js as an external dependency and require openpgp.js at runtime, instead of at build time?

Unfortunately I could not get openpgp.js outside of the bundle (as an external dependency) during apk building in Android Studio. And the file "metro.config.js" with "...blacklistRE: blacklist([/dist/.*/]" and other options didn't help me.

Thanks a lot

LiquidPlayer/LiquidCore

Answer questions ericwlange

Hi @boby1975 ,

You will have to hack around it. It looks like openpgp is using its own bundled code, and then LiquidCore is bundling on top of it. I have managed to work around it by replacing offending require() statements with LiquidCore.require(). This bypasses the bundler override and uses stock node require().

Also, for whatever reason, they have chosen not to package asn1.js into openpgp.js. I am guessing they had a problem with packaging it due to some circular references or something. So it is looking for that module at runtime. I already built some intelligence into the LiquidCore bundler so that it can handle circular requires.

To get this to work, you need to add to the top of your javascript file:

const asn1 = require('asn1.js')
global.requireASN1 = () => asn1
const openpgp = require('openpgp')

It is important that you create the requireASN1() function before you require openpgp.

Then you must patch your node_modules/openpgp/dist/openpgp.js file:

8016c8016
<     var crypto = require('crypto');
---
>     var crypto = LiquidCore.require('crypto');
23792c23792
<     crypto = require('crypto');
---
>     crypto = LiquidCore.require('crypto');
23821c23821
< const NodeReadableStream = _util.isNode && require('stream').Readable;
---
> const NodeReadableStream = _util.isNode && LiquidCore.require('stream').Readable;
24139c24139
< const NodeBuffer = _util.isNode && require('buffer').Buffer;
---
> const NodeBuffer = _util.isNode && LiquidCore.require('buffer').Buffer;
24596c24596
< const NodeReadableStream = isNode && require('stream').Readable;
---
> const NodeReadableStream = isNode && LiquidCore.require('stream').Readable;
30022c30022,30023
< const asn1 = nodeCrypto ? require('asn1.js') : undefined;
---
> //const asn1 = nodeCrypto ? require('asn1.js') : undefined;
> const asn1 = nodeCrypto ? requireASN1() : undefined;
30622c30623,30624
< const asn1 = nodeCrypto ? require('asn1.js') : undefined;
---
> //const asn1 = nodeCrypto ? require('asn1.js') : undefined;
> const asn1 = nodeCrypto ? requireASN1() : undefined;
31185c31187
< const nodeCrypto = _util2.default.detectNode() && require('crypto');
---
> const nodeCrypto = _util2.default.detectNode() && LiquidCore.require('crypto');
43138c43140
<     return require(module);
---
>     return LiquidCore.require(module);

I was able to get it to generate a key with the following code:

const asn1 = require('asn1.js')
global.requireASN1 = () => asn1
const openpgp = require('openpgp')

var options = {
  userIds: [{ name: 'Alice', email: 'alice@example.com' }],
  numBits: 2048,
  passphrase: 'secret'
}
var pubKey, privKey
openpgp.generateKey(options).then(key => {
  privKey = key.privateKeyArmored
  pubKey = key.publicKeyArmored
  console.log('Key generated')
  console.log('Public key = ' + pubKey)
})
2020-04-17 12:03:22.833 9200-9252/org.liquidplayer.testapp I/stdout: Key generated
2020-04-17 12:03:22.833 9200-9252/org.liquidplayer.testapp I/stdout: Public key = -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: OpenPGP.js v4.10.2
    Comment: https://openpgpjs.org
    
    xsBNBF6ZfukBCAC96Fk1Z+dD0CMOAzL0OSewNovtQVDmpb+9SHEjB4LdhH5o
    obreI2Ua7+MrJkg6K06C7ED21qKI1+HDXtiTUALj1ZsCKxcuy3lx8ZjJNo+d
    4WrcFarPBL3KOe8aSjYKqMzrlM4MzXWbfb5W7gUxGExILuuU8a9GkeshtgFE
    8l6/rZwdiAm7FcWAwZC1geZdIw/xu7tNKZ1PAtzFPHxioxHpsMoXS/4d8w/L
    BjJDqfWWEERLZ+EK12vwX3Ftxh6OWsfC5Oeb9B/JSKC8YoDpV3zG1DDUiXF6
    yx7Zp/Pk7feKLZI1tPnh/EyHFehNylHcltF8ErgEfsVl83vzMH3VQU8DABEB
    AAHNGUFsaWNlIDxhbGljZUBleGFtcGxlLmNvbT7CwHYEEAEIACAFAl6ZfukG
    CwkHCAMCBBUICgIEFgIBAAIZAQIbAwIeAQAKCRCxwSPraGOBAN87B/9kFRf1
    ZA65mwAWCwnGuoFX425pcP08b9Kquykx9KKYpt2I5/NbCIBdGFbYA0VPJMV/
    /h6Lwr2wqEc3MR4uoKm8EQReMEp2MdrxJunwVC+2j7OTngxz6EKBpgxSkYos
    KlFH+VmTtKtoY8sQ8NhgUpumRhC1c2Gg8Kp00A+zXmgwA1GN3+4pEB0uiQtT
    Cjls3TJT1xTRMhR2GWM96y+zSmiAMofQOOBnPlnIq9Bxl96ylaOo13h/Q75i
    BAplNVOX8j59eET/o4G8cG2uG715SV/RJ7MRJxCEgijnIZXmAr5FPtKQ+OUV
    QqOAPIIJE4bn3zkBiLVcpG61Fk7GfeWk+5YXzsBNBF6ZfukBCADclvmuQUa2
    F4A8qromgtN9ayyn4SKX588YSF6F/ZGFqK6f5Q2fb01k8hgwpOoW64YjfOQj
    nO5Ub3tnxes5dIwOOKXktT1bbf9DOLISH9Wip1rER3cVdSTuYxN98oJBiZpd
    xqAAWo8vU7REAw7wN0bRpSpZRlYT1GK7nYBid07oS5rEHxAFzfQN97Ih2gEW
    kaH2LHuXD/5zhoi3J2ulNoZ0AvjznFCtWV7idiBFdXMyEyRMHXNUTbd81SmF
    IRkD28iUxMzzt37o3cmqnN6/cq8+SM0crxhibRhFwYRuLzZeMBJLZ9+0aQO3
    1Ylrop01yQ0zj4hYoCExg86qcKgtzINLABEBAAHCwF8EGAEIAAkFAl6ZfukC
    GwwACgkQscEj62hjgQBPhQf/TW5kvv5JI/8kpuRs7lvWeHED/qVcwCDeTGF4
    96fH8zXsi1/cz/c9ntXSeBD6oB91d53GfQLCwQSx9eDLo/UG6T4IWfDQvMB3
    l8q4Hgc6ynQsm3qMANZdMSvQ3hS16bR70vCkYCPSyuG1rZ1o8XUp3R1Be5l0
    1IZHJBMkFbpTyNwHtBvq5WIDAVi+Cm8Mv1JmX4STbS5tRs3yNpK/ASIEmm6W
    tGJMOhjLxAGhwyMHBIKLhjEHEiaSHYlEDiXDwaZ4GWg/5qKBjSW0X/aDlpNf
    C6/0thIGSt6P4WnN6LXxBg5NL1PWNdK9IVa9B8pDbL/dpMZcJXCFuMCsKZEC
    gIn9Mg==
    =X7se
    -----END PGP PUBLIC KEY BLOCK-----

It is possible that I missed other require statements that need to be hacked, but you will discover that through testing. Finally, if you want your new openpgp.js file to work in regular (non-LiquidCore) node, you will have to add some logic to detect the presence of global.LiquidCore before using it. But I leave that up to you.

Hope this helps.

useful!

Related questions

No questions were found.
Github User Rank List