Meine AES-Verschlüsselung / Entschlüsselung Funktionen funktionieren nicht mit zufälligen ivecs

StackOverflow https://stackoverflow.com/questions/2541971

  •  23-09-2019
  •  | 
  •  

Frage

wurde mir langweilig und schrieb einen Wrapper um openSSL mit weniger Arbeit AES-Verschlüsselung zu tun. Wenn ich es wie folgt aus: http://pastebin.com/V1eqz4jp (ivec = 0)
Alles funktioniert gut, aber der Standard-ivec ist alle 0, die einige Sicherheitsprobleme hat. Da ich die Daten wieder als String sowieso bin vorbei, dachte ich, warum nicht eine zufällige ivec erzeugen und an der Front bleiben, nehmen die es wieder aus, wenn ich die Zeichenfolge zu entschlüsseln? Aus irgendeinem Grund ist es nicht funktioniert aber.

Nun, es funktioniert tatsächlich, fast. Es scheint in der Mitte der Zeichenfolge zu entschlüsseln, aber nicht der Anfang oder Ende :

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

Ich habe ehrlich gesagt keine Ahnung, was falsch gehen wird. Vielleicht ein dummer Fehler, oder vielleicht etwas über AES ich fehle?

Hier ist der Code: (Edited Steve Jessops Lösung für mein erstes Problem zu übernehmen)

/*!
 * 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;
}
War es hilfreich?

Lösung 3

Ein Freund von mir dachte, das Problem. Ich tue dies:

  1. Generieren Zufallszahl und speichern sie in ivec
  2. Verschlüsseln von Daten mit ivec
  3. Anfügen ivec von Ausgangsdaten zu beginnen

Das Problem ist, dass Schritt 2 den Inhalt des ivec ändert. Ich war im Grunde Speicherung von Zufallszahlen am Anfang meiner Zeichenfolge. Die Lösung war dies hinzuzufügen:

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

Andere Tipps

Sie sollten die ivec speichern [16] in ‚Ausgang‘ Verschlüsselung VOR. Das ist es ...

Ich möchte auch hinzufügen, dass es mit char Arbeit viel einfacher sein wird * statt String.

Diese Zeile ist falsch:

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

Die entschlüsselten Daten hat keinen nul Terminator, da Sie in.length() Bytes verschlüsselt. Das erklärt den Müll am Ende, aber nicht den Müll am Anfang. Es können auch andere Probleme als gut.

In der Regel können Sie die Ausgabe der Verschlüsselungsstufe als String behandeln, es sei denn, Sie einen zusätzlichen Schritt, wie Basis ausführen 64 die Ausgabe codiert. Jeder Ausgabe-Byte könnte ein nul.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top