2017-02-04 6 views
1

私はCrypto++ライブラリを暗号関連の仕事に使用しています。タスクのサブ部分は、テキストを暗号化して解読することです。メッセージは英数字の数字スペースと特殊文字を含む最大256文字です。Crypto ++で生RSAアルゴリズムを使用してメッセージを暗号化および復号化しますか?

このコードは、テキストの長さが8以下で動作していますが、その後は暗号化されたテキストの復号化に失敗します。

// g++ -std=c++1y crypto.cpp -I /home/shravan40/cryptopp/build -lcryptopp 

#include <iostream> 

#include <cryptopp/rsa.h> 
#include <cryptopp/integer.h> 
#include <cryptopp/osrng.h> 

int main(){ 
    // Keys 
    CryptoPP::Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9"); 

    CryptoPP::RSA::PrivateKey privKey; 
    privKey.Initialize(n, e, d); 

    CryptoPP::RSA::PublicKey pubKey; 
    pubKey.Initialize(n, e); 

    // Encryption 
    std::string message = "Shravan Kumar"; 
    CryptoPP::Integer m((const byte *)message.data(), message.size()); 
    std::cout << "m: " << m << std::endl; 
    // m: 126879297332596. 

    CryptoPP::Integer c = pubKey.ApplyFunction(m); 
    std::cout << "c: " << std::hex << c << std::endl; 
    // c: 3f47c32e8e17e291h 

    // Decryption 
    CryptoPP::AutoSeededRandomPool prng; 
    CryptoPP::Integer r = privKey.CalculateInverse(prng, c); 
    std::cout << "r: " << std::hex << r << std::endl; 

    // r: 736563726574h 
    std::string recovered; 
    recovered.resize(r.MinEncodedSize()); 

    r.Encode((byte *)recovered.data(), recovered.size()); 
    std::cout << "recovered: " << recovered << std::endl; 

    // recovered: Expected : (Shravan Kumar), Received -> y5��dqm0 
    return 0; 
} 
+4

メッセージはキー長に制限されるため、通常はメッセージを直接暗号化するためにPKIを使用しません。メッセージテキストを暗号化するには、対称アルゴリズム(CBCモードのAESなど)を使用する必要があります。公開鍵を使用して対称鍵を暗号化します。 –

+1

Crypto ++ wikiの[RSA Cryptography](http://www.cryptopp.com/wiki/RSA_Cryptography)も参照してください。 – jww

答えて

4

リチャードCrittenは、通常、ハイブリッド暗号化(AESなどの対称暗号でRSA等の非対称暗号)が使用されるin his comment正しいです。

安全性の低い例通常、平文をモジュラスnと同じサイズの部分に分割するだけで済みますが、したがって、あなたの場合は、8バイト/文字をまとめて(ビッグエンディアン)番号として使用してください。入力がASCIIのように見えるので、これら8バイトのうちの最上位ビットは常にゼロに設定されるため、暗号化/復号化に問題はないはずです。もちろん、RSAの入力は常にnより小さくなければなりません。

もちろん、文字列の最後の部分を処理するスマートな方法を考える必要があります。


注:それは(まだ)語られていない

  • 場合:パディングなしで生のRSAは、いずれかのセキュリティで保護されていません。この例がフィールドに実装されている場合は、問題になるキーサイズだけではありません。
  • 私は解読に関して何をしているのか分かっていません。あなたはもう一度あなたの教科書を見ておくべきです。
+0

私はちょうどノートのいくつかを追加する準備をしていました。それから、私はMaartenが質問に訪れたかどうかを調べるためにスクロールダウンしてみましょう:) – jww

+0

@jww私は今も今はまだ訪問していますが、ここでは暗号化に焦点を絞っています。エンコードの問題とコンバージョンの質問ではここでは少し繰り返し始めています。ルックには、暗号化に関するSOの例のほとんどが安全ではないという点もあります。それでも、私は[熊](http://stackoverflow.com/tags/cryptography/topusers)(と[erickson](http://stackoverflow.com/tags/encryption/topusers))を打ち負かす:) –

2
Integer m((const byte *)message.data(), message.size()); 

あなたがmessage.size()+1を使用している場合は、そのメッセージは、末尾NULLが含まれます。復号化中にこの文字列を使用して、復元された文字列がどこで終了するかを判断できます。それ以外の場合は、メッセージの長さを追跡する必要があります。

また、Crypto ++ wikiのRaw RSAに興味があります。しかし、Maartenが気をつけたように、正しいことをしてスキームを構築するのは難しいことです。

OAEPまたはPKCS v1.5のパディングを使用してRSA暗号化を使用することが考えられます。 Crypto ++ wikiのRSA Encryption Schemesも参照してください。


私は、これは未定義の動作であると信じて:

std::string recovered; 
recovered.resize(r.MinEncodedSize()); 
r.Encode((byte *)recovered.data(), recovered.size()); 

私はあなたが非constポインタを取得するために&recovered[0]を使用する必要があると思います。問題が発生している可能性があります。

関連する問題