2010-08-03 9 views
2

사용자 입력 문자열을 암호화 (나중에 암호 해독)하는 프로그램을 만들고 싶습니다. 여기 는 암호화 시작 :QString/QChar을 Crypto ++로 변환 변환

QString getData = ui->text->toPlainText(); //Data to process 
std::string output; //Result will be Base32 encoded string, so std::string is fine. 

지금, 내가 그렇게 그것이 ++ 암호화로 받아 들여질 수 char* 또는 std::stringQString을 변환해야합니다. 나는 을 반환하는 .data() 함수를 가지고 있기 때문에 QByteArray이 괜찮을 것이라고 생각했습니다. (getData 항상 17 바이트 이상 : CryptoPP는 AES 암호화를 위해 최소 17 바이트 필요). 그래서, 내가 사용한 다음 코드 :

QByteArray data; 
data.append(getData); 

//Creating key and iv: 

//Creating AES encryptor: 

//Encrypting AES and Base32: 
CryptoPP::StringSource ss((const byte*)data.data(), data.size() , true, 
    new CryptoPP::StreamTransformationFilter(Encryptor, 
     new CryptoPP::Base32Encoder(
       new CryptoPP::StringSink(output) 
     ) // Base32Encoder 
    ) // StreamTransformationFilter 
); // StringSource 

ui->text->clear(); 
getData = output.c_str(); 
ui->text->setText(getData); 

모두가 잘 될 것 같다. 하지만 비 ASCII 문자 (러시아어, 리투아니아어 등)를 지원하고 싶습니다. 암호 해독 후 ?으로 변경됩니다. 어떻게 해결할 수 있을까요? 나는 그들이 std::string을 지원하지 않는다는 것을 이해합니다.


편집 : 여기에 업데이트됩니다 코드 :

암호화 :

QString getData = ui->text->toPlainText(); //Data to process 
std::string output; 

QByteArray data = getData.toUtf8(); 

//Creating key and iv: <..> 

//Creating AES encryptor: <..> 

//Encrypting AES and Base32: 
CryptoPP::StringSource ss((const byte*) data.data(),getData.size()*2, true, 
    new CryptoPP::StreamTransformationFilter(Encryptor, 
     new CryptoPP::Base32Encoder(
       new CryptoPP::StringSink(output) 
     ) // Base32Encoder 
    ) // StreamTransformationFilter 
); // StringSource 

ui->text->clear(); 
getData = output.c_str(); 
ui->text->setText(getData); 

및 암호 해독 :

QString getData = ui->text->toPlainText(); 
QByteArray data; 
data.append(getData); 
std::string output; 

//Creating key and iv: 
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], 
     iv[ CryptoPP::AES::BLOCKSIZE ]; 

//Memsetting them: (randomization needed) 
::memset(key, 0x01, CryptoPP::AES::DEFAULT_KEYLENGTH); 
::memset( iv, 0x01, CryptoPP::AES::BLOCKSIZE); 

//Creating AES decryptor: 
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor(key, sizeof(key), iv); 

//Decrypting Base32 and AES 
CryptoPP::StringSource ss((const byte*) data.data(), data.size(), true, 
    new CryptoPP::Base32Decoder(
     new CryptoPP::StreamTransformationFilter(Decryptor, 
      new CryptoPP::StringSink(output) 
     ) // StreamTransformationFilter 
    ) // Base32Encoder 
); // StringSource 

ui->text->clear(); 
getData = QString::fromUtf8(output.c_str()); 
ui->text->setText(getData); 

이 내가 놓친 버그가 있습니까?

+0

"바이너리 바이트 배열을 소스로 사용"StringSource 생성자. 이 경우 "길이"매개 변수는 getData.size() * 2가 아닌 data.size() 여야합니다. –

+0

대단히 감사합니다! –

답변

1

QString에서 QByteArray로 변환 할 때 데이터가 손실된다고 생각합니다. 이것을 시도하십시오 :

QByteArray data = getData.toUtf8(); 

... 

getData = QString::fromUtf8(output.c_str()); 
+0

UTF-8로 충분하지 않다고 생각합니다. UTF-16 또는 UTF-32가 어쩌면? –

+0

"충분하지 않다"는 것은 무엇을 의미합니까? 위키 피 디아에서 : "UTF-16과 UTF-32처럼 UTF-8은 유니 코드 문자 집합의 모든 문자를 나타낼 수 있습니다." –

+0

@ EdgeLuxe : UTF-8에서 문자열의 길이는 바이트와 같지 않습니다 문자열의 길이 –

0

대신 reinterpret_cast<byte*>(QString::data())을 사용하십시오. 실제로 코드 페이지 변환을 시도하지 마십시오. AES는 상관하지 않습니다. StringSink 대신 ArraySink을 사용하십시오.

실제 QString :: data() 버퍼의 크기는 UTF-16을 사용하기 때문에 거기에 포함 된 문자 수의 두 배입니다.

+0

'ArraySink'는'byte *'배열과 길이를 필요로합니다. 그래서'byte *'배열은'QByteArray'이고 길이는'getData.size() * 2'입니다. (getData는'buffer가 거기에 포함 된 문자의 두 배입니다. 암호 해독 기능에? –

+0

@EdgeLuxe : 아니오 - QByteArray 로의 변환은 실제로 국제 문자의 파괴를 일으키는 원인입니다. QString은 버퍼를 노출합니다 - 다른 즉각적인 타입으로 변환하는 이유는 무엇입니까? AES는 모든 바이트 스트림을 암호화 할 수 있기 때문에 '바이트'는 CryptoPP에서 사용됩니다. 이러한 바이트의 실제 내용은 중요하지 않습니다. –

+0

질문을 수정했습니다. –