2017-02-05 21 views
0

私はcrypto++StreamTransformationFilter:暗号文の長さはブロックサイズの倍数ではありませんか?

でAESアルゴリズムの存在を使用してプレーンテキストを暗号化および復号化しようとしています。ここに私の暗号化方式ここ

/* 
* Encrypt the given text 
*/ 

template<typename T> 
T encryptText(T plainText) { 
    /* Key and IV setup 
    * AES encryption uses a secret key of a variable length (128-bit, 196-bit or 256- 
    * bit). This key is secretly exchanged between two parties before communication 
    * begins. DEFAULT_KEYLENGTH= 16 bytes 
    */ 
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; 
    memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); 
    T cipherText; 
    cout << "\n\nPlain Text size is (" << plainText.size() << " bytes)" << "\n\n"; 
    cout << plainText << "\n\n"; 
    /* 
    * Create Cipher Text 
    */ 
    CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv); 
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(cipherText)); 
    stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plainText.c_str()), plainText.length() + 1); 
    stfEncryptor.MessageEnd(); 
    cout << "\n\nCipher Text size is (" << cipherText.size() << " bytes)" << std::endl; 
    for(int i = 0; i < cipherText.size(); i++) { 
     cout << "0x" << std::hex << (0xFF & static_cast<byte>(cipherText[i])) << " "; 
    } 
    return cipherText; 
} 

は私の復号化方法

/* 
* Decrypt the given text 
*/ 

template<typename T> 
T decryptText(T encryptedText) { 
    /* Key and IV setup 
    * AES encryption uses a secret key of a variable length (128-bit, 196-bit or 256- 
    * bit). This key is secretly exchanged between two parties before communication 
    * begins. DEFAULT_KEYLENGTH= 16 bytes 
    */ 
    byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; 
    memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); 
    CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); 
    CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv); 
    T decryptedText; 
    CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedText)); 
    stfDecryptor.Put(reinterpret_cast<const unsigned char*>(encryptedText.c_str()), encryptedText.size()); 
    stfDecryptor.MessageEnd(); 
    std::cout << "\n\nDecrypted Text is " << "\n\n"; 
    std::cout << "\n\n" << decryptedText << "\n\n"; 
    return decryptedText; 
} 

encryptText機能が正常に実行されています私はそれの出力をmysqlデータベースに保存します。 decryptText関数を呼び出し中にエラーが

An uncaught exception occurred: StreamTransformationFilter: ciphertext length is not a multiple of block size 

を言って起こると私は、このエラーが原因で暗号化されたテキストであり、あまりにもいくつかのヌル(0)の値が含まれていてもよいことを理解しています。実際のテキストの解読方法

編集:

私がコメント欄で私のSQLクエリを表示するように求められたよう。

ここでは、mysqlデータベースに保存された暗号化データを取得するためのSQLクエリです。

template<typename T1, typename T2> 
void getUserSms(T1 userId,vector<T1>& smsIds,vector<T2>& text){ 
    try{ 
     mysql::connection db_cs(config_cs_db()); 
     auto sms = db_cs.run(select(all_of(us)).from(us).where(us.usersUserId == userId)); 
     while(!sms.empty()){ 
      const auto& row = sms.front(); 
      auto smsId = row.id.value(); 
      smsIds.push_back(smsId); 
      auto encryptedText = row.text.value(); 
      auto plainText = decryptText(encryptedText); 
      text.push_back(plainText); 
      sms.pop_front(); 
     } 
     return; 
    } 
    catch (const sqlpp::exception& e) { 
     std::cerr << "Could not get user sms due to some reason ...!!\n"; 
     std:cerr << e.what() << "\n"; 
     return; 
    } 
} 

私はをSQLクエリに使用しています。そして、テーブルの記述は

CREATE TABLE `user_sms`(
`id` BIGINT(50) NOT NULL AUTO_INCREMENT, 
`sender_number` VARCHAR(20), 
`text` VARCHAR(2000), 
`incoming_time` TIMESTAMP, 
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
`users_user_id` BIGINT(30), 
PRIMARY KEY(`id`), 
FOREIGN KEY(`users_user_id`) REFERENCES `users`(`user_id`) 
)ENGINE=InnoDB DEFAULT CHARSET=utf8; 
+1

暗号化された暗号文は、文​​字ではなくバイトです。文字としてそれを望むなら、それをBase64に変換して送信してください。生のバイトを直接文字として読み取ろうとする試みは、多くの可能性のある理由で失敗します。 – rossum

+0

もっとコードを見る必要があります。私は 'T'が' std :: string'だと思っています。 'BLOB'から' string'をどのように作成しているか見る必要があります。関数にアサーションを追加することができます: 'ASSERT(encryptedText.size()%AES :: BLOCKSIZE == 0)'。しかし、例外がすでにあなたに言ったことをあなたに伝えます。 – jww

+0

@jww:はい、 'T'は' std :: string'型です。 – Shravan40

答えて

1
  • 変更データ配列keyの種類と「IV fromバイトto符号なしchar`
  • 変更VARCHARBLOBからtextタイプmysqlデータベース内のテーブルuser_smsです。

CREATE TABLE `user_sms`( // Changes below is the changes has been made. `text` BLOB, )ENGINE=InnoDB DEFAULT CHARSET=utf8;

助けてくれてありがとうjwwを。

関連する問題