tradle / rn-nodeify

hack to allow react-native projects to use node core modules, and npm modules that use them
MIT License
619 stars 112 forks source link

iOS, ANDROID - RELEASE - Error: Secure random number generation is not supported by this browser. #70

Closed Lukkub closed 5 years ago

Lukkub commented 6 years ago

For iOS release scheme, problem with bip39.generateMnemonic from bip39 package after nodeify:

Secure random number generation is not supported by this browser.
Use Chrome, Firefox or Internet Explorer 11

Works fine for iOS debug. Works fine for Android debug and release.

React-Native version: "0.56.0-rc"

I am up-to-date with all packages and installation flow:

"rn-nodeify": "10.0.0"
"react-native-crypto": "2.1.2"
"react-native-randombytes": "3.4.0"

My shim.js:

if (typeof __dirname === 'undefined') global.__dirname = '/'
if (typeof __filename === 'undefined') global.__filename = ''
if (typeof process === 'undefined') {
  global.process = require('process')
} else {
  const bProcess = require('process')
  for (const p in bProcess) {
    if (!(p in process)) {
      process[p] = bProcess[p]
    }
  }
}

process.browser = false
if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer

// global.location = global.location || { port: 80 }
const isDev = typeof __DEV__ === 'boolean' && __DEV__
process.env['NODE_ENV'] = isDev ? 'development' : 'production'
if (typeof localStorage !== 'undefined') {
  localStorage.debug = isDev ? '*' : ''
}

// If using the crypto shim, uncomment the following line to ensure
// crypto is loaded first, so it can populate global.crypto
require('crypto')

My index.js of the app start with import './shim.js'

I was also trying with below shim.js file but no success on iOS release:

if (typeof __dirname === 'undefined') global.__dirname = '/'
if (typeof __filename === 'undefined') global.__filename = ''
if (typeof process === 'undefined') {
  global.process = require('process')
} else {
  const bProcess = require('process')
  for (var p in bProcess) {
    if (!(p in process)) {
      process[p] = bProcess[p]
    }
  }
}

process.browser = false
if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer

// global.location = global.location || { port: 80 }
const isDev = typeof __DEV__ === 'boolean' && __DEV__
process.env['NODE_ENV'] = isDev ? 'development' : 'production'
if (typeof localStorage !== 'undefined') {
  localStorage.debug = isDev ? '*' : ''
}

if (require('./package.json').dependencies['react-native-crypto']) {
  // important that this comes before require('crypto')
  const algos = require('browserify-sign/algos')
  if (!algos.sha256) {
    algos.sha256 = {
      "sign": "ecdsa",
      "hash": "sha256",
      "id": new Buffer("")
    }
  }

  let crypto
  if (typeof window === 'object') {
    if (!window.crypto) window.crypto = {}
    crypto = window.crypto
  } else {
    crypto = require('crypto')
  }

  if (!crypto.getRandomValues) {
    crypto.getRandomValues = getRandomValues
  }

  let randomBytes

  function getRandomValues (arr) {
    if (!randomBytes) randomBytes = require('react-native-randombytes').randomBytes

    const bytes = randomBytes(arr.length)
    for (var i = 0; i < bytes.length; i++) {
      arr[i] = bytes[i]
    }
  }
}
mvayngrib commented 6 years ago

@Lukkub the first shim looks right. The error looks like a message from the randombytes package (randombytes/browser.js). crypto.getRandomValues isn't getting defined early enough. See if you can log the order the modules are getting required (and maybe also compare debug vs release). I get:

  1. REACT-NATIVE-RANDOMBYTES (react-native-randombytes/index.js)
  2. REACT-NATIVE-CRYPTO (react-native-crypto/index.js)
  3. RANDOMBYTES (randombytes/browser.js)
Lukkub commented 6 years ago

@mvayngrib So I finally was able to get rid of the problem.

What I did.

  1. Upgrade RN to version: 0.56.0

  2. Change shim.js to the default one generated by the package:

    
    if (typeof __dirname === 'undefined') global.__dirname = '/'
    if (typeof __filename === 'undefined') global.__filename = ''
    if (typeof process === 'undefined') {
    global.process = require('process')
    } else {
    const bProcess = require('process')
    for (var p in bProcess) {
    if (!(p in process)) {
      process[p] = bProcess[p]
    }
    }
    }

process.browser = false if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer

// global.location = global.location || { port: 80 } const isDev = typeof DEV === 'boolean' && DEV process.env['NODE_ENV'] = isDev ? 'development' : 'production' if (typeof localStorage !== 'undefined') { localStorage.debug = isDev ? '*' : '' }

// If using the crypto shim, uncomment the following line to ensure // crypto is loaded first, so it can populate global.crypto // require('crypto')



So I keep commented `require('crypto')` section.

And It finally works well for Android/ iOS debug/release.
mvayngrib commented 6 years ago

@Lukkub interesting, you mean the require('crypto') line breaks things?

Lukkub commented 6 years ago

@mvayngrib Exactly - at least in my case.

kimmimy commented 5 years ago

https://stackoverflow.com/questions/56723706/error-null-is-not-an-object-evaluating-rnrandombyte-seed-ios .

can you can help?

mvayngrib commented 5 years ago

@kimmimy see https://stackoverflow.com/a/56725441/1126660

hzz780 commented 4 years ago

how to find the reason: webstorm -> nodemodules -> Find in path: 'xxxxxx' why: https://github.com/crypto-browserify/randombytes/blob/master/browser.js how to solve: https://www.npmjs.com/package/react-native-get-random-values

// index.js
import {AppRegistry} from 'react-native';
// declare global.crypto.getRandomValues before use it.
import 'react-native-get-random-values';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);
kyawthura2018 commented 3 years ago

how to find the reason: webstorm -> nodemodules -> Find in path: 'xxxxxx' why: https://github.com/crypto-browserify/randombytes/blob/master/browser.js how to solve: https://www.npmjs.com/package/react-native-get-random-values

// index.js
import {AppRegistry} from 'react-native';
// declare global.crypto.getRandomValues before use it.
import 'react-native-get-random-values';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

This work for me. Thanks a lot.

alexreyes commented 2 years ago

how to find the reason: webstorm -> nodemodules -> Find in path: 'xxxxxx' why: https://github.com/crypto-browserify/randombytes/blob/master/browser.js how to solve: https://www.npmjs.com/package/react-native-get-random-values

// index.js
import {AppRegistry} from 'react-native';
// declare global.crypto.getRandomValues before use it.
import 'react-native-get-random-values';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

Just installing react-native-get-random-values and importing it in my index.js fixed it for me as well! Thank you