【问题标题】:AES encryption in NI LabVIEWNI LabVIEW中的AES加密
【发布时间】:2018-08-21 10:08:22
【问题描述】:

如何在LabVIEW中实现AES加解密并配置如下设置?

  1. 填充 = PaddingMode.PKCS7
  2. 模式 = CipherMode.CBC
  3. 密钥大小 = 128
  4. 块大小 = 128

我在这里尝试了几个选项Igor TitovAES Crypto Toolkit by Alab Technologies 试图联系双方确认这些工具包是否支持上述配置,但他们没有通过电话或电子邮件回复。 非常感谢任何帮助。

我从Igor Titov找到了这段代码

加密:https://github.com/IgorTitov/LabVIEW-Advanced-Encryption-Standard/blob/master/Encrypt%20with%20AES.vi

/** 
     * Encrypt a text using AES encryption in Counter mode of operation
     *
     * Unicode multi-byte character safe
     *
     * @param plaintext Source text to be encrypted
     * @param password  The password to use to generate a key
     * @param nBits     Number of bits to be used in the key (128, 192, or 256)
     * @returns         Encrypted text
     */


    public function encrypt(plaintext : String, password : String, nBits : int) : String //Done in LV
    {
           var blockSize : int = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
        if (!(nBits == BIT_KEY_128 || nBits == BIT_KEY_192 || nBits == BIT_KEY_256)) 
  {
                 // standard allows 128/192/256 bit keys
              throw new Error("Must be a key mode of either 128, 192, 256 bits");
        }
        plaintext = Utf8.encode(plaintext);
        password = Utf8.encode(password);

        // use AES itself to encrypt password to get cipher key (using plain password as source for key 
        // expansion) - gives us well encrypted key
        var nBytes : int = nBits / 8;  // no bytes in key
        var pwBytes : Array = new Array(nBytes);
        for (var i : int = 0;i < nBytes;i++) 
        {
               pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
        }
        var key : Array = cipher(pwBytes, keyExpansion(pwBytes));  // gives us 16-byte key

        key = key.concat(key.slice(0, nBytes - 16));  // expand key to 16/24/32 bytes long

        // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
        // block counter in 2nd 8 bytes
        var counterBlock : Array = new Array(blockSize);
        var nonce : int = 123456789;////DEBUG!!!(new Date()).getTime();  // timestamp: milliseconds since 1-Jan-1970
        var nonceSec : int = Math.floor(nonce / 1000);
        var nonceMs : int = nonce % 1000;

        // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes
        for (i = 0;i < 4;i++) 
        {
               counterBlock[i] = (nonceSec >>> (i * 8)) & 0xff;             
        }

        for (i = 0;i < 4;i++)
        {
               counterBlock[i + 4] = nonceMs & 0xff;
        } 
        // and convert it to a string to go on the front of the ciphertext
        var ctrTxt : String = '';
        for (i = 0;i < 8;i++) 
        {
               ctrTxt += String.fromCharCode(counterBlock[i]);
        }
        // generate key schedule - an expansion of the key into distinct Key Rounds for each round
        var keySchedule : Array = keyExpansion(key);
        var blockCount : int = Math.ceil(plaintext.length / blockSize);
        var ciphertxt : Array = new Array(blockCount);  // ciphertext as array of strings

        for (var b : int = 0;b < blockCount;b++) 
        {
               // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
               // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
               for (var c : int = 0;c < 4;c++) 
            {
                    counterBlock[15 - c] = (b >>> (c * 8)) & 0xff;                  
        }

            for (c = 0;c < 4;c++) 
            {
                    counterBlock[15 - c - 4] = (b / 0x100000000 >>> c * 8);
            }

            var cipherCntr : Array = cipher(counterBlock, keySchedule);  // -- encrypt counter block --

            // block size is reduced on final block
            var blockLength : int = b < blockCount - 1 ? blockSize : (plaintext.length - 1) % blockSize + 1;
            var cipherChar : Array = new Array(blockLength);

            for (i = 0;i < blockLength;i++) 
            {  
                // -- xor plaintext with ciphered counter char-by-char --
                cipherChar[i] = cipherCntr[i] ^ plaintext.charCodeAt(b * blockSize + i);                    
                //trace("i=",i,"plaintext.charCodeAt(b * blockSize + i)",plaintext.charCodeAt(b * blockSize + i),"cipherChar[i]=",cipherChar[i]);
                cipherChar[i] = String.fromCharCode(cipherChar[i]);

            }

            ciphertxt[b] = cipherChar.join(''); 
            //trace(ciphertxt);
        }

        // Array.join is more efficient than repeated string concatenation in IE
        var ciphertext : String = ctrTxt + ciphertxt.join('');
        //trace("before 64 encode:",ciphertext);
        ciphertext = Base64.encode(ciphertext);  // encode in base64
           //trace("after 64 encode:",ciphertext);
           //alert((new Date()) - t);

        return ciphertext;
    }

解密:https://github.com/IgorTitov/LabVIEW-Advanced-Encryption-Standard/blob/master/Decrypt%20with%20AES.vi

/** 
         * Decrypt a text encrypted by AES in counter mode of operation
         *
         * @param ciphertext Source text to be encrypted
         * @param password   The password to use to generate a key
         * @param nBits      Number of bits to be used in the key (128, 192, or 256)
         * @returns          Decrypted text
         */
        public function decrypt(ciphertext : String, password : String, nBits : int) : String 
  {
            var blockSize : int = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
            if (!(nBits == BIT_KEY_128 || nBits == BIT_KEY_192 || nBits == BIT_KEY_256)) {
                  // standard allows 128/192/256 bit keys
                  throw new Error("Must be a key mode of either 128, 192, 256 bits");
            }

            ciphertext = Base64.decode(ciphertext.split("\n").join(""));
            password = Utf8.encode(password);
            //var t = new Date();  // timer

            // use AES to encrypt password (mirroring encrypt routine)
            var nBytes : int = nBits / 8;  // no bytes in key
            var pwBytes : Array = new Array(nBytes);
            for (var i : int = 0;i < nBytes;i++) 
            {
                pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
            }
            var key : Array = cipher(pwBytes, keyExpansion(pwBytes));
            key = key.concat(key.slice(0, nBytes - 16));  // expand key to 16/24/32 bytes long

            // recover nonce from 1st 8 bytes of ciphertext
            var counterBlock : Array = new Array(8);
            var ctrTxt : String = ciphertext.slice(0, 8);
            for (i = 0;i < 8;i++) 
            {
                counterBlock[i] = ctrTxt.charCodeAt(i);
            }

            // generate key schedule
            var keySchedule : Array = keyExpansion(key);

            // separate ciphertext into blocks (skipping past initial 8 bytes)
            var nBlocks : int = Math.ceil((ciphertext.length - 8) / blockSize);
            var ct : Array = new Array(nBlocks);
            for (b = 0;b < nBlocks;b++) 
            {
                ct[b] = ciphertext.slice(8 + b * blockSize, 8 + b * blockSize + blockSize);

                //trace("ct[b]=",ct[b],"blockSize=",blockSize,8 + b * blockSize, 8 + b * blockSize + blockSize);
            }
            //var temp:String=ct[1];
//          for (var i:int=0;i<temp.length;i++)
//          {
//              trace("ct[1]Byte Array:",temp.charCodeAt(i));
//          }

            var ciphertextArr : Array = ct;  // ciphertext is now array of block-length strings

            // plaintext will get generated block-by-block into array of block-length strings
            var plaintxt : Array = new Array(ciphertextArr.length);

            for (var b : int = 0;b < nBlocks;b++) 
            {
                // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
                for (var c : int = 0;c < 4;c++) 
                   {
                        counterBlock[15 - c] = ((b) >>> c * 8) & 0xff;
                }
                for (c = 0;c < 4;c++) 
                {
                        counterBlock[15 - c - 4] = (((b + 1) / 0x100000000 - 1) >>> c * 8) & 0xff;
                }
                //trace(counterBlock);
                var cipherCntr : Array = cipher(counterBlock, keySchedule);  // encrypt counter block
                //trace(cipherCntr);
                var plaintxtByte : Array = new Array(String(ciphertextArr[b]).length);
                for (i = 0;i < String(ciphertextArr[b]).length;i++) 
                {
                    // -- xor plaintxt with ciphered counter byte-by-byte --
                    plaintxtByte[i] = cipherCntr[i] ^ String(ciphertextArr[b]).charCodeAt(i);
                    //trace("i=",i,"plaintxtByte[i]=",plaintxtByte[i],"cipherCntr[i]=",cipherCntr[i],"String(ciphertextArr[b]).charCodeAt(i)=",String(ciphertextArr[b]).charCodeAt(i));
                    //trace(plaintxtByte[i]);
                    plaintxtByte[i] = String.fromCharCode(plaintxtByte[i]);

                }
                plaintxt[b] = plaintxtByte.join('');
            }

            // join array of blocks into single plaintext string
            var plaintext : String = plaintxt.join('');
            plaintext = Utf8.decode(plaintext);  // decode from UTF8 back to Unicode multi-byte chars
            return plaintext;
        }

不确定这是什么编程语言。如果我能在将此代码转换为 C# 方面获得帮助,这将解决我的阻塞问题。

这是 VI sn-p。

【问题讨论】:

  • 这看起来像 ActionScript,但我以前从未使用过那种语言,所以我可能是错的。您问题中指向 Igor 存储库的链接指向 LabVIEW 源 VI 文件,而不是这些函数。这些是从哪里来的?
  • @JoeFriedrichsen 在那个 LabView 文件中,他添加了这个代码作为描述。添加了该vi框图的图像,请检查
  • @HaBo 让我知道答案是否有帮助,否则如果你被卡住了,我可以写填充。 S
  • @SeanJ 我有点卡住了。如果您可以与填充共享,那将有所帮助。
  • @HaBo 目前时间不多,但您不妨试试:lavag.org/files/file/198-encryption

标签: c# aes labview


【解决方案1】:

我对河豚做过类似的事情,但不熟悉 Alab Tech 的 AES 实现。
假设 Alab Tech 库功能正确,只需在加密之前根据需要填充数据。

KCS7(在 RFC 5652 中描述)。这会将数据填充到块大小 number 等于添加的字节数。如果是原 data 是 N 字节的整数倍,然后是额外的字节块 与值 N 相加

这听起来相对简单,下面的简单框图显示了它的工作原理:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 2016-09-22
    相关资源
    最近更新 更多