user2727195
user2727195

Reputation: 7340

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("[email protected]|" + 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});
            }
        },

Upvotes: 0

Views: 8266

Answers (3)

Kedar9444
Kedar9444

Reputation: 1853

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" })

Upvotes: 0

jmuet
jmuet

Reputation: 396

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')

Upvotes: 9

Ron Wertlen
Ron Wertlen

Reputation: 832

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.

Upvotes: 1

Related Questions