青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

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 閱讀(2944) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲高清资源综合久久精品| 午夜国产不卡在线观看视频| 亚洲三级毛片| 欧美激情欧美狂野欧美精品| 亚洲欧洲精品一区二区三区不卡| 99热免费精品| 国产精品久久久久久久午夜 | 日韩一二三区视频| 亚洲影视九九影院在线观看| 国产精品一二三视频| 久久精品水蜜桃av综合天堂| 欧美激情视频一区二区三区在线播放 | 国产精品xvideos88| 午夜精品一区二区三区在线| 老妇喷水一区二区三区| 亚洲美女少妇无套啪啪呻吟| 国产精品成人在线| 欧美诱惑福利视频| 亚洲国产视频a| 午夜免费电影一区在线观看| 亚洲电影在线观看| 欧美三级电影大全| 久久精品系列| 亚洲美女视频网| 久久久久久久成人| 9l国产精品久久久久麻豆| 国产老肥熟一区二区三区| 美国十次成人| 亚洲午夜视频在线观看| 免费美女久久99| 亚洲一区区二区| 伊人成人在线| 欧美特黄一级| 免费观看久久久4p| 亚洲欧美日韩第一区| 亚洲电影在线免费观看| 亚洲欧美一区二区原创| 亚洲国产天堂久久综合网| 国产精品久久久久一区二区三区共| 久久久久久高潮国产精品视| 亚洲天堂偷拍| 亚洲欧洲日产国码二区| 免费欧美高清视频| 久久精品成人一区二区三区蜜臀| 9i看片成人免费高清| 在线成人av.com| 国产午夜精品久久久久久免费视| 欧美日韩大片| 欧美国产一区二区三区激情无套| 欧美夜福利tv在线| 亚洲深夜av| 亚洲精品在线视频| 欧美激情在线播放| 老司机午夜精品视频在线观看| 亚洲欧美影音先锋| 亚洲视频碰碰| 99av国产精品欲麻豆| 亚洲激情另类| 国产精品乱码久久久久久| 午夜日韩视频| 一本色道久久综合| 亚洲国产一区二区三区高清| 老司机一区二区| 久久精品首页| 久久久亚洲国产美女国产盗摄| 亚洲一区二区少妇| 亚洲午夜伦理| 亚洲与欧洲av电影| 亚洲专区一区| 亚洲欧美日韩一区在线观看| 这里只有精品丝袜| 亚洲视频在线视频| 一区二区三区久久| 亚洲永久免费观看| 亚洲综合色网站| 午夜天堂精品久久久久| 午夜精品短视频| 香蕉国产精品偷在线观看不卡| 亚洲男人的天堂在线aⅴ视频| 亚洲一区www| 性欧美大战久久久久久久久| 欧美一区免费视频| 久久激情五月婷婷| 免费视频久久| 亚洲国产精品激情在线观看| 最新国产乱人伦偷精品免费网站| 亚洲精品国产视频| 中文在线资源观看视频网站免费不卡| 亚洲视频导航| 亚洲男同1069视频| 久久国产精品99精品国产| 久久精品国产综合精品| 六月婷婷一区| 欧美日韩成人综合在线一区二区| 国产精品ⅴa在线观看h| 国产麻豆精品theporn| 国内精品视频666| 亚洲国产日韩欧美在线动漫| 一区二区三区四区五区在线| 欧美在线关看| 欧美大片免费观看| 日韩视频在线一区| 亚洲自拍偷拍色片视频| 久久精品综合| 欧美日韩在线播放三区四区| 国产无一区二区| 亚洲精品孕妇| 欧美在线看片a免费观看| 免费视频一区| 亚洲另类春色国产| 欧美一区二区三区在| 麻豆免费精品视频| 国产精品一区二区三区四区 | 欧美精品1区2区3区| 国产精品video| 韩日视频一区| 亚洲视频精选在线| 久久影视精品| 99日韩精品| 久热精品视频在线| 国产精品毛片va一区二区三区| 精品成人在线观看| 亚洲在线观看视频| 欧美国产一区二区在线观看 | 玉米视频成人免费看| 亚洲手机成人高清视频| 久热精品在线| 亚洲在线视频| 欧美日韩一区二区三区在线观看免 | 久久狠狠婷婷| 亚洲老司机av| 蜜桃久久av一区| 国产亚洲精品美女| 亚洲午夜电影在线观看| 欧美成人网在线| 久久av资源网站| 国产精品视频福利| 一区二区三区毛片| 欧美激情久久久久久| 久久www成人_看片免费不卡| 国产精品久久久久久久浪潮网站 | 亚洲一区一卡| 亚洲黄色小视频| 久久夜色精品亚洲噜噜国产mv| 国产精品亚洲视频| 亚洲专区欧美专区| 亚洲免费观看视频| 欧美国产欧美亚洲国产日韩mv天天看完整| 国产婷婷色一区二区三区在线 | 亚洲免费电影在线| 欧美波霸影院| 亚洲国产精品日韩| 美国成人直播| 久久成人免费日本黄色| 国产专区欧美专区| 久久国产精品久久国产精品| 亚洲一级高清| 国产精品视频免费观看www| 亚洲制服av| 一区二区三区国产精品| 欧美日韩免费观看一区三区| 亚洲精品乱码久久久久久| 欧美国产视频在线| 欧美成人一二三| 99热这里只有精品8| 亚洲精品久久久久中文字幕欢迎你| 美女主播一区| 亚洲清纯自拍| 亚洲精品一区二区在线| 欧美日韩国产一区二区三区地区| 9国产精品视频| 99精品国产福利在线观看免费| 欧美日韩123| 亚洲主播在线观看| 亚洲欧美日韩一区二区| 国产亚洲欧美一级| 蜜臀av一级做a爰片久久| 美女亚洲精品| 日韩午夜av在线| 99精品欧美一区| 国产精品日韩久久久| 久久精品国产综合精品| 久久亚洲私人国产精品va媚药| 亚洲国产一二三| 亚洲精品影院| 国产精品美女一区二区在线观看| 欧美一级大片在线免费观看| 久久精品国产久精国产思思| 亚洲国产黄色| 亚洲毛片在线看| 国产精品一区二区久久久久| 蜜桃伊人久久| 欧美日韩另类字幕中文| 亚洲欧美中日韩| 久久色在线播放| 一本色道久久综合狠狠躁篇怎么玩| 亚洲性视频网站| 尤物网精品视频| 一本久久综合| 极品av少妇一区二区|