简体   繁体   中英

nodejs pbkdf2sync Not a buffer error

Suddenly in my console it's start giving errors, and it has been running fine for days without any change. Please advise.

/node_modules/mysql/lib/protocol/Parser.js:82
        throw err;
              ^
TypeError: Not a buffer
    at TypeError (native)
    at pbkdf2 (crypto.js:607:20)
    at Object.exports.pbkdf2Sync (crypto.js:590:10)


    crypto: require("crypto"),

    encrypt: function(password) {
        var salt = this.getSalt(password, this.constructor.GUID);
        return {salt: salt, password: this.getEncrypted(password, salt)};
    },

    getSalt: function(password, GUID) {
        return this.crypto.createHash("sha256").update(password + "|" + GUID).digest("hex")
    },

    getEncrypted: function(password, salt) {
        return this.crypto.pbkdf2Sync(password, salt, 4096, 512, "sha256").toString("hex");
    },

    verifyPassword: function(user, password) { //var salt = this.getSalt("test@test.com|" + this.constructor.GUID); console.log("salt: " + salt); console.log("password: " + this.getPassword("HUG2015", salt));
        return this.crypto.pbkdf2Sync(password, user.salt, 4096, 512, "sha256").toString("hex")  == user.password; //test
    },

    generateAuthToken: function() {
        return this.crypto.randomBytes(64).toString("hex");
    }

Edit: Usage

        getUser: function(emailAddress, password) {
            var self = this;
            this.connection.query("SELECT * from admin WHERE emailAddress = ?", [emailAddress], function(error, rows, fields){
                if(error) {
                    self.onFault({status: 500, body: error});
                } else {
                    if(rows.length == 1) {
                        self.verifyPassword(rows[0], password)
                    } else {
                        self.onFault({status: 401, body: {}});
                    }
                }
            });
        },

        verifyPassword: function(user, password) {
            var self = this;
            try {
                if(this.authenticationProxy.verifyPassword(user, password)) {
                    this.setAuthToken(user, this.authenticationProxy.generateAuthToken());
                } else {
                    this.onFault({status: 401, body: {}});
                }
            } catch(exception) {
                this.onFault({status:500, body: exception});
            }
        },

My guess is, that 'not a buffer' is thrown if password is a number. Inside crypto.js there is a toBuf call which tries to change password into a buffer (unless it is already a buffer) but converts Strings only.

You can try two things:

1) ensure that password (passed to crypto.pbkdf2Sync ) is a String

2) or convert it to buffer yourself -> pass new Buffer(password, 'binary')

If this code hasn't changed at all and suddenly it's not working, it's because one of the calling libraries or other changes you have made are interfering.

(Or a new node version is being used, but I doubt that's your problem).

The pattern you are using is not recommended:

mysingleton = {

crypto: require('crypto'),
...

}

This is because any callback through an anonymous function will lose your 'this' Object.

Also in node.js, you do not need this pattern, because each file in mode.js is kept in a separate namespace and protected by the module.exports.

You can get rid of the references to 'this' in the following way, as a quick check to see if 'this' is the culprit:

var
   c = require('crypto');

mysingleton = {

// delete the crypto definition here
// crypto: ...,
...
encrypt: function(password) {
    // note elimination of this below
    var salt = mysingleton.getSalt(password, this.constructor.GUID);
    return {salt: salt, password: this.getEncrypted(password, salt)};
},
...
getSalt: function(password, GUID) {
    return c.createHash("sha256").update(password + "|" + GUID).digest("hex")
},
...
}

If that fixes things, I would suggest you get some more background on what the best recommended pattern is for your framework / system.

In my case, I was trying to send the JSON object directly to the function.

{ token: "abc" }

I stringify the input to the function and everything worked properly.

JSON.stringify({ token: "abc" })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM