Search code examples
javascriptangularjsnode.jsrsacryptojs

Node CryptoJS vs Jsrsasign SHA256withRSA with encrypted pem


So I am running into an issue using jsrsasign. I am not quite what I am doing wrong. I am attempting to emulate a hash process we are uinsg in NodeJS using angular and it is not clear what the issue is. Here is the process in we have in NodeJS that works perfect

var restler = require('restler');
var path = require('path');
var fs = require('fs');
var crypto = require('crypto');
var dateFormat = require('dateformat');

var sha_hash = crypto.createHash('SHA1');
var pem = fs.readFileSync('private-key.pem');
var pkey = pem.toString('ascii');

var private_key = {
    key: pkey,
    passphrase:'password'
}

//var current_date = new Date();
//console.log(dateFormat(current_date, "yyyy/mm/dd HH:MM:ss l"));
var current_date = '2015/05/06 20:07:12 926';

//SToken
sha_hash.update(current_date);
var stoken = sha_hash.digest('hex');
console.log(stoken);

//Signature
var signature = crypto.createSign('RSA-SHA256')
signature.update(stoken);
var sig = signature.sign(private_key, 'base64');
console.log(sig);

Both the SToken Values and the Signature Values produce the expected results if we try something similar using angularjs, the Signature value is incorrect.

Here is the index.html:

<!DOCTYPE html>
<html>
<body ng-app="main">
<div ng-view>
</div>
</body>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/dateformat/dist/dateformat.min.js"></script>

<script src="http://yui.yahooapis.com/2.9.0/build/yahoo/yahoo-min.js">    </script>

<script src="bower_components/crypto-js/core.js"></script>
<script src="bower_components/crypto-js/x64-core.js"></script>
<script src="bower_components/crypto-js/pbkdf2.js"></script>
<script src="bower_components/crypto-js/crypto-js.js"></script>
<script src="bower_components/crypto-js/hmac.js"></script>
<script src="bower_components/crypto-js/hmac-sha256.js"></script>
<script src="bower_components/crypto-js/sha1.js"></script>
<script src="bower_components/crypto-js/sha256.js"></script>

<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/ext/base64.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/ext/jsbn.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/ext/jsbn2.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/ext/rsa.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/ext/rsa2.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/crypto-1.1.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/rsasign-1.2.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/rsapem-1.1.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/asn1-1.0.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/asn1hex-1.1.js"></script>
<script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/keyutil-1.0.js"></script>

<script src="modules/authentication/authentication.module.js"></script>
<script src="modules/authentication/authentication.controller.js"></script>
<script src="app.js" ></script>
</html>

And here is the authentication.controller.js file:

(function (authenticationModule) {

    var authenticationController = function($scope, $http, $q, $filter) {

        var deferred = $q.defer()
        var private_key = $http({
            method: 'GET',
            url: 'private-key.pem'
        }).success(function(privateKey) {
            deferred.resolve();

            //var current_date = new Date();
            //var date_string = $filter('date')(current_date, "yyyy/mm/dd HH:MM:ss SSS");
            var date_string = '2015/05/06 20:07:12 926';

            //SToken
            var stoken = CryptoJS.SHA1(date_string).toString();
            console.log(stoken);
            $scope.stoken = stoken;

            //Signature
            var sig = new KJUR.crypto.Signature({"alg": "SHA256withRSA", "prov": "cryptojs/jsrsa"});

            sig.init(privateKey, 'password');
            sig.updateString(stoken);
            var signature = sig.sign();
            console.log(signature);
            $scope.signature = signature;
        }).error(function(error) {
            console.error("there was an error reading file");
            deferred.reject(error);
        });

    };

    authenticationModule.controller('authenticationController', ['$scope', '$http', '$q', '$filter', authenticationController]);


}(angular.module('authentication')));

And here is the authentication.module.js file

(function (angular) {

    'use strict';
    //Initialize the Module
    angular.module('authentication',[]);

}(window.angular));

Here is the app.js file:

(function(angular){

    //Defines my angular main portion of the application
    var module = angular.module('main',['ngRoute', 'authentication']);


    //Defines the routes
    module
        .config(function($routeProvider){
            $routeProvider
                .when('/auth',{     templateUrl:'modules/authentication/authentication.view.html',  controller:'authenticationController'})
                .otherwise({redirectTo:'/auth'});
        });

})(window.angular);

And finally here is the view:

<div>
    SToken: {{stoken}}
</div>
<div>
    Signature: {{signature}}
</div>

Again, just to repeat, the SToken value appears correct but when I show the signature, it is incorrect. I am not quite sure how to deal with this but any assistance would be appreciated.


Solution

  • After some research, I realize that I forgot to base64 encode the answer from angularjs

    So I changed the controller.js code from this

    var signature = sig.sign();
    

    To this:

    var signature = hextob64(sig.sign());
    

    I also has to update the index.html file to include this library

    <script language="JavaScript" type="text/javascript" src="bower_components/jsrsasign/base64x-1.1.js"></script>
    

    Everything matched once I added these changes.