Domanda

Ero annoiato e ha scritto un wrapper di openSSL per eseguire la crittografia AES con meno lavoro.Se faccio così:http://pastebin.com/V1eqz4jp (ivec = 0)
Tutto funziona bene, ma il default ivec è tutto a 0, che ha alcuni problemi di sicurezza.Dal momento che sto passando i dati come una stringa in ogni caso, ho capito, perché non generare un casuale ivec e lo stick per il fronte, il prendere di nuovo fuori quando ho decifrare la stringa?Per qualche motivo non funziona però.

Beh, in effetti, funziona quasi.Sembra di decifrare il centro della corda, ma non l'inizio o alla fine:

String is: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF
Encrypting..
���l%%1u���B!
�����`pN)�ɶ���[l�ӏ��{�Q�?�2�/�HԵ�y"�=Z�Cu����l%%1u���B!

Decrypting..
String is: �%���G*�5J�0��0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF

Onestamente non ho idea di che cosa sta andando male.Forse qualche errore stupido, o forse mi manca qualcosa AES?

Ecco il codice:(A cura di incorporare Steve Jessop la soluzione al mio primo problema)

/*!
 * Simple AES
 * Brendan Long
 * March 29, 2010
 * 
 * Simplified encryption and decryption using OpenSSL's AES library.
 * Remember to compile with -lcrypto and link against the library
 * g++ (your stuff) -lcrypto simpleAes.cpp (or simpleAes.o)
 *
 * Implementation note: Using the default ivec (0) is not secure. For
 *                      the full security that AES offers, use a different
 *                      ivec each time (it does not need to be secret,
 *                      just different.
 *
 * This code is released into the public domain. Yada yada..
 * Read this for details: http://creativecommons.org/licenses/publicdomain/
 *
 * If for some reason public domain isn't good enough, you may use, alter,
 * distribute or do anything else you want with this code with no restrictions.
 */

#include <openssl/aes.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>

bool seed = true;

/*!
 * Encrypts a string using AES with a 256 bit key
 * Note: If the key is less than 32 bytes, it will be null padded.
 *       If the key is greater than 32 bytes, it will be truncated
 * \param in The string to encrypt
 * \param key The key to encrypt with
 * \return The encrypted data
 */
std::string aes_encrypt(std::string in, std::string key){

    // Seed the random number generator once
    if(seed){
        srand( (unsigned int) time(NULL));
        seed = false;
    }

    // Generate a random ivec
    unsigned char ivec[16];
    for(int i=0; i<16; i++){
        ivec[i] = (unsigned char) rand();
    }

     // Round up to AES_BLOCK_SIZE
    size_t textLength = ((in.length() / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;

    // Always pad the key to 32 bits.. because we can
    if(key.length() < 32){
        key.append(32 - key.length(), '\0');
    }

    // Get some space ready for the output
    unsigned char *output = new unsigned char[textLength];

    // Generate a key
    AES_KEY *aesKey = new AES_KEY;
    AES_set_encrypt_key((unsigned char*)key.c_str(), 256, aesKey);

    // Encrypt the data
    AES_cbc_encrypt((unsigned char*)in.c_str(), output, in.length() + 1, aesKey, ivec, AES_ENCRYPT);

    // Make the data into a string
    std::string ret((char*) output, textLength);

    // Add the ivec to the front
    ret = std::string((char*)ivec, 16) + ret;

    // Clean up
    delete output;
    delete aesKey;

    return ret;
}

/*!
 * Decrypts a string using AES with a 256 bit key
 * Note: If the key is less than 32 bytes, it will be null padded.
 *       If the key is greater than 32 bytes, it will be truncated
 * \param in The string to decrypt
 * \param key The key to decrypt with
 * \return The decrypted data
 */
std::string aes_decrypt(std::string in, std::string key){

    // Get the ivec from the front
    unsigned char ivec[16];
    for(int i=0;i<16; i++){
        ivec[i] = in[i];
    }

    in = in.substr(16);

    // Always pad the key to 32 bits.. because we can
    if(key.length() < 32){
        key.append(32 - key.length(), '\0');
    }

    // Create some space for output
    unsigned char *output = new unsigned char[in.length()]; 

    // Generate a key
    AES_KEY *aesKey = new AES_KEY;
    AES_set_decrypt_key((unsigned char*)key.c_str(), 256, aesKey); // key length is in bits, so 32 * 8 = 256

    // Decrypt the data
    AES_cbc_encrypt((unsigned char*)in.c_str(), output, in.length(), aesKey, ivec, AES_DECRYPT);

    // Make the output into a string
    std::string ret((char*) output);

    // Clean up
    delete output;
    delete aesKey;

    return ret;
}
È stato utile?

Soluzione 3

Un mio amico ha capito il problema.Io sto facendo questo:

  1. Generare un numero casuale e conservarla in ivec
  2. Crittografare i dati con ivec
  3. Aggiungere ivec all'inizio di dati di output

Il problema è che il passo 2 cambia il contenuto di ivec.Ero praticamente memorizzazione di numeri casuali all'inizio della mia stringa.La soluzione è stata quella di aggiungere questo:

unsigned char ivec[16];
// set ivec to random numbers
std::string ivecString((char*) ivec, 16);
// encrypt data
return ivecString + encryptedData;

Altri suggerimenti

Si dovrebbe salvare l'Ivec [16] in 'uscita' prima della cifratura. Questo è tutto ...

Vorrei anche aggiungere che sarà molto più semplice lavorare con char * invece di stringa.

Questa linea è sbagliata:

std::string ret((char*) output);

I dati decriptati non ha un terminatore nul, dal momento che sono stati crittografati byte in.length(). Questo spiega la spazzatura alla fine, ma non la spazzatura all'inizio. Ci possono essere altri problemi.

In generale, non si può trattare l'uscita dello stadio di cifratura come una stringa, a meno che non si esegue un ulteriore passo, come ad esempio Base 64 codifica l'uscita. Ogni byte di uscita potrebbe essere un nul.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top