1

AES暗号化で文字列を暗号化するプログラムを作ってみました。stackoverflow や他の多くのフォーラムを見た後、私はこれに行き着きました。しかし、コードにはいくつかの問題があります。

1.暗号化が機能しない場合があります(20回試行で2回失敗)。修正方法は?それはivecまたは多分textLengthに関連していますか?

2.暗号化と復号化の後、プライマリ文字列の最初の 16 文字しかありません。その後、ランダムな文字がいくつかあります。すべての文字列を解読することは可能ですか、それとも 16 文字に分割する必要がありますか?

3.いくつかの文字を融合する必要があるので、これを作成しました:

    char ivec[16];
    for(int i=0;i<16;i++)
    {
    ivec[i]=iveccreate[i];
    }

しかし、やはり char ivec[16] は 55 文字です。理由はありますか?

4. 関数 AES_cbc_encrypt の後、ivec がまったく異なる文字に変更されました。これを止める方法はありますか (コードのサイズを小さくしたい)?

1~4の質問にお答えいただけると大変助かります。

マカロール

PS:私はポーランド出身なので、英語はあまり得意ではありません。ごめん。

有効なコード:

#include <string.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <openssl/aes.h>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/rand.h>
using namespace std;

string AESencode(string Text,string Key);
void AESdecode(string in,string Key);
char *encode(unsigned char *input, int length);
char *decode(unsigned char *input,int lenght);

void main
{
string out=AESencode("String,which I want to encrypt.\0","encryptionkey");
AESdecode(out,"encryptionkey");
return 0;
}

string AESencode(string Text,string Key)
{
   //Creating 16 random ive
   srand((unsigned int) time(NULL));
   unsigned char ive[16];
   for(int i=0; i<16; i++){
   ive[i] = (unsigned char) rand();
   }

//I'm losing null by encode ive
char *iveccreate=encode(ive,16);

//Copying 16 first chars from iveccreate(16 random letters,numbers)
char ivec[16];
   for(int i=0;i<16;i++)
   {
   ivec[i]=iveccreate[i];
   }

//Saving ivec,because I need to fuse ivec with output later
//and after encode I lose orginal ivec
char* ivec1=decode((unsigned char*)iveccreate,strlen((const char*)iveccreate));

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

//If necessary adding null to the Key(full 32 bytes)
if(Klucz.length() < 32){
    Key.append(32 - Key.length(), '\0');
}

//Creating space for the output
unsigned char *aesoutput = new unsigned char[textLength];

//Create and set AESkey
AES_KEY *aesKey = new AES_KEY;
AES_set_encrypt_key((unsigned char*)Key.c_str(), 256, aesKey);

//Encrypting
AES_cbc_encrypt((unsigned char*)Text.c_str(), aesoutput, Text.length()+ 1, aesKey, (unsigned char*)ivec, AES_ENCRYPT);

//Fusing ivec with aesoutput
char wyjsciowy[strlen((const char*)Wyjscie)+16];
    for(int i=0;i<16;i++){
        fuse[i]=ivec1[i];
    }
    for(int i=0;i<strlen((const char*)Wyjscie);i++)        {
        fuse[i+16]=aesouput[i];
    }

//Encode the fuse
char* out=encode((unsigned char*)wyjsciowy,strlen(wyjsciowy));

//Saving chars to string
string mychar((char*)out);

//Creating normal string from the base64 encode output
//String is 65 chars, new line, 65 chars
//so I'm looking for the number of not 65, ending chars of the string
int res=mychar.length()%65;

string allstr;
//Fuse strings without new line charater
for(int i=0;i<(mychar.length()-res);i+=65)
{
    allstr+=mychar.substr(i,64);
}

//Fuse string with the ending string.If res==0 it will add nothing.
allstr+=mychar.substr((mychar.length()-res),res);

//Returnig string
return allstr;
}

//Base64 encode function
char *encode(unsigned char *input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length+1);
memcpy(buff, bptr->data, bptr->length);
buff[bptr->length] = 0;
BIO_free_all(b64);
return buff;
}

//Base64 decode function
char *decode(unsigned char *input, int length)
{
BIO *b64, *bmem;
char *buffer = (char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}


void AESdecode(string in,string Key)
{
    //Decode the input string with Base64
    char* dec=decode((unsigned char*)in.c_str(),in.length());

    //Getting ivec
    unsigned char ivec[16];
    {

        //Getting first 16 bytes from dec
        unsigned char preivec[16];
        for(int i=0;i<16; i++){
            preivec[i] = dec[i];
        }

        //Encode these 16 bytes
        char *ppiv=encode(preivec,16);

        //Now we have 25 chars text
        //And ivec is only fist 16
        for(int i=0;i<25; i++){
            ivec[i] = ppiv[i];
        }
    }

    //Getting aesouput bytes
    char data[strlen(dec)-16];
    for(int i=16;i<(strlen(dec));i++){
        data[i-16]=dec[i];
    }

   //If necessary adding null to the Key(full 32 bytes)
    if(Key.length()< 32){
        Key.append(32-Key.length(),'\0');
    }   

    //Creating space for the output
    unsigned char *output = new unsigned char[strlen(data)];

    //Create and set new AESkey
    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

    //Deccrypting
    AES_cbc_encrypt((unsigned char*)data, output, strlen(data), aesKey,ivec, AES_DECRYPT);

    //And there should be full primary string
    cout<<"OUTPUT: "<<output<<endl;
   }
4

1 に答える 1

0

AES キーは、可変長の文字列ではなく、固定長のバイト配列です。AES_set_decrypt_key() を呼び出すと、13 文字の長さの文字列が渡され、null バイトが追加されるため、14 バイトが既知です。次に、関数は (32-14) -> 残りの 18 バイトをキーに使用します。この 18 バイトの内容は、ほとんどが運の結果です

これはあなたの問題だと思います。

于 2013-02-16T22:37:43.343 に答える