4

I have a working Java code for encryption of string in AES encryption using the key , and i have been trying the replicate the code in Nodejs for quite long but unable to get the exact encrypted hash output as Java code gives me. Please let me know what i have been doing wrong.

Encrypt.java

    @Component
    public class WebSecurity {

        @Autowired
        Environment env;
        private SecretKeySpec skeySpec;
        private Cipher cipher;

        public WebSecurity() {
            skeySpec = null;
            cipher = null;
        }

        public void initEncrypt(String key) throws Exception {
            try {
                skeySpec = new SecretKeySpec(HexUtil.HexfromString(key), "AES");
                cipher = Cipher.getInstance("AES");
                cipher.init(1, skeySpec);
            } catch (NoSuchAlgorithmException nsae) {
                throw new Exception("Invalid Java Version");
            } catch (NoSuchPaddingException nse) {
                throw new Exception("Invalid Key");
            }
        }

        public String encrypt(String message,String enc_key) throws Exception {
            try {
                initEncrypt(enc_key);

                byte encstr[] = cipher.doFinal(message.getBytes());
                String encData = HexUtil.HextoString(encstr);
                return java.net.URLEncoder.encode(encData);
            } catch (BadPaddingException nse) {
                throw new Exception("Invalid input String");
            }
        }

        public static void main(String[] args) throws Exception {
            System.out.println(new WebSecurity().encrypt("Charcoal Integration", "key here"));
        }

    }

Hexutil.java is the file where all the magic is happening and i am unable to replicate the same in nodejs.

    public class HexUtil {

        public HexUtil() {
        }

        public static byte[] HexfromString(String s) {
            int i = s.length();
            byte abyte0[] = new byte[(i + 1) / 2];
            int j = 0;
            int k = 0;
            if (i % 2 == 1)
                abyte0[k++] = (byte) HexfromDigit(s.charAt(j++));
            while (j < i)
                abyte0[k++] = (byte) (HexfromDigit(s.charAt(j++)) << 4 | HexfromDigit(s.charAt(j++)));
            return abyte0;
        }

        public static int HexfromDigit(char c) {
            if (c >= '0' && c <= '9')
                return c - 48;
            if (c >= 'A' && c <= 'F')
                return (c - 65) + 10;
            if (c >= 'a' && c <= 'f')
                return (c - 97) + 10;
            else
                throw new IllegalArgumentException("invalid hex digit: " + c);
        }

        public static String HextoString(byte abyte0[], int i, int j) {
            char ac[] = new char[j * 2];
            int k = 0;
            for (int l = i; l < i + j; l++) {
                byte byte0 = abyte0[l];
                ac[k++] = hexDigits[byte0 >>> 4 & 0xf];
                ac[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(ac);
        }

        public static String HextoString(byte abyte0[]) {
            return HextoString(abyte0, 0, abyte0.length);
        }

        private static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    }

This is the nodejs code that i have tried.

Encrypt.js

    let crypto = require('crypto');
    var util= require('util');

    var encoder=new util.TextEncoder();

    var encryptKey = function (text, algorithm) {
            var cipher = crypto.createCipher(algorithm, HexfromString('a4e11920212a47d85358bb86ba75abcd').toString('hex'));
            // console.log(HexfromString('a4e11920212a47d85358bb86ba750f37').toString('binary'))

            // var encstr = cipher.final(text).toString(2);

            // console.log(test);
            var abc=text.split('').map(s);
            // console.log('abc : ',(abc[0] >>> 0).toString(2))
            var crypted = cipher.update(HextoString(encoder.encode(String(text).getBytes())),'utf8', 'hex')
            crypted += cipher.final('hex');
            return crypted;

    }
    function s(x) {return x.charCodeAt(0);}


    var HexfromString = function(s){
            var i = s.length;
            var abyte0 = [(i + 1) / 2];
            var j = 0;
            var k = 0;
            if (i % 2 == 1){
                abyte0[k++] =  HexfromDigit(new Buffer(s.charAt(j++)));
            }
            while (j < i){
                // console.log('hex : ',HexfromDigit(s.charAt(j++)).toString(2))
                abyte0[k++] = (HexfromDigit(s.charAt(j++)) << 4 | HexfromDigit(s.charAt(j++))).toString(2)

            }
            return abyte0;
    }

    function getSignedInteger(bits) {
        return bits.length === 8 && +bits[0]
            ? ~(parseInt(bits, 2) ^ 255)
            : parseInt(bits, 2);
    }

    var HexfromDigit = function(a) {
        var c = a.charCodeAt(0);
        // console.log('a: ',a, ' c : ',c);
            if (c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0))
                return c - 48;
            if (c >= 'A'.charCodeAt(0) && c <= 'F'.charCodeAt(0))
                return (c - 65) + 10;
            if (c >= 'a'.charCodeAt(0) && c <= 'f'.charCodeAt(0))
                return (c - 97) + 10;
            else
                console.log('invalid hex digit', c)
        }

    var HextoStrings = function(abyte0, i, j) {
        console.log(abyte0)
            var tempArr=[j * 2]
            var k = 0;
            for (var l = i; l < j; l++) {
                var byte0 = abyte0[l];
                tempArr[k++] = hexDigits[byte0 >>> 4 & 0xf];
                tempArr[k++] = hexDigits[byte0 & 0xf];
                // console.log(hexDigits[byte0 >>> 4 & 0xf])
                // console.log(tempArr, k)
            }
            // console.log(tempArr);
            return  String(tempArr);
        }


    var HextoString = function(abyte0) {
            return HextoStrings(abyte0, 0, abyte0.length);
        }

    // var hexDigits = '0123456789ABCDEF';
    var hexDigits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];

    var valEncrypt = encryptKey('charcoaleats', 'aes-256-ecb');
    var encodedEnVal = encodeURI(valEncrypt);
    console.log( 'encrypt : ',encodedEnVal );

Key Used : a4e1112f45e84f785358bb86ba750f48

String To Be Encrypted : maharastra

Expected Hash Output : 81FD9101751D3F6632C0372E4BE257D1

Help is much appreciated.

9
  • The magic is in a hex encoder? Oh dear. Why not just get a pre-made hex encoder/decoder (i.e. codec)? You may need to prefix a 0character if the number of hex digits is odd. Commented Feb 17, 2020 at 15:33
  • 1
    Or simply use the built-in node cipher class? nodejs.org/api/crypto.html#crypto_class_cipher Commented Feb 17, 2020 at 15:40
  • @MaartenBodewes thanx ,in js we have Buffer.from method to convert string to hex , bt i am unable to generate the proper hex from the array , any code wld help me alot Commented Feb 17, 2020 at 15:40
  • OK, tested that for you, the hex encoding / decoding is not failing for the Java code. So you just need to create or implement a hex encoder. This is definitely wrong: abyte0[k++] = new Buffer(HexfromDigit(s.charAt(j++))); Commented Feb 17, 2020 at 15:55
  • @MaartenBodewes i have been following you , Buffer.from() method in nodejs gives me proper hex encoding of the key , still stucked at providing the proper buffer to hextoString Commented Feb 17, 2020 at 16:06

1 Answer 1

1
let crypto = require('crypto');

var iv = new Buffer.from('');   //(null) iv 
var algorithm = 'aes-256-ecb';
var password = 'a4e1112f45e84f785358bb86ba750f48';      //key password for cryptography

function encrypt(buffer){
    var cipher = crypto.createCipheriv(algorithm,new Buffer(password),iv)
    var crypted = Buffer.concat([cipher.update(buffer),cipher.final()]);
    return crypted;
}

console.log(encrypt(new Buffer('TextToEncrypt')).toString())
Sign up to request clarification or add additional context in comments.

1 Comment

Hey @rahul were you able to get this working, I am having same trouble as you. Wanted to check the final solution for this ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.