IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Je recherche un algorithme de chiffrement AES 128 bits en c++.


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Je recherche un algorithme de chiffrement AES 128 bits en c++.
    Salut!

    Je suis à la recherche d'un algorithme de chiffrement AES de 128 bits en c++.

    J'ai essayer ceci :

    Le .h

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
     
    #ifndef AES_ENC_H
    #define AES_ENC_H
    #include <iostream>
    #include <openssl/evp.h>
    #include <openssl/err.h>
    #include <ctime>
    #include <openssl/rand.h>
    #include <openssl/aes.h>
    #include "../Core/utilities.h"
    #include "../Math/maths.h"
    #include "export.hpp"
    #include <string.h>
    #include <stdlib.h>
    #include "bigInt.hpp"
    #include <array>
    #include <memory>
    /**
      *\namespace odfaeg
      * the namespace of the Opensource Development Framework Adapted for Every Games.
      */
    namespace odfaeg {
        namespace network {
            /**
              * \file aes.h
              * \class AES_ENC
              * \brief Perform symetric encryptions with the aes algorithm.
              * \author Duroisin.L
              * \version 1.0
              * \date 1/02/2014
              *
              */
            class ODFAEG_NETWORK_API AES_ENC {
            public:
                struct AESWord128 {
                    AESWord128() {
                        byte1 = byte2 = byte3 = byte4 = 0;
                    }
                    AESWord128 (unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4) : byte1(b1), byte2(b2), byte3(b3), byte4(b4) {
     
                    }
                    AESWord128 rotWord() {
                        AESWord128 out (byte4, byte3, byte2, byte1);
                        return out;
                    }
                    AESWord128 operator^(const AESWord128& w) {
                        AESWord128 out(byte1 ^ w.byte1, byte2 ^ w.byte2, byte3 ^ w.byte3, byte4 ^ w.byte4);
                        return out;
                    }
                    unsigned char byte1, byte2, byte3, byte4;
                };
     
                AES_ENC() {
                    ossl_key = new unsigned char[32];
                    iv = new unsigned char[32];
                    aesSalt = new unsigned char[8];
                    e_ctx = new EVP_CIPHER_CTX;
                    d_ctx = new EVP_CIPHER_CTX;
                    aesPass = ossl_generateKey(256);
                    generateKey();
                }
                /**
                * \fn unisgned char encrypt(const unsigned char* data, int dataSize, int* newSize)
                * \brief encrypt the data.
                * \param data : the data to encrypt.
                * \param dataSize : the size of the data to encrypt.
                * \param newSize : the size of the encrypted data.
                * \return the encrypted data.
                */
                unsigned char* ossl_encrypt(const unsigned char* data, int dataSize, int* newSize);
                /**
                * \fn unsigned char* decrypt(const unsigned char* encData, int dataSize, int* newSize)
                * \brief decrypt the data.
                * \param encData : the encrypted data.
                * \param dataSize : the size of the encrypted data.
                * \param newSize : the size of the data.
                * \return the data.
                */
                unsigned char* ossl_decrypt(const unsigned char* encData, int dataSize, int* newSize);
                /**
                * \fn char* getKey()
                * \brief get the key used to hash the aes key.
                * \return the key.
                */
                char* ossl_getKey ();
                /**
                * \fn char* getIv()
                * \brief get the iv used to hash the key.
                * \return the iv.
                */
                char* ossl_getIv();
                /**
                * \fn void setKey (char* key);
                * \brief set the key used to hash the aes key.
                * \param key : the key.
                */
                void ossl_setKey (char* key);
                /**
                * \fn void setIv (char* iv);
                * \brief set the iv used to hash the key.
                * \param iv : the iv.
                */
                void ossl_setIv (char* iv);
                unsigned char* encrypt(const unsigned char* mess, std::size_t dataSize, std::size_t& newSize);
                unsigned char* decrypt(const unsigned char* mess, size_t dataSize, size_t& newSize);
                ~AES_ENC() {
                    delete[] ossl_key;
                    delete[] iv;
                    delete[] aesSalt;
                    delete[] aesPass;
                    EVP_CIPHER_CTX_cleanup(d_ctx);
                    EVP_CIPHER_CTX_cleanup(e_ctx);
                    delete e_ctx;
                    delete d_ctx;
                }
            private:
                /**
                * \fn unsigned char* generateKey(int length)
                * \brief generate an aes key with the given length.
                * \param the length of the key.
                * \return the pass used to hash the key.
                */
                unsigned char* ossl_generateKey(int length) {
                    size = length;
                    aesPass = new unsigned char[size / 8];
                    if (RAND_bytes(aesPass, size / 8) == 0)
                        std::cerr<<"fail to generate aes pass"<<std::endl;
                    int nrounds = 5;
                    if (RAND_bytes(aesSalt, 8) == 0)
                        std::cerr<<"fail to generate random salt"<<std::endl;
                    /*
     
                    * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the 			* supplied key material.
                    * nrounds is the number of times the we hash the material. More rounds 			* are more secure but
                    * slower.
                    */
                    if (EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), aesSalt, aesPass, 			    size / 8, nrounds, ossl_key, iv) == 0)
                        std::cerr<<"Failed to hash the aes key."<<std::endl;
                    EVP_CIPHER_CTX_init(e_ctx);
                    //EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
                    EVP_CIPHER_CTX_init(d_ctx);
                    //EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
                    return aesPass;
                }
            private :
                void generateKey();
                std::array<std::array<int, 4>, 4> encryptBloc(std::array<std::array<int, 4>, 4> matrix);
                std::array<std::array<int, 4>, 4> decryptBloc(std::array<std::array<int, 4>, 4> matrix);
                std::array<std::array<int, 4>, 4> addRoundKey(std::array<std::array<int, 4>, 4> in, std::array<int, 16> key);
                std::array<int, 176>  keyExpansion(std::array<int, 16> k);
                std::array<int, 16>  getRoundKey(int round);
                AESWord128 subWord(AESWord128 w);
                int size; /**> the size of the key.*/
                std::string aes_key; /**> the aes key.*/
                unsigned char *ossl_key, *iv, *aesSalt, *aesPass; /**> the key, the iv, the salt and the pass used to hash the aes key.*/
                EVP_CIPHER_CTX* e_ctx, *d_ctx; /**>The ciphers used to encrypt and decrypt the data. */
                const int nb = 4;    //Nombre de colonne (toujours 4 pour AES)
                const int nk = 4;    //Nombre de mot dans la clé (un mot = 4 octet) (4 pour AES-128)
                const int nr = 10;    //Nombre de tour de ronde (10 pour AES-128)
     
                std::array<int, 16> key;
                std::array<int, 176> expandKey;
                std::array<AESWord128, 16> rCon;
                std::array<std::array<int, 4>, 4> subBytes(std::array<std::array<int, 4>, 4> in);
                std::array<std::array<int, 4>, 4> shiftRows(std::array<std::array<int, 4>, 4> in);
                std::array<std::array<int, 4>, 4> mixColumns(std::array<std::array<int, 4>, 4> out);
                std::array<std::array<int, 4>, 4> invSubBytes(std::array<std::array<int, 4>, 4> in);
                std::array<std::array<int, 4>, 4> invShiftRows(std::array<std::array<int, 4>, 4> in);
                std::array<std::array<int, 4>, 4> invMixColumns(std::array<std::array<int, 4>, 4> in);
                int xtime(int x);
                int x_time(int x, int y);
                int gf2Mult (int x, int y);
                void addTab(unsigned char in[], std::array<std::array<int, 4>, 4> add, int pos);
                std::array<unsigned char, 4> intToBytes(int i);
                int bytesToInt(std::array<unsigned char, 4> b);
                //La boite-S pour l'operation SubBytes
                static const int sBox[256];
                // la boite-S pour l'operation InvSubBytes
                static const int invSBox[256];
            };
        }
    }
    #endif // AES_ENC

    Le .cpp

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
     
    #include "../../../include/odfaeg/Network/aes.h"
    namespace odfaeg {
        namespace network {
            const int AES_ENC::sBox[] = {
                    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE,
                    0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4,
                    0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7,
                    0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3,
                    0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09,
                    0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3,
                    0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE,
                    0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
                    0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92,
                    0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C,
                    0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19,
                    0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
                    0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2,
                    0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5,
                    0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25,
                    0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
                    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86,
                    0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E,
                    0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42,
                    0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
                };
            const int AES_ENC::invSBox[] = {
                    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81,
                    0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E,
                    0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23,
                    0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66,
                    0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72,
                    0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65,
                    0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46,
                    0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
                    0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA,
                    0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91,
                    0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6,
                    0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
                    0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F,
                    0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2,
                    0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8,
                    0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
                    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93,
                    0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB,
                    0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6,
                    0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
                };
            using namespace std;
            unsigned char* AES_ENC::ossl_encrypt(const unsigned char* data, int dataSize, int* newSize) {
                int cLen = dataSize+AES_BLOCK_SIZE;
                int fLen = 0;
                unsigned char *encData = new unsigned char[cLen];
                if (!EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), nullptr, ossl_key, iv))
                    return nullptr;
                if (!EVP_EncryptUpdate(e_ctx, encData, &cLen, data, dataSize))
                    return nullptr;
                if(!EVP_EncryptFinal_ex(e_ctx, encData+cLen, &fLen)) {
                    return nullptr;
                }
                *newSize = cLen + fLen;
     
                return encData;
            }
            unsigned char* AES_ENC::ossl_decrypt(const unsigned char* encData, int dataSize, int* newSize) {
                int pLen = dataSize;
                int fLen = 0;
                unsigned char *data = new unsigned char[pLen];
                if (!EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), nullptr, ossl_key, iv))
                    return nullptr;
                if (!EVP_DecryptUpdate(d_ctx, data, &pLen, encData, dataSize))
                    return nullptr;
     
                if (!EVP_DecryptFinal_ex(d_ctx, data+pLen, &fLen)) {
                    char* err = (char*) malloc(130);
                    ERR_load_crypto_strings();
                    ERR_error_string(ERR_get_error(), err);
                    fprintf(stderr, "Error encrypting message: %s\n", err);
                    free(err);
                }
                *newSize = pLen + fLen;
                return data;
            }
            void AES_ENC::ossl_setKey(char* sKey) {
               ossl_key = new unsigned char[size / 8];
               memcpy(ossl_key, (unsigned char*) sKey, strlen(sKey));
               //key[strlen(sKey) +  1] = '\0';
            }
            void AES_ENC::ossl_setIv(char* sIv) {
               iv = new unsigned char[size / 8];
               memcpy(iv, (unsigned char*) sIv, strlen(sIv));
               //iv[strlen(sIv) +  1] = '\0';
            }
            char* AES_ENC::ossl_getKey() {
               return (char*) ossl_key;
            }
            char* AES_ENC::ossl_getIv() {
               return (char*) iv;
            }
            void AES_ENC::generateKey() {
                BigInt k = BigInt::genRandom(64, 16);
                string s = k.toStr(16);
                for (unsigned int i = 0; i < nk * 4; i++) {
                    BigInt n (s.substr(i, 1), 16);
                    key[i] = core::conversionStringInt(n.toStr(10));
                }
                rCon[1] = AESWord128(1, 0, 0, 0);
                for (int i = 2; i < 15; i++) {
                    rCon[i] = AESWord128(gf2Mult(2,rCon[i-1].byte1),0,0,0);
                }
                expandKey = keyExpansion(key);
            }
            /**
             * Permet de chiffrer une suite de bytes
             */
            unsigned char* AES_ENC::encrypt(const unsigned char* mess, size_t dataSize, size_t& newSize) {
                array<array<int, 4>, 4> tmpbloc;
                int i = 0, j = 0;
                array<unsigned char, 4> tmpSize;
                newSize = ((dataSize/16)*16)+32;
                unsigned char* res = new unsigned char[newSize];
     
                //J'ai choisi d'ajouter un bloc contenant la taille du message d'origine car
                //une fois chiffrer le message est de taille multiple a 16 donc il faudra la taille d'origine
                //pour dechiffrer
                tmpSize = intToBytes(dataSize);
                tmpbloc[0][0] = tmpSize[0] + 128;
                tmpbloc[0][1] = tmpSize[1] + 128;
                tmpbloc[0][2] = tmpSize[2] + 128;
                tmpbloc[0][3] = tmpSize[3] + 128;
                for(i =4;i<16;i++)
                    tmpbloc[i/4][i%4] = 0;
     
                tmpbloc = encryptBloc(tmpbloc);
                i=0;
                addTab(res,tmpbloc,i);
     
                while (i<dataSize) {
                    //Creation du bloc de 16bytes à chiffrer
                    if (i+16<=dataSize){
                        for (j=0; j<16;j++){
                            tmpbloc[j/4][j%4] = mess[i+j] + 128;
                        }
                    }else{
                        j=0;
                        for (int k=i; k<dataSize;k++){
                            tmpbloc[j/4][j%4] = mess[k] + 128;
                            j++;
                        }
                        for (int k = j; k<16;k++)
                            tmpbloc[j/4][j%4] = 0;
                    }
     
                    //Chiffrement des données
                    tmpbloc = encryptBloc(tmpbloc);
     
                    //Ajout des données au tableau de resultat
                    addTab(res,tmpbloc,i+16);
     
                    i+=16;
                }
     
                return res;
            }
     
            /**
             * Permet de dechiffrer une suite de bytes
             */
            unsigned char* AES_ENC::decrypt(const unsigned char* mess, size_t dataSize, size_t& newSize) {
     
                array<unsigned char, 4> tmpSize;
                int pos = 0;
                array<array<int, 4>, 4> tmpbloc;
                for (int i=0;i<16;i++)
                    tmpbloc[i/4][i%4] = mess[i] + 128;
                tmpbloc = decryptBloc(tmpbloc);
     
                tmpSize[0] = (unsigned char)(tmpbloc[0][0] - 128);
                tmpSize[1] = (unsigned char)(tmpbloc[0][1] - 128);
                tmpSize[2] = (unsigned char)(tmpbloc[0][2] - 128);
                tmpSize[3] = (unsigned char)(tmpbloc[0][3] - 128);
                for (unsigned int i = 0; i < 4; i++)
                    std::cout<<(int) tmpSize[i]<<std::endl;
                newSize = bytesToInt(tmpSize);
                std::cout<<newSize<<std::endl;
                unsigned char* res = new unsigned char [newSize];
                int i = 16;
                while (i<dataSize){
                    for (int j=0;j<16;j++)
                        tmpbloc[j/4][j%4] = mess[i+j] + 128;
     
                    tmpbloc = decryptBloc(tmpbloc);
                    addTab(res,tmpbloc,pos);
                    pos+=16;
                    i += 16;
                }
     
                return res;
            }
     
            /**
             * Chiffre un bloc 16 bytes rangés dans un tableau [4][4]
             */
            array<array<int, 4>, 4> AES_ENC::encryptBloc(array<array<int, 4>, 4> matrix){
     
                matrix = addRoundKey(matrix, getRoundKey(0));
     
                //Ronde AES
                for (int i=1; i<nr;i++){
                    matrix = subBytes(matrix);
                    matrix = shiftRows(matrix);
                    matrix = mixColumns(matrix);
                    matrix = addRoundKey(matrix, getRoundKey(i));
                }
                matrix = subBytes(matrix);
                matrix = shiftRows(matrix);
                matrix = addRoundKey(matrix, getRoundKey(nr));
                return matrix;
            }
     
            /**
             * Dechiffre un bloc
             */
            array<array<int, 4>, 4> AES_ENC::decryptBloc(array<array<int, 4>, 4> matrix){
                matrix = addRoundKey(matrix, getRoundKey(nr));
     
                //Ronde AES
                for (int i=nr-1; i>0; i--){
                    matrix = invShiftRows(matrix);
                    matrix = invSubBytes(matrix);
                    matrix = addRoundKey(matrix, getRoundKey(i));
                    matrix = invMixColumns(matrix);
                }
                matrix = invShiftRows(matrix);
                matrix = invSubBytes(matrix);
                matrix = addRoundKey(matrix, getRoundKey(0));
                return matrix;
            }
     
            /****************************************************************************************************************
            * Construction des clés de rondes
            ****************************************************************************************************************/
     
            /**
             * Applique un XOR sur chaque element de in par key
             * @param in    tableau 4x4 a traiter
             * @param key    cle de cryptage
             * @return        retourne un tableau 4x4
             */
            array<array<int, 4>, 4> AES_ENC::addRoundKey(array<array<int, 4>, 4> in, array<int, 16> key)
            {
                array<array<int, 4>, 4> out;
                int k =0, l=0;
     
                for (int i=0;i< (4*nk);i++)
                {
                    k = i/4 % 4;
                    l = i % 4;
                    out[k][l] = in[k][l] ^ key[i];
                }
     
                return out;
            }
     
            /**
             * Procede à la generation des clés de rondes
             */
            array<int, 176> AES_ENC::keyExpansion(array<int, 16> k)
            {
                AESWord128 tmp;
                array<AESWord128, 176> w;
     
                int t = 0, i = 0;
                array<int, 176> result;
     
                for (i=0; i< nk; i++)
                {
                    w[i] = AESWord128(k[t],k[t+1],k[t+2],k[t+3]);
                    t += 4;
                }
     
                for(i=nk; i < (nb * (nr +1)); i++ )
                {
                    tmp = AESWord128(w[i-1]);
     
                    if ((i % nk) == 0){
                        tmp = AESWord128((subWord(tmp.rotWord()))^(rCon[i / nk]));
                    }else if((nk > 6) && (i % nk ==4)){
                        tmp = AESWord128(subWord(tmp));
                    }
     
                    w[i] = AESWord128(w[i - nk]^(tmp));
                }
     
                t = 0;
                i = 0;
     
                while ( i < (nk * (nr+1)))
                {
                    result[t] = w[i].byte1;
                    result[t+1] = w[i].byte2;
                    result[t+2] = w[i].byte3;
                    result[t+3] = w[i].byte4;
                    i++;
                    t+=4;
                }
                return result;
            }
     
            /**
             * Retourne la clé de ronde de la ronde round
             * @round
             */
            array<int, 16> AES_ENC::getRoundKey(int round)
            {
                array<int, 16> out;
                int t= 0;
                for (int i=(round*4*nk); i < (round*4*nk)+(4*nk); i++){
                    out[t] = expandKey[i];
                    t++;
                }
     
                return out;
     
            }
            /**
             * Application de la sBox a un mot AES de clé de ronde
             * @param w
             * @return
             */
            AES_ENC::AESWord128 AES_ENC::subWord(AESWord128 w)
            {
                AESWord128 out (sBox[w.byte1],sBox[w.byte2],sBox[w.byte3],sBox[w.byte4]);
                return out;
            }
     
            /**
             * Operation SubBytes, transforme les octet de in par la S-Box
             * @param in    tableau 4x4 representant les donnees sur lesquelles ont dois effectuer une substitution
             * @return        retourne un tableau 4x4 ou les octets sont substitues
             */
            array<array<int, 4>, 4> AES_ENC::subBytes(array<array<int, 4>, 4> in)
            {
                array<array<int, 4>, 4> out;
     
                for (int i = 0; i<4;i++){
                    for (int j=0;j<4;j++){
                        out[i][j]= sBox[in[i][j]];
                    }
                }
     
                return out;
            }
     
            /**
             * Applique un decalage a gauche circulaire
             * @param in    matrice4x4 de donnees a applique le decalage circulaire e gauche
             * @return        retourne un tableau 4x4 sur lequel un decalage cirulaire e etait effectue
             */
            array<array<int, 4>, 4> AES_ENC::shiftRows(array<array<int, 4>, 4> in)
            {
                array<array<int, 4>, 4> out;
     
                for (int i=0;i<4;i++){
                    out[0][i]=in[0][i];
                }
     
                out[1][0] = in[1][1];
                out[1][1] = in[1][2];
                out[1][2] = in[1][3];
                out[1][3] = in[1][0];
     
                out[2][0] = in[2][2];
                out[2][1] = in[2][3];
                out[2][2] = in[2][0];
                out[2][3] = in[2][1];
     
                out[3][0] = in[3][3];
                out[3][1] = in[3][0];
                out[3][2] = in[3][1];
                out[3][3] = in[3][2];
     
                return out;
     
            }
     
            /**
             * Traite les colonnes commes des polynomes de degres n et applique un produit matriciel sur chaque element
             * @param in
             * @return
             */
            array<array<int, 4>, 4> AES_ENC::mixColumns(array<array<int, 4>, 4> in)
            {
                array<array<int, 4>, 4> out;
                array<int, 4> sp;
     
                   for (int c = 0; c < 4; c++) {
                      sp[0] = (gf2Mult(0x02, in[0][c])) ^ (gf2Mult(0x03, in[1][c])) ^ in[2][c] ^ in[3][c];
                      sp[1] = in[0][c] ^ (gf2Mult(0x02, in[1][c])) ^ (gf2Mult(0x03, in[2][c])) ^ in[3][c];
                      sp[2] = in[0][c] ^ in[1][c] ^ (gf2Mult(0x02, in[2][c])) ^ (gf2Mult(0x03, in[3][c]));
                      sp[3] = (gf2Mult(0x03, in[0][c])) ^ in[1][c] ^ in[2][c] ^ (gf2Mult(0x02, in[3][c]));
                      for (int i = 0; i < 4; i++) out[i][c] = sp[i];
                   }
     
                return out;
            }
     
        /****************************************************************************************************************
         * Procédure de déchiffrement
         ****************************************************************************************************************/
     
            /**
             * Operation inverse de SuBytes
             * @param in    donnees e deSubytes
             * @return        retourne un tableau 4x4 ou les donnees sont plus substitues par la S-Box
             */
            array<array<int, 4>, 4> AES_ENC::invSubBytes(array<array<int, 4>, 4> in)
            {
                array<array<int, 4>, 4> out;
     
                for (int i = 0; i<4;i++){
                    for (int j=0;j<4;j++){
                        out[i][j]= invSBox[in[i][j]];
                    }
                }
                return out;
            }
     
            /**
             * Inverse de ShiftRow, donc decalage a droite
             * @param in
             * @return
             */
            array<array<int, 4>, 4> AES_ENC::invShiftRows(array<array<int, 4>, 4> in){
                array<array<int, 4>, 4> out;
     
                for (int i=0;i<4;i++){
                    out[0][i]=in[0][i];
                }
     
                out[1][1] = in[1][0];
                out[1][2] = in[1][1];
                out[1][3] = in[1][2];
                out[1][0] = in[1][3];
     
                out[2][2] = in[2][0];
                out[2][3] = in[2][1];
                out[2][0] = in[2][2];
                out[2][1] = in[2][3];
     
                out[3][3] = in[3][0];
                out[3][0] = in[3][1];
                out[3][1] = in[3][2];
                out[3][2] = in[3][3];
     
                return out;
            }
     
            /**
             * Inverse de MixColumns
             * @param in
             * @return
             */
            array<array<int, 4>, 4> AES_ENC::invMixColumns(array<array<int, 4>, 4> in)
            {
               array<array<int, 4>, 4> out;
               array<int, 4> sp;
     
               for (int c = 0; c < 4; c++) {
                  sp[0] = (gf2Mult(0x0e, in[0][c])) ^ (gf2Mult(0x0b, in[1][c])) ^
                          (gf2Mult(0x0d, in[2][c])) ^ (gf2Mult(0x09, in[3][c]));
                  sp[1] = (gf2Mult(0x09, in[0][c])) ^ (gf2Mult(0x0e, in[1][c])) ^
                          (gf2Mult(0x0b, in[2][c])) ^ (gf2Mult(0x0d, in[3][c]));
                  sp[2] = (gf2Mult(0x0d, in[0][c])) ^ (gf2Mult(0x09, in[1][c])) ^
                          (gf2Mult(0x0e, in[2][c])) ^ (gf2Mult(0x0b, in[3][c]));
                  sp[3] = (gf2Mult(0x0b, in[0][c])) ^ (gf2Mult(0x0d, in[1][c])) ^
                          (gf2Mult(0x09, in[2][c])) ^ (gf2Mult(0x0e, in[3][c]));
                  for (int i = 0; i < 4; i++) out[i][c] = sp[i];
               }
     
     
               return out;
            }
            int AES_ENC::xtime(int x){
                x = x<<1;
                if (x >> 8 == 1)
                    x = (x ^ 0x1B) & 0xff;
                return x;
            }
            int AES_ENC::x_time(int x, int y){
                if (y !=0){
                    for (int i=0; i<y;i++)
                        x =  xtime(x);
                }else{
                    x =0;
                }
                return x;
            }
            int AES_ENC::gf2Mult(int x, int y) {
                int tmpres = 0;
                int res = 0;
                if (y >> 7 == 1) {
                    tmpres = x_time(x, 7);
                    res = tmpres;
                }
                for(unsigned int i=1;i<7;i++){            //On test tous les bits du 6eme au 2eme
                    if ((y<<24+i)>>31 == 1){
                        tmpres = x_time(x,7-i);
                        res = res^tmpres;
                    }
                }
                if ((y<<31)>>31 == 1)    //Si le premier bit est a 1
                    res = res^x;        //On Xor le resultat avec x
                return res;
            }
            void AES_ENC::addTab(unsigned char in[], std::array<std::array<int, 4>, 4> add, int pos){
                int t=0;
                for (int i=pos; i<pos+16;i++){
                    if (i < 4)
                        in[i] = (unsigned char)(add[t/4][t%4]-128);
                    t++;
                }
            }
            array<unsigned char, 4> AES_ENC::intToBytes(int i){
                array<unsigned char, 4> res;
                res[0] = (unsigned char)((i) >> 24);
                res[1] = (unsigned char)((i) >> 16);
                res[2] = (unsigned char)((i) >> 8);
                res[3] = (unsigned char)((i));
                return res;
            }
            /**
            * Convertit 4 bytes en l'entier correspondant
            */
            int AES_ENC::bytesToInt(array<unsigned char, 4> b){
                return  (b[0] & 0xFF) << 24 |
                        (b[1] & 0xFF) << 16 |
                        (b[2] & 0xFF) << 8 |
                        (b[3] & 0xFF);
            }
        }
    }

    Mais ça ne fonctionne pas car je ne retrouve pas le texte en clair que je chiffre :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int main() {
        std::string phrase = "Hello world!";
        network::AES_ENC aes;
        unsigned char* crypted = aes.encrypt(reinterpret_cast<const unsigned char*>(phrase.c_str()), phrase.length(), newSize);
        unsigned char* decrypted = aes.decrypt(crypted, newSize, newSize);
        std::string s (reinterpret_cast<const char*> (decrypted), newSize);
        std::cout<<"decrypted aes : "<<s<<std::endl;
        return 0;
    }

    Et je ne comprend absolument pas pourquoi ça ne fonctionne pas!
    Merci d'avance pour votre aide.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    second résultat google = http://stackoverflow.com/questions/2...-aes-using-c-c

    Partant de là, tu as déjà quinze solutions.

    D'un autre côté, tu passes par deux reinterpret_cast, pour changer le signe des caractères.
    C'est normal que ca ne fonctionne pas.

    L'interface de ton algorithme est mal pensée: on ne devrait pas avoir besoin d'un reinterpret_cast pour l'utiliser.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour étendre ce que dit leternel, je pense que tu devrais éviter de travailler directement sur des chaînes de caractères quand ton outil de cryptage est censé manipuler des données brutes.

    Je conseillerais de procéder par étapes et d'insérer explicitement une étape spécifique d'encodage de ta chaîne, qui convertit une std::string ou std::wstring en std::vector<unsigned char>:
    • string ou wstring en entrée
    • encodage -> vecteur de unsigned char
    • travailler exclusivement en unsigned char (tu dois chiffrer des bytes sans te soucier de ce qu'ils représentent) pour le chiffrement (pour bien faire, en entrée comme en sortie, tu devrais avoir un std::vector<unsigned char> -- Edit: Ou plutôt, en entrée, une paire d'itérateurs de unsigned char, mais bon...)
    • sauvegarde/affichage (via dump hexa+ascii) des données chiffrées
    • déchiffrement (pareil que pour chiffrement)
    • décodage pour obtenir ta chaîne de caractères.
    • Affichage de la chaîne.

    Rendre ces étapes permet non seulement de rendre la logique indépendante de celle-ci, mais aussi d'expliciter sous quel format tu veux que tes chaînes soient stockées (UTF-8 étant un bon candidat).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Ha, bon, j'utilise des reinterpret_cast pour le cryptage rsa et ça a toujours bien fonctionné comme cela.

    Je suis passé par openSSL au final, je pense que c'est plus simple.

    Au départ tout ce que j'ai c'est un pointeur sur void qui pointe vers un tableau de données de n'importe quel type. (char, int, etc...)

    Bref, tout est au final décomposés en un tableaux d'octets.

    Mais openSSL ne prend que des tableaux d'unsigned char* c'est d'ailleurs pour cela que je dois caster mes char* en unsigned char*.

    Tu me conseillerais de faire comment alors pour caster ça en unsigned char ?

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     const void* SymEncPacket::onSend (size_t& dataSize) {
                unsigned char* buffer;           
                buffer = aes.ossl_encrypt(reinterpret_cast<const unsigned char*> (getData()), getDataSize(), reinterpret_cast<int*>(&dataSize));           
                return &buffer[0];
            }
    void SymEncPacket::onReceive (const void* data, size_t dataSize) {
                unsigned char* buffer;
                std::size_t dstSize = 0;           
                buffer = aes.ossl_decrypt(reinterpret_cast<const unsigned char*> (data), dataSize, reinterpret_cast<int*>(&dstSize));          
                append(&buffer[0], dstSize);
            }

    Je ne comprend pas, il ne devrait pas y avoir de valeurs négatives pour une table ASCII.

    Donc logiquement une std::string ça devrait être un tableaux d'unsigned char.

    Que dois je faire pour caster ça correctement, faire une opération genre + 128 ?

    Donc -128 = -128 + 128 = 0.
    0 = 0 + 128 = 128.
    127 = 127 + 128 = 255.

    Il me semble que reinterpret_cast fait cela.
    Tandis que static_cast fait un autre genre de conversion mais le plus important c'est que dans ma méthode onReceive je retrouve les même données que dans la méthode onSend, le type de donnée que j'envoie n'a aucune importance.
    Dernière modification par Invité ; 18/07/2015 à 17h58.

  5. #5
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Salut, par défaut un char est signé, donc possède une range qui va de -128 à +127. Ceci a été fait car la table ASCII à l'origine n'avait besoin que de 7bit (128 caractères). Le char est aussi utilisé dans l'embarqué pour faire des calcul plus rapidement qu'avec des int.

    Donc si tu convertit un unsigned char* en char*, tu auras des soucis . C'est pourquoi, il faut toujours éviter les cast, plus tu les évites, plus tu auras un comportement correct .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En fait, un char est un unsigned char ou un signed char, au choix du compilateur.
    C'est même assez traitre.
    Un char doit pouvoir représenter la plage [0..127], tandis que les deux autres sont respectivement dans [0..255] et [-127..127].
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par leternel Voir le message
    En fait, un char est un unsigned char ou un signed char, au choix du compilateur.
    C'est même encore plus traitre que ça: Le char est signé ou non (gcc offre un paramètre de compilation pour ça) mais même quand char est signé, char et signed char restent deux types différents (j'ignore si c'est le cas aussi en C, vu qu'en C il n'y a pas de surcharge de fonctions pour tester Edit: Si j'en crois les warnings de gcc, c'est le cas en C également).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    http://www.open-std.org/JTC1/SC22/WG...docs/n1256.pdf

    §6.2.5/15
    The three types char, signed char,and unsigned char are collectively called the character types.
    The implementation shall define char to have the same range,representation, and behavior as either signed char or unsigned char.
    Donc un char n'est ni un unsigned char ni un signed char mais un mix des deux, peu importe le compilo, il doit juste prendre en compte la range [0-127].

    Ensuite il est aussi précisié:

    CHAR_MIN,defined in <limits.h>,will have one of the values 0 or SCHAR_MIN,and this can be used to distinguish the two options.
    Irrespective of the choice made,char is a separate type from the other two and is not compatible with either.
    Donc char* != signed char* != unsigned char*.

    Il ne faut pas les convertir ou les mélanger .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    blabla
    ps: Je ne connaissais pas cette option, y a-t-il un intérêt réel?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #10
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    L’intérêt est surtout en embarqué, ça permet d'avoir un type par default bien définis et ne pas avoir de surprise .

    Par exemple, dans les moteurs graphique en embarqué, on définit souvent le type char à unsigned char, ce qui permet de les utiliser pour le calcul des couleur, car un calcul sur un char est beaucoup plus rapide que sur un int . Et l'utilisation mémoire est plus faible aussi .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Visual C++ marche correctement en C++, mais par contre semble les considérer comme identiques en C:
    Déjà entre char const * et unsigned char const*, il faut monter le niveau de warning à 4 pour avoir le moindre avertissement. Et même au niveau 4, il n'y a aucun warning entre char const * et signed char const*.
    (tests réalisés sous les versions 2005 et 2010)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    VC++ est un compilateur C++, M$ ne garanti aucun standard C je crois, même pas le C89, je crois.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Je veux bien éviter la conversion mais je ne vois pas comment je pourrai l'éviter. :/

    Il m'arrive parfois d'avoir de mauvaise surprise à l’exécution comme par exemple un bad decrypt error.

    A cause du cast certainement mais les méthodes onSend et onReceive de la SFML ne me renvoie qu'un bête pointeur sur void*, il n'y a donc aucun type précis de données renvoyé par SFML, à la version précédente le type de donnée renvoyé par SFML était le type était char, ensuite il a changé en void* pour je ne sais pas quelle raison mais comment éviter le cast si openSSL attend un unsigned char* mais que SFML me renvoie un void*, ou alors je dois modifier le code de la SFML pour qu'elle me renvoie un unsigned char.

    Je ne sais pas de trop ce que vous en pensez, dois je avertir le webmaster de la SFML pour lui dire qu'il vaut mieux, changer de type pour éviter la conversion ?

    Bref, je trouve que Laurent devrait convertir ses int* en un tableau de unsigned char* plutôt que de faire un pointeur sur void*, m'aurai éviter de mauvaise surprise.

    Vivement le c++17 avec les std::socket!

  14. #14
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    OnSend et OnReceive sont en void* car la SFML n'a pas a savoir quel type de donnée tu échanges. Peu importe le type de donnée, ces méthode doivent envoyées des octet et te retourner des octet.
    Ensuite c'est à toi de savoir ce que tu envois et ce que tu reçois.
    Si tu envois du char* alors tu cast en char*
    Si tu envois du unsigned char* tu cast en unsigned char*.
    Si tu envois du struct toto*, tu cast en struct toto*.

    C'est le fonctionnement de base d'un échange client/serveur en donnée binaire (ou protocole maison, mais pas à base de string).

    Donc c'est à toi, dans ton code, de caster comme il le faut. Je suppose que ça ne te viendrais jamais à l'idée de caster du struct toto* en char*, bah là c'est le même principe avec du char* ou du unsigned char*.

    Une fois de plus, tu remets en cause le code SFML et non pas ton propre code .....
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  15. #15
    Invité
    Invité(e)
    Par défaut
    Bah alors c'est bon ce que j'ai fais, j'ai bien casté du void* en unsigned char* car si j'envoie du unsigned char*, je reçois du unsigned char* également.

  16. #16
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    dans ce bout de code que tu mets au début du post:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main() {
        std::string phrase = "Hello world!";
        network::AES_ENC aes;
        unsigned char* crypted = aes.encrypt(reinterpret_cast<const unsigned char*>(phrase.c_str()), phrase.length(), newSize);
        unsigned char* decrypted = aes.decrypt(crypted, newSize, newSize);
        std::string s (reinterpret_cast<const char*> (decrypted), newSize);
        std::cout<<"decrypted aes : "<<s<<std::endl;
        return 0;
    }
    La ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::string s (reinterpret_cast<const char*> (decrypted), newSize);
    decrypted est au format unsigned et tu le cast en char .....
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  17. #17
    Invité
    Invité(e)
    Par défaut
    Oui mais je ne fais plus cela, j'ai changé de méthode depuis.

    Par contre, je ne sais pas comment SFML fais pour transformer ses chaînes de caractères en octets. (Avec l'opérateur << de la classe sf:acket)

    Est ce que il les transformes en char ou en unsigned char ?

    Le principal soucis comme je l'ai déjà dis c'est que c_str() renvoie un tableau de char, mais que openssl attend un tableau d'unsigned char.

    Comment faire dans ce cas pour passer d'un tableau de char en un tableau d'octets ?

  18. #18
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    C'est parce que tu ne dois pas chiffrer une chaine de caractère, mais une suite d'octets. Point. C'est tout.

    On ne chiffre pas un texte. Ca n'a pas de sens.
    C'est une séquence de nombres (en l'occurence, dont les valeurs sont entre 0 et 255) que l'on sait chiffrer, via des opérations mathématiques comme la somme, le produit par une puissance de 2 et le xor bit-à-bit.
    Ainsi, d'ailleurs, qu'une somme cumulative des blocs successifs.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  19. #19
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Tu t'y prend pas de la bonne manière sur la communication réseau.

    Premier principe:
    En chiffrement ou non, quand on communique en binaire on utilise une structure de paquet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Paquet
    {
      int size;
      void* buffer;
    }
    Ensuite on a une fonction d'envoi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void envoi(Paquet* pqt)
    {
      send(pqt->size, sizeof(pqt->size));
      send(pqt->buffer, pqt->size);
    }
    Une fonction de reception:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Paquet* reception()
    {
      Paquet* pqt = new paquet();
      read(pqt->size, sizeof(pqt->size);
      pqt->buffer = malloc(pqt->size);
      read(pqt->buffer, pqt->size);
      return (pqt);
    }
    Une fonction de chiffrement qui s'occupera de la transformation pour le protocole en même temps (je ne maitrise pas l'appel à ossl_encrypt donc à toi de modifier mon code) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Paquet* chiffrement(void* donnee, int size)
    {
      Paquet *pqt = new Paquet();
      pqt->buffer = ossl_encrypt(donnee, size, pqt->size);
      return (pqt);
    }
    Une fonction qui déchiffrera:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void* dechiffrement(Paquet* pqt)
    {
      void* donnee = decrypt(pqt->buffer, pqt->size, newsize);
      return (donnee);
    }
    Et ton code principale client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class *donneeClient = ......;
    .......
    Paquet* donneeAEnvoyer = chiffrement(donneeclient, donneeclient->getSize());
    envoi(donneeAEnvoyer);
    code principal serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class *donneeRecu;
    Paquet* pqt = reception();
    donneeRecu = reinterpret_cast<class*>dechiffrement(pqt);
    Tu remarquera qu'il n'y a donc qu'un seul cast, qui est obligatoire pour récupérer les données.
    Le reste fonctionne en void* car on a pas besoin de connaitre les données échangées.

    Il y a certainement des choses à modifier, mais le but était de te montrer le principe:
    Client:donnée compréhensible->transformation protocole->chiffrement->envois.
    Serveur:réception->déchiffrement->transformation protocole->donnée compréhensible.

    Le fonctionnement est le même lorsque tu utilise une sérialisation (une sérialisation d'une classe en string pour l'envoyé via le réseau est du chiffrement en quelque sorte, dans le sens ou les données sont modifié).
    Pour moi, le chiffrement est une sorte de sérialisation que seul le programme l'ayant créé puisse le lire.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    @skeud: Y'a rien qui te choque dans les deux premiers codes de ton message?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Déchiffrement AES 128 bits
    Par Happpy dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 05/03/2014, 00h27
  2. Exemple de chiffrement-déchiffrement 128 bits
    Par n5Rzn1D9dC dans le forum Contribuez
    Réponses: 1
    Dernier message: 16/11/2013, 19h55
  3. Algorithme de chiffrement AES et DES (taille des messages)
    Par Mikediten dans le forum Mathématiques
    Réponses: 0
    Dernier message: 24/06/2009, 21h00
  4. AES 128 bits
    Par bibi-C-Moi dans le forum VHDL
    Réponses: 3
    Dernier message: 31/07/2007, 08h25
  5. AES 128 bits
    Par bibi-C-Moi dans le forum Composants
    Réponses: 3
    Dernier message: 31/07/2007, 08h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo