最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to calculate checksum in React Native and Node? - Stack Overflow

programmeradmin3浏览0评论

I'm uploading an image file from React Native to AWS Lambda (Node 10.x) and want to verify the hash of the file I've sent matches the file received. To do this I'm using hashing in React Native and again in Lambda, but the hashes never match. Here are the relevant bits of code I've tried.

React Native

import RNFS from "react-native-fs";
const contentChecksum = await RNFS.hash(post.contentUrl, "md5");

Lambda (Node)

import AWS from "aws-sdk";
const crypto = require("crypto");
const s3 = new AWS.S3();

const data = await s3
    .getObject({
      Bucket: file.bucket,
      Key: file.key
    })
    .promise();
const contentChecksum = crypto
    .createHash("md5")
    .update(data.Body)
    .digest("hex");

These checksums never match. I've tried using base64 encoding in Node (data.Body.toString("base64")) and also sha256. What is the trick to calculating the checksum so they match in React Native and Node?

Edit: Here are the results from a recent test.

post.contentUrl: file:///Users/xxxxxxx/Library/Developer/CoreSimulator/Devices/2F2F4FD3-574E-40D7-BE6B-7080E926E70A/data/Containers/Data/Application/65A3FF67-98B2-444D-B75D-3717C1274FBC/Library/Caches/Camera/FDCD8F90-D24F-4E64-851A-96AB388C4B59.jpg

(the file is local on an iPhone)

contentChecksum from React Native: 48aa5cdb30f01719a2b12d481dc22f04

contentChecksum from Node (Lambda): 7b30b61a55d2c39707082293c625fc10

data.Body is a Buffer.

I also note that the eTag attribute on the S3 object matches the md5 checksum I'm calculating in Node. Since eTag is usually the md5 hash of the file, this tells me that I'm likely calculating the hash incorrectly in React Native, but I'm not sure how. I'm using the hash function from the react-native-fs package.

I'm uploading an image file from React Native to AWS Lambda (Node 10.x) and want to verify the hash of the file I've sent matches the file received. To do this I'm using hashing in React Native and again in Lambda, but the hashes never match. Here are the relevant bits of code I've tried.

React Native

import RNFS from "react-native-fs";
const contentChecksum = await RNFS.hash(post.contentUrl, "md5");

Lambda (Node)

import AWS from "aws-sdk";
const crypto = require("crypto");
const s3 = new AWS.S3();

const data = await s3
    .getObject({
      Bucket: file.bucket,
      Key: file.key
    })
    .promise();
const contentChecksum = crypto
    .createHash("md5")
    .update(data.Body)
    .digest("hex");

These checksums never match. I've tried using base64 encoding in Node (data.Body.toString("base64")) and also sha256. What is the trick to calculating the checksum so they match in React Native and Node?

Edit: Here are the results from a recent test.

post.contentUrl: file:///Users/xxxxxxx/Library/Developer/CoreSimulator/Devices/2F2F4FD3-574E-40D7-BE6B-7080E926E70A/data/Containers/Data/Application/65A3FF67-98B2-444D-B75D-3717C1274FBC/Library/Caches/Camera/FDCD8F90-D24F-4E64-851A-96AB388C4B59.jpg

(the file is local on an iPhone)

contentChecksum from React Native: 48aa5cdb30f01719a2b12d481dc22f04

contentChecksum from Node (Lambda): 7b30b61a55d2c39707082293c625fc10

data.Body is a Buffer.

I also note that the eTag attribute on the S3 object matches the md5 checksum I'm calculating in Node. Since eTag is usually the md5 hash of the file, this tells me that I'm likely calculating the hash incorrectly in React Native, but I'm not sure how. I'm using the hash function from the react-native-fs package.

Share Improve this question edited Sep 10, 2019 at 17:32 Fook asked Aug 27, 2019 at 18:17 FookFook 5,5607 gold badges37 silver badges59 bronze badges 7
  • What do the outputs look like and what is the value of post.contentUrl and data.Body? – tbking Commented Aug 27, 2019 at 18:56
  • @tbking I've added more info in the question. – Fook Commented Aug 27, 2019 at 19:36
  • Looks like an encoding issue. Try data.Body.toString() in node. – tbking Commented Aug 27, 2019 at 19:44
  • That didn't seem to help. – Fook Commented Aug 28, 2019 at 19:29
  • access the file object in react-native and take the hash of it, and similar on lambda, use the file content and take hash of the content again, that should be the logic. – Mohit Yadav Commented Sep 10, 2019 at 18:37
 |  Show 2 more ments

2 Answers 2

Reset to default 2 +50

You can use the same code on React and AWS Lambda, that is Node.js.

So in your React.js application you could use the following code:

import * as React from 'react';
import crypto from 'crypto';

var key = 'YOUR_KEY';

export default class Test extends React.Component {

    render() {
        var hash = crypto.createHash('md5').update(key).digest('hex');
        return (
            <div>
                {hash}
            </div>
        )
    }

}

And the variable hash have to contains the same value you get on AWS.

In order to run you have to install the crypto library:

npm i --save react-native-crypto

Change the variable YOUR_KEY, then run the application:

npm start

And in the browser you should get:

4b751fef5e9660e3943173fd3e6c4224

You can use the crypto module.

To get a list of all available hash algorithms, you can use crypto.getHashes().

Here is a Nodejs example:

var crypto = require('crypto')

crypto.getHashes() // [ 'dsa', 'dsa-sha', ..., 'md5', ... ]

Here is a helper method for generating checksum value from string input:

var crypto = require('crypto')

function checksum(str, algorithm, encoding) {
  return crypto
    .createHash(algorithm || 'md5')
    .update(str, 'utf8')
    .digest(encoding || 'hex')
}

checksum('This is my test text'); 
checksum('This is my test text', 'sha1');
发布评论

评论列表(0)

  1. 暂无评论