Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AES-CBC在ActionScript中加密,在Javascript中解密_Javascript_Node.js_Actionscript 3_Node Crypto_As3crypto - Fatal编程技术网

AES-CBC在ActionScript中加密,在Javascript中解密

AES-CBC在ActionScript中加密,在Javascript中解密,javascript,node.js,actionscript-3,node-crypto,as3crypto,Javascript,Node.js,Actionscript 3,Node Crypto,As3crypto,我们有一个用ActionScript编写的遗留工具,它使用AES-CBC和硬编码共享密钥加密输入。我正在尝试用Typescript编写相应的解密函数,但没有成功。AS3端使用Hurlant as3crypto库,该库带有NullPad和一个空(例如长度为0)IV。同样值得注意的是,共享机密只有15字节,而不是16字节。as3crypto似乎并不介意,我也尝试过使用16字节的密钥,但没有成功。我的目标是修复Javascript中的AESDeccrypt()函数,以便成功解密AS3 AESNecyp

我们有一个用ActionScript编写的遗留工具,它使用AES-CBC和硬编码共享密钥加密输入。我正在尝试用Typescript编写相应的解密函数,但没有成功。AS3端使用Hurlant as3crypto库,该库带有NullPad和一个空(例如长度为0)IV。同样值得注意的是,共享机密只有15字节,而不是16字节。as3crypto似乎并不介意,我也尝试过使用16字节的密钥,但没有成功。我的目标是修复Javascript中的AESDeccrypt()函数,以便成功解密AS3 AESNecypt()函数的输出

下面是AS3中的encypt(以及工作解密对应项),然后是Typescript中的尝试解密(和相应的加密)函数。在本例中,输入“test”在AS3中被加密为“ryhkw3BmJ85+qBr0E9bYqw==”,但Javascript解密不会产生“test”

AS3

<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" visible="false">
    <fx:Script><![CDATA[
        import com.hurlant.crypto.Crypto;
        import com.hurlant.crypto.symmetric.ICipher;
        import com.hurlant.crypto.symmetric.IPad;
        import com.hurlant.crypto.symmetric.IVMode;
        import com.hurlant.crypto.symmetric.NullPad;
        import com.hurlant.util.Hex;

        import mx.utils.Base64Decoder;
        import mx.utils.Base64Encoder;

        static var KEY:String = "vI^diTubIwH]Gag";

        internal static function aesEncrypt(decoded:String):String
        {
            var pad:IPad = new NullPad();
            var mode:ICipher = Crypto.getCipher("aes-cbc", Hex.toArray(Hex.fromString(KEY)), pad);
            pad.setBlockSize(mode.getBlockSize());

            var iv:ByteArray = new ByteArray();
            if (mode is IVMode) {
                (mode as IVMode).IV = iv;
            }

            var encoder:Base64Encoder = new Base64Encoder();
            var ba:ByteArray = Hex.toArray(Hex.fromString(decoded));
            mode.encrypt(ba);
            encoder.reset();
            encoder.encodeBytes(ba);
            return encoder.toString();
        }

        internal static function aesDecrypt(encoded:String):String
        {
            var pad:IPad = new NullPad();
            var mode:ICipher = Crypto.getCipher("aes-cbc", Hex.toArray(Hex.fromString(KEY)), pad);
            pad.setBlockSize(mode.getBlockSize());

            var iv:ByteArray = new ByteArray();
            if (mode is IVMode) {
                (mode as IVMode).IV = iv;
            }
            var decoder:Base64Decoder = new Base64Decoder();
            decoder.reset();
            decoder.decode(encoded);
            var ba:ByteArray = decoder.toByteArray();
            mode.decrypt(ba);
            return Hex.toString(Hex.fromArray(ba));
        }

        trace(aesEncrypt('test'));
        trace(aesDecrypt('ryhkw3BmJ85+qBr0E9bYqw=='));
        ]]></fx:Script>
</s:Application>
不幸的是,我们不能像我们希望的那样更新ActionScript工具的遗留代码(特别是因为空IV和空填充都不好,更不用说非标准密钥长度了)。如果有人能帮我演示如何修复Javascript端以进行解密,我将不胜感激。我更喜欢纯节点加密解决方案,但如果CryptoJS或Forge可以使用的话,我很乐意使用它们(我在这项任务中使用它们也不成功)

let crypto = require('crypto');

function aesEncrypt(cleartext:string, cipherType:string = 'AES', keyBitLength:number = 128, mode:string = 'CBC', cryptkey:string = 'vI^diTubIwH]Gag') {
  const algorithm = `${cipherType.toLowerCase()}-${keyBitLength}-${mode.toLowerCase()}`;
  const blockSize = keyBitLength / 8;
  const key = Buffer.from(cryptkey);
  const paddedKey = nullPad(key, blockSize);
  const iv = Buffer.alloc(blockSize, 0);
  const cipher = crypto.createCipheriv(algorithm, paddedKey, iv);
  cipher.setAutoPadding(false);
  const encodedInputBuffer = Buffer.from(cleartext, 'utf8');
  const encodedInput = encodedInputBuffer.toString('hex');
  const paddedInputBuffer = nullPad(Buffer.from(encodedInput), blockSize);
  const encrypted = Buffer.concat([cipher.update(paddedInputBuffer), cipher.final()])
  return encrypted.toString('base64');
}

function aesDecrypt(encoded:string, cipherType:string = 'AES', keyBitLength:number = 128, mode:string = 'CBC', cryptkey:string = 'vI^diTubIwH]Gag') {
  const algorithm = `${cipherType.toLowerCase()}-${keyBitLength}-${mode.toLowerCase()}`;
  const blockSize = keyBitLength / 8;
  const key = Buffer.from(cryptkey);
  const paddedKey = nullPad(key, blockSize);
  let iv = Buffer.alloc(blockSize, 0);
  const decipher = crypto.createDecipheriv(algorithm, paddedKey, iv);
  decipher.setAutoPadding(false);
  const decodedInput = Buffer.from(encoded, 'base64').toString( 'binary');
  let decrypted = Buffer.concat([decipher.update(decodedInput, 'binary'), decipher.final()]);
  return decrypted.toString().trim();
}

function nullPad(input:Buffer, length:number) {
  const nullPad = Buffer.alloc(length);
  let padLength = length - (input.length % length);
  if (padLength == length) {
    padLength = 0;
  }

  if(padLength > 0) {
    input = Buffer.concat([input, nullPad.slice(0, padLength)]);
  }
  return input;
}

// should output "ryhkw3BmJ85+qBr0E9bYqw=="
console.log("Encrypt 'test'\t\t\t\t>>>\t" + aesEncrypt("test"));

// should output "test"
console.log("Decrypt 'ryhkw3BmJ85+qBr0E9bYqw=='\t>>>\t" + aesDecrypt("ryhkw3BmJ85+qBr0E9bYqw=="));
// working roundtrips
console.log("Decrypt '+3C9rjmO7W7hIQqcJMPgXQ=='\t>>>\t" + Buffer.from(aesDecrypt("+3C9rjmO7W7hIQqcJMPgXQ=="), 'hex').toString());
console.log("Decrypt 'elaKkhcvG75EBFvZwB1KiA=='\t>>>\t" + aesDecrypt("elaKkhcvG75EBFvZwB1KiA=="));