Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
767 views
in Technique[技术] by (71.8m points)

node.js - Howto patch/shim crypto.getRandomValues for React Native

I am porting some packages created for NodeJS to React Native using ReactNativify to rewrite Node API object dependencies to their browserify equivalents.

One of them is crypto. In transformer.js (or .babelrc) I have:

// The following plugin will rewrite imports. Reimplementations of node
// libraries such as `assert`, `buffer`, etc. will be picked up
// automatically by the React Native packager.  All other built-in node
// libraries get rewritten to their browserify counterpart.

[require('babel-plugin-rewrite-require'), {
  aliases: {
    crypto: 'crypto-browserify',
    // ...
  },
  throwForNonStringLiteral: true,
}],

In ReactNativify global.js there is this code (which I excluded, because it is not meant for production):

// Don't do this in production. You're going to want to patch in
// https://github.com/mvayngrib/react-native-randombytes or similar.
global.crypto = {
  getRandomValues(byteArray) {
    for (let i = 0; i < byteArray.length; i++) {
      byteArray[i] = Math.floor(256 * Math.random());
    }
  },
};

.

My first question: How is getRandomValues correctly patched for production?


There is a second option, and that is using react-native-crypto (a clone of crypto-browserify)

Ideally I should just be able to do this in transformer.js:

  aliases: {
    crypto: 'react-native-crypto', // instead of 'crypto-browserify'
    // ...
  },

But react-native-crypto uses rn-nodeify instead of ReactNativify, which generates a shim.js to be imported in index.android.js / index.ios.js with code similar to this:

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

    if (typeof window === 'object') {
        const wCrypto = window.crypto = window.crypto || {}
        wCrypto.getRandomValues = wCrypto.getRandomValues || getRandomValues
    }

    const crypto = require('crypto')
    const randomBytes = crypto.randomBytes
    crypto.randomBytes = function (size, cb) {
        if (cb) return randomBytes.apply(crypto, arguments)

        const arr = new Buffer(size)
        getRandomValues(arr)
        return arr
    }

    crypto.getRandomValues = crypto.getRandomValues || getRandomValues

    function getRandomValues (arr) {
        // console.warn('WARNING: generating insecure psuedorandom number')
        for (var i = 0; i < arr.length; i++) {
        arr[i] = Math.random() * 256 | 0
        }

        return arr
    }
}

I don't know if all this shim code is needed when using ReactNativify, and couldn't find good sources, so ...

My second question: How to use react-native-crypto in 'the proper ReactNativify way'?


I've created github issues in ReactNativify and react-native-crypto repo's:

Versions:

node               7.10.1       /usr/local/bin/node  
npm                4.2.0        /usr/local/bin/npm   
yarn               0.24.6       /usr/bin/yarn        
react-native-cli   2.0.1       
app rn version     0.45.1      
ignite             2.0.0        /usr/local/bin/ignite
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...