• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數據加載中……

            ChaCha20 加密 算法 c++11實現


            ChaCha20 加密/解密算法, 支持單輪多輪加密
              1 #ifndef CHACHA20_H
              2 #define CHACHA20_H
              3 
              4 #include <array>
              5 #include <vector>
              6 #include <algorithm>
              7 #include <sstream>
              8 #include <iostream>
              9 #include <iomanip>
             10 #include <string>
             11 
             12 //#include<QDebug>
             13 
             14 
             15 /**
             16  * @brief ChaCha20 加密/解密算法, 支持單輪多輪加密
             17  */
             18 class ChaCha20
             19 {
             20 public:
             21     /**
             22      * @brief ChaCha20 chacha20加密算法構造器 單輪
             23      * @param key 32字節的key
             24      * @param nonce 8字節隨機數
             25      */
             26     ChaCha20(std::array<unsigned char32> key, std::array<unsigned char8> nonce) :
             27         matrix{}
             28     {
             29         // 16byte常量字符串"apxe3 dnyb-2k et"
             30         this->matrix[ 0= 0x61707865;
             31         this->matrix[ 1= 0x3320646e;
             32         this->matrix[ 2= 0x79622d32;
             33         this->matrix[ 3= 0x6b206574;
             34 
             35         this->matrix[ 4= littleEndianToInt(key, 0);
             36         this->matrix[ 5= littleEndianToInt(key, 4);
             37         this->matrix[ 6= littleEndianToInt(key, 8);
             38         this->matrix[ 7= littleEndianToInt(key, 12);
             39 
             40         this->matrix[ 8= littleEndianToInt(key, 16);
             41         this->matrix[ 9= littleEndianToInt(key, 20);
             42         this->matrix[10= littleEndianToInt(key, 24);
             43         this->matrix[11= littleEndianToInt(key, 28);
             44 
             45         this->matrix[12= 0;
             46         this->matrix[13= 0;
             47         this->matrix[14= littleEndianToInt(nonce, 0);
             48         this->matrix[15= littleEndianToInt(nonce, 4);
             49     }
             50 
             51     /**
             52      * @brief ChaCha20 ChaCha20 chacha20加密算法構造器, 多輪
             53      * @param key 32字節key
             54      * @param nonce 12字節隨機數
             55      * @param counter 輪轉次數
             56      */
             57     ChaCha20(std::array<unsigned char32> key, std::array<unsigned char12> nonce, const int counter) :
             58         matrix{}
             59     {
             60 
             61         // 16byte常量字符串"apxe3 dnyb-2k et"
             62         this->matrix[ 0= 0x61707865;
             63         this->matrix[ 1= 0x3320646e;
             64         this->matrix[ 2= 0x79622d32;
             65         this->matrix[ 3= 0x6b206574;
             66 
             67         this->matrix[ 4= littleEndianToInt(key, 0);
             68         this->matrix[ 5= littleEndianToInt(key, 4);
             69         this->matrix[ 6= littleEndianToInt(key, 8);
             70         this->matrix[ 7= littleEndianToInt(key, 12);
             71         this->matrix[ 8= littleEndianToInt(key, 16);
             72         this->matrix[ 9= littleEndianToInt(key, 20);
             73         this->matrix[10= littleEndianToInt(key, 24);
             74         this->matrix[11= littleEndianToInt(key, 28);
             75 
             76 
             77         this->matrix[12= counter;
             78         this->matrix[13= littleEndianToInt(nonce, 0);
             79         this->matrix[14= littleEndianToInt(nonce, 4);
             80         this->matrix[15= littleEndianToInt(nonce, 8);
             81     }
             82 
             83 
             84     /**
             85      * @brief encrypt 加密
             86      * @param plain 原文
             87      * @param dst 密文
             88      * @param len 原文長度
             89      */
             90     void encrypt( std::vector<unsigned char>& plain, std::vector<unsigned char>& ciphertext) {
             91         std::array<int16> x{};
             92         std::array<unsigned char64> output{};
             93         int i, dpos = 0, spos = 0, len = plain.size();
             94 //        qDebug() << "len:" << len;
             95         while (len > 0) {
             96 //            for (i = 16; i-- > 0; ) x[i] = this->matrix[i];
             97             std::copy_n(matrix.begin(), matrix.size(), x.begin());
             98             for (i = 20; i > 0; i -= 2) {
             99                 quarterRound(x, 04,  812);
            100                 quarterRound(x, 15,  913);
            101                 quarterRound(x, 261014);
            102                 quarterRound(x, 371115);
            103                 quarterRound(x, 051015);
            104                 quarterRound(x, 161112);
            105                 quarterRound(x, 27,  813);
            106                 quarterRound(x, 34,  914);
            107 
            108 //                qDebug() << "[" << intToHex(x[0]).c_str() << ", " << intToHex(x[1]).c_str() << ", " << intToHex(x[2]).c_str() << ", " << intToHex(x[3]).c_str()
            109 //                         << ", " << intToHex(x[4]).c_str() << ", " << intToHex(x[5]).c_str() << ", " << intToHex(x[6]).c_str() << ", " << intToHex(x[7]).c_str()
            110 //                         << ", " << intToHex(x[8]).c_str() << ", " << intToHex(x[9]).c_str() << ", " << intToHex(x[10]).c_str() << ", " << intToHex(x[11]).c_str()
            111 //                         << ", " << intToHex(x[12]).c_str() << ", " << intToHex(x[13]).c_str() << ", " << intToHex(x[14]).c_str() << ", " << intToHex(x[15]).c_str()  << "]";
            112             }
            113             for (i = 16; i-- > 0; ) x[i] += this->matrix[i];
            114             for (i = 16; i-- > 0; ) intToLittleEndian(x[i], output, 4 * i);
            115 
            116             // TODO: (1) check block count 32-bit vs 64-bit; (2) java int is signed!
            117             this->matrix[12+= 1;
            118             if (this->matrix[12== 0) {
            119                 this->matrix[13+= 1;
            120             }
            121             if (len <= 64) {
            122                 for (i = len; i-- > 0; ) {
            123 //                    qDebug() << "dist["  << (i + dpos) << "] = " << ((unsigned char) (plain[i + spos] ^ output[i]));
            124                     ciphertext[i + dpos] = (unsigned char) (plain[i + spos] ^ output[i]);
            125                 }
            126                 return;
            127             }
            128             for (i = 64; i-- > 0; ) {
            129 //                qDebug() << "dist[" << (i + dpos) << "] = " << ((unsigned char) (plain[i + spos] ^ output[i]));
            130                 ciphertext[i + dpos] = (unsigned char) (plain[i + spos] ^ output[i]);
            131             }
            132             len -= 64;
            133             spos += 64;
            134             dpos += 64;
            135         }
            136     }
            137 
            138 
            139 
            140     /**
            141      * @brief decrypt 解密
            142      * @param src 原文
            143      * @param plain 密文
            144      * @param len
            145      */
            146     void decrypt(std::vector<unsigned char>& ciphertext, std::vector<unsigned char>& plain) {
            147         encrypt(ciphertext, plain);
            148     }
            149 
            150 
            151 //    void test(){
            152 //        int v = 0xaaaa, c=0x8888;
            153 //        rotate(v, c);
            154 //    }
            155 
            156 
            157 protected:
            158     template< typename T >
            159     std::string intToHex( const T& i )
            160     {
            161       std::stringstream stream;
            162       stream //<< "0x"
            163              << std::setfill ('0'<< std::setw(sizeof(T)*2)
            164              << std::hex << i;
            165       return stream.str();
            166     }
            167 
            168 private:
            169     /**
            170      * N支持8或12
            171      */
            172     template<size_t N >
            173     /**
            174      * @brief littleEndianToInt 小端內存塊轉整數
            175      * @param bs  小端內存塊
            176      * @param offset 需要轉換成int的位置offset
            177      * @return 返回轉換后的整數
            178      */
            179     inline int littleEndianToInt(std::array<unsigned char, N>& bs, const int& offset){
            180         return (bs[offset]) | (bs[offset + 1<< 8| (bs[offset + 2<< 16| (bs[offset + 3<< 24);
            181     }
            182 
            183 
            184     /**
            185      * @brief intToLittleEndian
            186      * @param n 整數
            187      * @param bs 小端內存塊, 出參
            188      * @param offset 存放在內存塊中的偏移位
            189      */
            190     inline void intToLittleEndian(const int& n, std::array<unsigned char64>& bs, int offset){
            191         bs[  offset] = (unsigned char)(n      );
            192         bs[++offset] = (unsigned char)((unsigned)n >>  8);
            193         bs[++offset] = (unsigned char)((unsigned)n >> 16);
            194         bs[++offset] = (unsigned char)((unsigned)n >> 24);
            195     }
            196 
            197 
            198     int rotate(const int& v, const int& c){
            199 //        qDebug() << intToHex((v << c) | (v >> (32 - c))).c_str();
            200         return (v << c) | ((unsigned)v >> (32 - c));
            201     }
            202 
            203     void quarterRound(std::array<int16>& x, const int& a, const int& b, const int& c, const int& d) {
            204 //        qDebug() << "begin " << intToHex(x[a]).c_str() << ", "<< intToHex(x[b]).c_str() << ", "<< intToHex(x[c]).c_str() << ", "<< intToHex(x[d]).c_str();
            205         x[a] += x[b];
            206 //        qDebug() << "1 " << intToHex(x[a]).c_str() << ", "<< intToHex(x[b]).c_str() << ", "<< intToHex(x[c]).c_str() << ", "<< intToHex(x[d]).c_str();
            207 
            208 //        qDebug() << "1 " << intToHex(x[d]).c_str() << ",  " << intToHex(x[d] ^ x[a]).c_str();
            209         x[d] = rotate(x[d] ^ x[a], 16);
            210 //        qDebug() << "1 " << intToHex(x[d]).c_str() << ",  " << intToHex(x[d] ^ x[a]).c_str();
            211         x[c] += x[d];
            212 //        qDebug() << "2 " << intToHex(x[a]).c_str() << ", "<< intToHex(x[b]).c_str() << ", "<< intToHex(x[c]).c_str() << ", "<< intToHex(x[d]).c_str();
            213 
            214         x[b] = rotate(x[b] ^ x[c], 12);
            215 //        qDebug() << "2 " << intToHex(x[b]).c_str() ;
            216         x[a] += x[b];
            217         x[d] = rotate(x[d] ^ x[a], 8);
            218         x[c] += x[d];
            219         x[b] = rotate(x[b] ^ x[c], 7);
            220 //        qDebug() << "end " << intToHex(x[a]).c_str() << ", "<< intToHex(x[b]).c_str() << ", "<< intToHex(x[c]).c_str() << ", "<< intToHex(x[d]).c_str();
            221     }
            222 
            223 
            224 private:
            225     std::array<int16> matrix;
            226 
            227 };
            228 
            229 
            230 
            231 
            232 #endif // CHACHA20_H
            233 






            調用方式:

            1  加密:

             1         volatile bool flag = false;
             2         //加密
             3         QByteArray qKeyBytes = qKey.toUtf8();
             4         std::array<unsigned char32> keyBytes;
             5         std::copy_n(qKeyBytes.begin(), keyBytes.size(), keyBytes.begin());
             6 
             7         QByteArray qSourceBytes = qSource.toUtf8();
             8         std::vector<unsigned char> sourceBytes(qSourceBytes.size());
             9         std::copy_n(qSourceBytes.begin(), qSourceBytes.size(), sourceBytes.begin());
            10 
            11         std::vector<unsigned char> destinaBytes(sourceBytes.size());
            12         if(qNonce.length() == 8){
            13             QByteArray qNonceBytes = qNonce.toUtf8();
            14             std::array<unsigned char8> nonceBytes;
            15             std::copy_n(qNonceBytes.begin(), qNonceBytes.size(), nonceBytes.begin());
            16             ChaCha20 chacha20(keyBytes, nonceBytes);
            17             //            chacha20.test();
            18             chacha20.encrypt(sourceBytes, destinaBytes);
            19             flag = true;
            20         } else if(qNonce.length() == 12){
            21             QByteArray qNonceBytes = qNonce.toUtf8();
            22             std::array<unsigned char12> nonceBytes;
            23             std::copy_n(qNonceBytes.begin(), qNonceBytes.size(), nonceBytes.begin());
            24             ChaCha20 chacha20(keyBytes, nonceBytes, qCounter.toUInt());
            25             //            chacha20.test();
            26             chacha20.encrypt(sourceBytes, destinaBytes);
            27             flag = true;
            28         } else {
            29             qDebug() << TIMESTAMP << "encrypt nonce長度不合法";
            30         }
            31 
            32         if(flag){
            33             QByteArray qDestBytes(destinaBytes.size(), 0);
            34             std::copy_n(destinaBytes.begin(), destinaBytes.size(), qDestBytes.begin());
            35 
            36             qDebug() << TIMESTAMP << "encrypt data:" << qDestBytes.toHex();
            37 
            38             QString qDestStr = qDestBytes.toBase64(QByteArray::Base64UrlEncoding);
            39             qDebug() << TIMESTAMP << "encrypt base64 data:" << qDestStr;
            40 
            41             ui->leDestina->setText(qDestStr);
            42         }



            2: 解密
                        volatile bool flag = false;
                        //解密
                        QByteArray qKeyBytes = qKey.toUtf8();
                        std::array<unsigned char, 32> keyBytes;
                        std::copy_n(qKeyBytes.begin(), keyBytes.size(), keyBytes.begin());

                        QByteArray qDestinaBytes;
                        qDestinaBytes = qDestinaBytes.fromBase64(qDestina.toUtf8());
                //        qDebug() << TIMESTAMP << "ciphertext data:" << qDestinaBytes.toHex();

                        std::vector<unsigned char> destinaBytes(qDestinaBytes.size());
                        std::copy_n(qDestinaBytes.begin(), qDestinaBytes.size(), destinaBytes.begin());

                        std::vector<unsigned char> sourceBytes(destinaBytes.size());
                        if(qNonce.length() == 8){
                            QByteArray qNonceBytes = qNonce.toUtf8();
                            std::array<unsigned char, 8> nonceBytes;
                            std::copy_n(qNonceBytes.begin(), qNonceBytes.size(), nonceBytes.begin());
                            ChaCha20 chacha20(keyBytes, nonceBytes);
                            chacha20.decrypt(destinaBytes, sourceBytes);
                            flag = true;
                        } else if(qNonce.length() == 12){
                            QByteArray qNonceBytes = qNonce.toUtf8();
                            std::array<unsigned char, 12> nonceBytes;
                            std::copy_n(qNonceBytes.begin(), qNonceBytes.size(), nonceBytes.begin());
                            ChaCha20 chacha20(keyBytes, nonceBytes, qCounter.toUInt());
                            chacha20.decrypt(destinaBytes, sourceBytes);
                            flag = true;
                        } else {
                            qDebug() << TIMESTAMP << "decrypt nonce長度不合法";
                        }

                        if(flag){
                            QByteArray qSourceBytes(sourceBytes.size(), 0);
                            std::copy_n(sourceBytes.begin(), sourceBytes.size(), qSourceBytes.begin());

                            qDebug() << TIMESTAMP << "decrypt ascii data:" << qSourceBytes.toHex();

                            QString qSourceStr = qSourceBytes;
                            qDebug() << TIMESTAMP << "decrypt data:" << qSourceStr;

                            ui->leSource->setText(qSourceStr);
                        }


                        //解密
                        qDebug() << TIMESTAMP << "key:" << qKey << ", nonce:" << qNonce << ", counter:" << qCounter
                                 << ", destina:" << qDestina;



            后記 :
            1. nonce長度只允許8字節或12字節, 如果nonce長度為8字節, 則counter被無視, 如果為12字節, counter才有效
            2. key長度恒定為32字節, 如果不足, 自己補齊32字節
            3. 解密就是將加密的結果在xor一次





















            posted on 2021-06-03 17:38 Khan 閱讀(2781) 評論(0)  編輯 收藏 引用

            中文字幕亚洲综合久久2| 久久免费国产精品| 精品伊人久久大线蕉色首页| 久久久综合香蕉尹人综合网| 国产L精品国产亚洲区久久| 亚洲国产精品婷婷久久| 久久777国产线看观看精品| 久久久国产精品亚洲一区| 久久久久99精品成人片直播| 成人国内精品久久久久一区| 乱亲女H秽乱长久久久| 久久久久久国产精品免费无码| 久久久久久午夜成人影院 | 久久精品国产清自在天天线 | 久久久久99精品成人片| 精品久久久久久无码人妻热 | 精品一二三区久久aaa片| 人人狠狠综合久久88成人| 9久久9久久精品| 99久久99久久精品国产片果冻| 久久免费小视频| 欧美伊人久久大香线蕉综合69| 精品久久久久久无码不卡| 丰满少妇高潮惨叫久久久| 91视频国产91久久久| 国产精品九九久久免费视频| 免费一级做a爰片久久毛片潮| 国产精品久久婷婷六月丁香| jizzjizz国产精品久久| 国产激情久久久久影院| 狠狠色婷婷久久综合频道日韩| 中文字幕乱码久久午夜| 一本伊大人香蕉久久网手机| 色天使久久综合网天天 | 国产韩国精品一区二区三区久久| 中文精品久久久久国产网址| 久久婷婷五月综合色奶水99啪| 久久人人爽人人爽人人AV| 久久久久久亚洲精品无码| 久久精品国产亚洲AV高清热| 日产久久强奸免费的看|