Nodejs javascript implementation of PBEWithMD5AndTripleDES/CBC/PKCS5Padding

前端 未结 2 960
轻奢々
轻奢々 2021-01-01 06:15

In order to write an simple nodejs app talking to an server written in java I have to implement the following functionality for nodejs.

public class Crypto {         


        
2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-01 06:49

    My final solution 5 years ago was:

    var forge = require('node-forge');
    var crypto = require('crypto');
    var base64Coder = require('./utils/tac-base64coder');
    var ByteBuffer = forge.util.ByteBuffer;
    
    var DES_EDE_KEY_LEN = 24;
    var DES_BLOCK_SIZE = 8;
    var SALT_BYTES = [0x45, 0xC4, 0x31, 0x72, 0x8A, 0x62, 0xB3, 0x9A];
    var KEY_BUFFER_LENGTH = 24;
    var IV_BUFFER_LENGTH = 8;
    
    module.exports = {
    
      /**
       * Generates the derived key. The 16 bytes of the first digest and the 1st 8 bytes of the 2nd digest
       * form the triple DES key, and the last 8 bytes of the 2nd digest form the IV.
       *
       * @method _deriveCipherKey
       * @param {String}      key       The key phrase
       * @param {Int8Array}   salt      The salt
       * @param {Number}      iCount    The iteration count
       * @returns {Buffer}
       * @private
       */
      _deriveCipherKey: function _deriveCipherKey (key, salt, iCount) {
        var md;
        var passwdBytes = new Buffer(key);
        var i;
        var toBeHashed;
        var result = new Buffer(DES_EDE_KEY_LEN + DES_BLOCK_SIZE);
        result.fill(0);
    
        // if the 2 salt halves are the same, invert one of them
        for (i = 0; i < 4; i++) {
          if (salt[i] !== salt[i + 4]) {
            break;
          }
        }
    
        if (i === 4) { // same, invert 1st half
          for (i = 0; i < 2; i++) {
            var tmp = salt[i];
            salt[i] = salt[3 - i];
            salt[3 - 1] = tmp;
          }
        }
    
        for (i = 0; i < 2; i++) {
          toBeHashed = new Buffer(salt.length / 2);
          toBeHashed.fill(0);
    
          salt.copy(toBeHashed, 0, i * (salt.length / 2));
    
          for (var j = 0; j < iCount; j++) {
            md = crypto.createHash('md5');
            md.update(toBeHashed);
            md.update(passwdBytes);
            toBeHashed = md.digest();
          }
          toBeHashed.copy(result, i * 16);
        }
    
        return result;
      },
    
      /**
       * Encrypts the given string with the given key
       *
       * @method encrypt
       * @param {String}      encryptionKey   The encryption key
       * @param {String}      toEncrypt       The string to encrypt
       * @returns {String}
       */
      encrypt: function encrypt (encryptionKey, toEncrypt) {
        var encodedStr = forge.util.encodeUtf8(toEncrypt);
        var salt = new Buffer(SALT_BYTES);
        var key = new Buffer(KEY_BUFFER_LENGTH);
        var iv = new Buffer(IV_BUFFER_LENGTH);
        var key2 = new ByteBuffer();
        var iv2 = new ByteBuffer();
        var derivedKey = this._deriveCipherKey(encryptionKey, salt, 12);
        var cipher;
        var i = 0;
    
        derivedKey.copy(key, 0, 0, 24);
        derivedKey.copy(iv, 0, 24);
    
        for (; i < KEY_BUFFER_LENGTH; i++) {
          key2.putByte(key[i]);
        }
    
        for (i = 0; i < IV_BUFFER_LENGTH; i++) {
          iv2.putByte(iv[i]);
        }
    
        cipher = forge.des.createEncryptionCipher(key2);
        cipher.start(iv2);
        cipher.update(forge.util.createBuffer(encodedStr));
        cipher.finish();
    
        return base64Coder.encode(cipher.output.getBytes().toString());
      },
    
      /**
       * Decrypts the given base64 string with the given key
       *
       * @method decrypt
       * @param {String}      encryptionKey     The decryption key
       * @param {String}      toDecrypt         The encrypted base64 string
       * @returns {String}
       */
      decrypt: function decrypt (encryptionKey, toDecrypt) {
        var decr = forge.util.decode64(toDecrypt);
        var salt = new Buffer(SALT_BYTES);
        var key = new Buffer(KEY_BUFFER_LENGTH);
        var iv = new Buffer(IV_BUFFER_LENGTH);
        var derivedKey = this._deriveCipherKey(encryptionKey, salt, 12);
        var key2 = new forge.util.ByteBuffer();
        var iv2 = new forge.util.ByteBuffer();
        var i = 0;
        var cipher;
    
        derivedKey.copy(key, 0, 0, 24);
        derivedKey.copy(iv, 0, 24);
    
        for (; i < KEY_BUFFER_LENGTH; i++) {
          key2.putByte(key[i]);
        }
    
        for (i = 0; i < IV_BUFFER_LENGTH; i++) {
          iv2.putByte(iv[i]);
        }
    
        cipher = forge.des.createDecryptionCipher(key2);
    
        cipher.start(iv2);
        cipher.update(forge.util.createBuffer(decr));
        cipher.finish();
    
        return cipher.output.getBytes().toString('utf8');
      }
    };
    

提交回复
热议问题