Amplify-js: Error: Native crypto module could not be used to get secure random number.

Created on 1 Nov 2020  路  62Comments  路  Source: aws-amplify/amplify-js

Describe the bug
I'm using the serverless.com framework together with: "amazon-cognito-identity-js": "^4.5.2" and I still get the error: Error: Native crypto module could not be used to get secure random number. even though it was supposed to be fixed in version 3.2.0.

It happens when I use the CognitoUser.authenticateUser method. Any updates on this issue?

amazon-cognito-identity-js

Most helpful comment

I am still experiencing this error with Angular 11 when running ng-serve, and @aws-amplify/auth.

Warning: ./node_modules/amazon-cognito-identity-js/es/utils/cryptoSecureRandomInt.js
Module not found: Error: Can't resolve 'crypto' in '/Users/mattijs/www/earnr/earnr-dashboard/node_modules/amazon-cognito-identity-js/es/utils'

I have tried installing "amazon-cognito-identity-js": "^4.5.4-unstable.6",

"compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "crypto": [
        "../../node_modules/crypto-js"
      ]
    },

and installing latest ampliy/core, auth and pubsub. Nothing works.

I can't use require, TS compiler is freaking out.

All 62 comments

@Benzer1406 Are you still experiencing this issue after using the unstable tag and setting global.crypto = require('crypto'), as we discussed in the other issue?
https://github.com/aws-amplify/amplify-js/issues/4886#issuecomment-720102849

@amhinson No, that solved it for me. If you want to you can close the issue when you released the fix on the stable version, leaving a comment here to let everybody know.

Ok will do. Thanks for the follow up! I will update the issue once it is released to latest.

For anyone seeing the same issue using Node, you can get around it by using amazon-cognito-identity-js@unstable and/or aws-amplify@unstable and setting global.crypto = require('crypto') at the top of the file before any imports.

@amhinson I used unstable tag for amazon-cognito-identity-js and crypto on top of all the imports as mentioned in earlier comments, Still issue remains same.

Error: Native crypto module could not be used to get secure random number.

@manojkumarg16 Could you provide some more details so I can try to reproduce the issue you're seeing? A code snippet of the file you're working with would help.

@amhinson Here is the code, a simple function
const globalAny:any = global;
globalAny.fetch = require('node-fetch');
globalAny.crypto = require('crypto');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');

const login = (email_id, pass) => {
/* Login */
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username : ,
Password : ,
});
return new Promise((resolve,reject) => {
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
resolve(result);
},
onFailure: (err) => {
reject(err);
}
});
})
}

}

Can you try assigning require('crypto') directly to global.crypto instead of globalAny.crypto? Here's where we're using it in the amazon-cognito-identity-js code:
https://github.com/aws-amplify/amplify-js/blob/main/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js#L15

Also, what version of Node are you using?

@amhinson I'm using typescript , so type need to be denoted, that's the reason I used it as globalAny:any = global.
as mentioned here : https://github.com/aws-amplify/amplify-js/issues/4886#issuecomment-720101857

I'm using node v12.18.3

Could you try doing that anyway, perhaps just with a // @ts-ignore for now just to validate if it changes anything?

Also, can you also delete your node_modules and yarn.lock/package-lock.json and install the dependencies again?

@amhinson tried as you said, but nothing turned up. Still issue remains

Can you share your package.json?

{
"name": "serverless",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "env-cmd -f .env.dev nodemon --exec serverless offline start --httpPort 4000 --websocketPort 4001 --lambdaPort 4002",
"package": "SLS_DEBUG=* sls package",
"deploy-function": "SLS_DEBUG=* sls deploy function --function graphql",
"deploy-stack": "SLS_DEBUG=* sls deploy",
"prisma:generate": "prisma generate",
"prisma:introspect": "prisma introspect",
"lint": "eslint ."
},
"dependencies": {
"@prisma/client": "^2.6.2",
"@types/graphql-fields": "^1.3.3",
"amazon-cognito-identity-js": "^4.5.3-unstable.1",
"apollo-errors": "^1.9.0",
"apollo-server": "^2.19.0",
"apollo-server-express": "2.17.0",
"aws-sdk": "^2.4.8",
"class-validator": "^0.12.2",
"crypto-js": "^3.3.0",
"eslint-import-resolver-webpack": "^0.12.2",
"express": "^4.17.1",
"graphql": "^15.3.0",
"graphql-fields": "^2.0.3",
"graphql-middleware-sentry": "^3.2.1",
"graphql-playground-middleware-express": "1.7.20",
"graphql-tag": "2.11.0",
"graphql-tools": "6.2.1",
"graphql-type-json": "^0.3.2",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.4",
"nexmo": "^2.9.1",
"node-fetch": "^2.6.1",
"nodemailer": "^6.4.13",
"otp-generator": "^2.0.0",
"password-generator": "^2.3.2",
"path": "^0.12.7",
"pg": "^8.3.3",
"reflect-metadata": "^0.1.13",
"request": "^2.88.2",
"serverless-http": "^2.5.0",
"source-map-support": "^0.5.19",
"telesignsdk": "^2.2.1",
"type-graphql": "^1.0.0"
},
"devDependencies": {
"@prisma/cli": "^2.6.2",
"@types/express": "^4.17.8",
"@types/jest": "26.0.13",
"@types/node": "14.6.4",
"@types/nodemailer": "^6.4.0",
"@typescript-eslint/eslint-plugin": "2.24.0",
"@typescript-eslint/parser": "2.30.0",
"copy-webpack-plugin": "^6.1.0",
"cors": "2.8.4",
"env-cmd": "10.1.0",
"eslint": "6.8.0",
"eslint-config-airbnb": "18.1.0",
"eslint-config-airbnb-typescript": "7.2.1",
"eslint-config-prettier": "6.10.0",
"eslint-plugin-import": "2.20.1",
"eslint-plugin-jest": "23.8.2",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-prettier": "3.1.2",
"husky": "4.2.5",
"jest": "25.2.2",
"lint-staged": "10.0.8",
"nodemon": "^2.0.4",
"prettier": "1.19.1",
"serverless": "1.78.0",
"serverless-dotenv-plugin": "^3.0.0",
"serverless-offline": "6.5.0",
"serverless-webpack": "5.3.3",
"ts-loader": "^8.0.3",
"typegraphql-prisma": "^0.6.0",
"typescript": "3.8.3",
"webpack": "4.42.0",
"webpack-node-externals": "2.5.2"
}
}

I'm having some trouble trying to replicate the issue you're seeing unfortunately 馃槙 . I just created a new Serverless framework Express app using some of the same code snippets you provided and I am able to successfully authenticate a user. Would you be able to look into creating a basic Express app that you could share with me to show the behavior you're seeing, and then provide some reproduction steps?

Week back I wrote a rough code snippet of same which was working fine. Now I just reused the snippet which is throwing error, quite strange :(

@Benzer1406 This fix is now available with latest 馃憤

@manojkumarg16 Can you try with the latest version to see if any behavior changes?

@amhinson tried with latest version of crypto , still issue persists
"amazon-cognito-identity-js": "^4.5.3-unstable.1",
"crypto-js": "^4.0.0",

@amhinson It started working after downgrading amazon-cognito-identity-js from ^4.5.3-unstable.1--> 4.5.0 and removing crypto-js .
Thanks for your support @amhinson

@manojkumarg16 can you try with "amazon-cognito-identity-js": "4.5.3"? You also shouldn't need to install crypto-js unless you're using it explicitly in your project.

@amhinson I tried with "amazon-cognito-identity-js": "4.5.3" I am still getting the same issue .

@pathiyilnaveen Could you share your code or a small reproducible example so we can try to replicate the issue you are seeing?

I am using amplify on my unit tests
@amhinson

const chai = require('chai');
const chaiHttp = require('chai-http');
const mocha = require('mocha');
const Amplify = require('aws-amplify');
const { Auth } = require('aws-amplify');

const { describe, before } = mocha;
const { it } = mocha;
const { expect } = require('chai');

chai.use(chaiHttp);
chai.should();

Amplify.default.configure({
  Auth: {
    // REQUIRED - Amazon Cognito Identity Pool ID
    identityPoolId: 'ID_POOL_ID',
    // REQUIRED - Amazon Cognito Region
    region: 'us-east-1',
    // OPTIONAL - Amazon Cognito User Pool ID
    userPoolId: 'USR_POOL_ID',
    // OPTIONAL - Amazon Cognito Web Client ID
    userPoolWebClientId: 'WEB_CLIENT
  },
});

async function onUserSignIn(email, password) {
  const username = email;
  await Auth.signIn(username, password).then((user) => {
    global.cognito_id = user.username;
  });
}

before(async function () {
  this.timeout(10000);
  const mailId = '[email protected]';
  const password = 'test@123';
  await onUserSignIn(mailId, password);
});

Below is my dependencies in package.json

"dependencies": {
"@babel/cli": "^7.10.1",
"@babel/preset-env": "^7.10.2",
"amazon-cognito-identity-js": "4.5.3",
"aws-amplify": "^3.0.23",
"aws-sdk": "^2.756.0",
"axios": "^0.20.0",
"body-parser": "^1.19.0",
"bull": "^3.14.0",
"bull-board": "^0.9.0",
"casbin": "^5.0.4",
"casbin-sequelize-adapter": "^2.1.0",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"cpx": "^1.5.0",
"cross-fetch": "^3.0.5",
"debug": "~2.6.9",
"elasticsearch": "^16.7.1",
"express": "~4.16.1",
"express-validator": "^6.6.0",
"geoip-lite": "^1.4.2",
"http-aws-es": "^6.0.0",
"ioredis": "^4.17.3",
"json-rules-engine": "^5.0.3",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.3",
"lodash": "^4.17.19",
"logform": "^2.2.0",
"mocha": "^7.2.0",
"moment": "^2.29.1",
"morgan": "~1.9.1",
"multer": "^1.4.2",
"nodemailer": "^6.4.8",
"nodemon": "^2.0.4",
"npm-run-all": "^4.1.5",
"pg": "^8.2.1",
"pg-hstore": "^2.3.3",
"read-excel-file": "^4.0.6",
"redis": "^3.0.2",
"redis-clustr": "^1.7.0",
"rimraf": "^3.0.2",
"save": "^2.4.0",
"save-dev": "0.0.1-security",
"sequelize": "^5.21.12",
"swagger-jsdoc": "^4.2.0",
"swagger-stats": "^0.95.18",
"swagger-ui-express": "^4.1.4",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0",
"xlsx": "^0.16.7"
},

here is the error i get
1) "before all" hook in "{root}"

0 passing (13ms)
1 failing

1) "before all" hook in "{root}":
Error: Native crypto module could not be used to get secure random number.
at cryptoSecureRandomInt (node_modules/amazon-cognito-identity-js/lib/utils/cryptoSecureRandomInt.js:43:9)
at WordArray.random (node_modules/amazon-cognito-identity-js/lib/utils/WordArray.js:50:56)
at randomBytes (node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:40:58)
at AuthenticationHelper.generateRandomSmallA (node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:101:21)
at new AuthenticationHelper (node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:56:29)
at CognitoUser.authenticateUserDefaultAuth (node_modules/amazon-cognito-identity-js/lib/CognitoUser.js:264:32)
at CognitoUser.authenticateUser (node_modules/amazon-cognito-identity-js/lib/CognitoUser.js:237:19)
at /smart-property/service-api/service-api/service-api/node_modules/@aws-amplify/auth/lib/Auth.js:515:18
at new Promise ()
at AuthClass.signInWithPassword (node_modules/@aws-amplify/auth/lib/Auth.js:514:16)
at AuthClass.signIn (node_modules/@aws-amplify/auth/lib/Auth.js:400:25)
at onUserSignIn (test/07UserCreation.js:31:14)
at Context. (test/07UserCreation.js:40:9)
at process.topLevelDomainCallback (domain.js:126:23)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test-coverage-html: nyc --reporter=html mocha -timeout 10000 --exit
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test-coverage-html script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

@pathiyilnaveen Can you add global.crypto = require('crypto') at the top of the file?

@amhinson Thanks , I added it but still issue is seen . Should I add any specific version of crypto in my package.json ?

No, you shouldn't have to add crypto, as it is included with Node by default now.

  • What version of Node are you using?
  • Just to verify, did you add global.crypto = require('crypto') above all of the require on line 1?
  • Could you try updating to the latest version (3.3.7) of Amplify?

node -v : v10.19.0
I have added crypto like you suggested as well as amplify version but the same resut .

Is it working for you ? If so could you please let me know your node version and share package.json dependencies

If you could provide a sample repo that shows the behavior you're seeing, that would be the quickest way for us to solve the issue you're seeing.

@amhinson Thanks so much Great Help !! I figured out where to add global.crypto = require('crypto') . We have to added this to top of the very first test file in the test folder .

Ah ok great! Glad you were able to figure it out 馃檪

Same issue was coming to me, it was not getting reproduced on my local dev machine, was coming only on my deployed containers. I also upgraded my amazon-cognito-identity-js to 4.5.3. but no luck but finally added global.crypto = require('crypto') in my code resolved the issue. Thanks.

@amhinson Sorry for the late reply. I tried with the latest tag and it works without issue. I can even delete the global.crypto = require('crypto');from my files. Thanks for the support!

I have the same error here but can't fix it. Any updates?

@renanwilliam could you provide what you've tried from this issue?

Just to correct one thing, I actually had to leave the 'global.crypto = requiere('crypto-JS'); on top for it to work.

I've tried install latest tag and insert global.crypto = require('crypto') at the top.
I'm using typescript with the code bellow:

const globalAny:any = global;
globalAny.crypto = require('crypto');

It was working before, stopped after update from 4.4.0 to 4.5.3. After rolling back to 4.4.0 come back to works.

@renanwilliam can you share more about your app and some reproduction steps? If possible, a small sample repo that we could run to replicate the issue you're seeing would be ideal.

Unfortunally I'm experiencing the same error, I tried setting crypto to the top, I tried settings
"resolutions": { "crypto-js": "3.1.9-1" } in the package.json but all these solutions didn't work for me

these are my depencies in the package.json if it could be usefull :
"dependencies": { "aws-amplify": "^3.3.7", "aws-sdk": "^2.786.0", "body-parser": "^1.19.0", "compression": "^1.7.4", "cors": "^2.8.5", "express": "^4.17.1", "express-fileupload": "^1.2.0", "morgan": "^1.10.0", "node-fetch": "^2.6.1", "resource-router-middleware": "^0.7.0", "ulid": "^2.3.0", "uuid": "^8.3.1" } ,

@Ladvace Could you share more about your app and reproduction steps? Also, you shouldn't need to add any resolutions anymore.

Can you make sure you have global.crypto = require('crypto') at the very top of your file before any imports?

I already have global.crypto = require('crypto').
I do nothing more than this:
const signInRes = await signIn(username, password); return res.send(signInRes);

@Ladvace Would you be able to share a small example repo that shows the behavior you're seeing? I've really been trying hard to replicate the issues you are seeing, but there are just just many different factors that might be contributing to the problem.

I hope this will be fine: https://pastebin.com/MYxyuMHk

@Ladvace Thank you, that will help a lot! Is this just a standard Express app?

yes. the api.get you see in the pastebin it's just an express router.

let api = Router();

Thanks again for the reproduction sample @Ladvace! I have made a small adjustment in this PR that should fix the behavior you're seeing. It is available to use now with the unstable tag, and we will likely have a release to latest next week.

Can you verify that unstable works for you?

Also, with that fix, it is no longer required to add global.crypto = require('crypto') in your code, as this will handle that automatically.

ok, fixed!, thanks so much

@amhinson - I too can confirm "unstable" with no additional require works. Thanks for the fix & the unstable push.

Here works too.

How to add global.crypto = require('crypto') in build file? i mean after bundling we can do it manually, how to do before bundle starts ?

Please use the package
"amazon-cognito-identity-js": "4.3.3" instead of "amazon-cognito-identity-js": "^4.3.3"

This ^ sysmbol will always find latest version of the package and it will break if any unstable version released or any errors.

I was facing this issue when I was working with amazon cognito in nodejs. After so many hit and trial i found the solution, just change the amazon-cognito-identity-js version to :

"amazon-cognito-identity-js": "^4.5.4-unstable.6"

and now it is working for me, hope it will save your time and will work for you all who is facing this issue.

Update: latest is now up to date with the fix so global.crypto = require('crypto') is not required anymore 馃憤

I am still experiencing this error with Angular 11 when running ng-serve, and @aws-amplify/auth.

Warning: ./node_modules/amazon-cognito-identity-js/es/utils/cryptoSecureRandomInt.js
Module not found: Error: Can't resolve 'crypto' in '/Users/mattijs/www/earnr/earnr-dashboard/node_modules/amazon-cognito-identity-js/es/utils'

I have tried installing "amazon-cognito-identity-js": "^4.5.4-unstable.6",

"compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "crypto": [
        "../../node_modules/crypto-js"
      ]
    },

and installing latest ampliy/core, auth and pubsub. Nothing works.

I can't use require, TS compiler is freaking out.

+1 for mattiLeBlanc - starting a new vanilla Angular 11 project, installing Amplify and Auth

@mjpaton I fixed/hacked it by doing the following:
Adding to polyfill.ts

// Amplify polyfill
(window as any).global = window;
(window as any).process = {};

Adding the following packages to my package.json:

    "@aws-amplify/auth": "^3.4.13",
    "@aws-amplify/core": "^3.8.5",
    "@aws-amplify/pubsub": "^3.2.11",
    "amazon-cognito-identity-js": "^4.5.4-unstable.6",

and added to tsconfig:

"compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "crypto": [
        "../../node_modules/crypto-js"
      ]
    },

I am still getting warnings:

image

but Auth seems to be working.
What is the proper solution for Angular 11?

@mattiLeBlanc do you mind posting your full tsconfig.

I'm hoping something within that is a clue to get this working.

Also using Angular 11,
I've tried every permutation between adding global.crypto = require('crypto') to the top of main.ts or not, using "amazon-cognito-identity-js": "^4.5.4-unstable.6" or latest,
I've tried with and without the polyfills, and the compiler paths you listed, and I just can't seem to get past this issue.

@theninadoge

Pretty much standard generated by angular, except for the paths.

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "crypto": [
        "../../node_modules/crypto-js"
      ]
    },
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  },
  "exclude": [ "lib", "bin", "scripts"]
}

@mattiLeBlanc Are you seeing an Error that crashes your app, or are you just seeing the warning in the console? I think that the warning might just be coming from this require, which isn't relevant for web:
https://github.com/aws-amplify/amplify-js/blob/e98217cf13f2ab82730861fe91f9690d7ed2fa38/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js#L18-L23

With that said, I don't think it should impact your app in any way besides the warning showing. I am going to look into what it would take to suppress that warning.

@amhinson I am currently seeing errors during build and ng serve, because I added this to my polyfill:

(window as any).global = window;
(window as any).process = {};

If I leave that out the app crashes.

Yep confirmed I'm still getting about a dozen warnings in the console - @amhinson any update on how they can be suppressed if they truly are spurious for web?

I've not noticed an impact aside from them blowing up the console - auth works, refreshing tokens work, API calls work to cognito secured endpoints.

@mjpaton This appears to just be limited to Angular apps from my testing. As you mentioned, there should be no effect on the functionality here. I'll look into what we can do on our side to suppress and superficial warnings.

It appears that there may not be much we can do on our side with this. The implementation we have is similar to crypto-js, and it looks like they have the same issues:
https://github.com/brix/crypto-js/issues/262
https://github.com/brix/crypto-js/issues/290
https://github.com/brix/crypto-js/issues/291
https://github.com/brix/crypto-js/issues/295

Here is one potential solution you can add in your app to suppress the warning: https://stackoverflow.com/a/54162447

Was this page helpful?
0 / 5 - 0 ratings