0

OpenSSL を使用して C で単純な暗号化ルーチンを作成しようとしていますが、奇妙なことがわかりました。私は C の第一人者でも、OpenSSL の専門家でもありません。だから私は間違いを犯したかもしれません。

機能は次のとおりです

char *rsa_encrypt(char *data)
{
    const char xponent_in_hex[] = "010001";
    const char modulus_in_hex[] = "D0BA16F11907E7B0819705A15264AC29BEE9F1EC5F22642992
    D3E27100B7F212864A624A12FFB6D531712B0B0225AAD0C2E313D077A7DB2A5A33483EEFF41A9D";    

    BIGNUM *xponent = NULL;
    BIGNUM *modulus = NULL;

    BN_hex2bn(&xponent, xponent_in_hex);
    BN_hex2bn(&modulus, modulus_in_hex);

    RSA *rsa = RSA_new();
    rsa->e = xponent;
    rsa->n = modulus;
    rsa->iqmp = NULL;
    rsa->d = NULL;
    rsa->p = NULL;
    rsa->q = NULL;

    char encoded[512] = { 0 };
    RSA_public_encrypt(
    strlen(data), 
    (const unsigned char *)data, 
    (unsigned char *)encoded,
    rsa, 
    RSA_PKCS1_OAEP_PADDING
);

    RSA_free(rsa);

    return (encoded);
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
}

同じデータに対してその関数を数回呼び出し、呼び出されるたびに異なる値を生成します。作成されたRSA 構造体の指数係数は定数であり、入力データは各呼び出しで同じであるため、明らかに間違っています。

では、なぜRSA_public_encryptそのように振る舞うのでしょうか。

指数係数に基づいて RSA 暗号化の公開鍵を生成するにはどうすればよいですか?

そして、私はどこで間違いを犯しましたか?

4

2 に答える 2

5

これは実際には正しいことであり、間違いを犯しているわけではありません。あなたの混乱は、へのRSA_PKCS1_OAEP_PADDINGパラメータから生じますRSA_public_encrypt

RSA暗号化プロセスは実際には次のとおりです。

  1. 平文(plain)を取得してエンコードし、encoded_plainを生成します。
  2. encode_plainを暗号化します。

(ご想像のとおり、復号化プロセスでは、値を復号化してからメッセージを復号化する必要があります)。

このRSA_PKCS1_OAEP_PADDINGパラメーターは、プレーンテキストのエンコード方法(OAEPエンコードを使用する必要がある)を指定します。

簡単に説明すると、OAEPパディングはパディングにいくつかのランダムな値を使用するため、ととの両方がプレーンテキストの有効なencoded_plain値でxxxxxxxABCありyyyyyyyABCzzzzzzzABCそれらのencoded_plainは異なる値に暗号化されます。対応する復号化(および同じRSA_PKCS1_OAEP_PADDINGパラメータをに渡すことによって復号化RSA_private_decrypt)操作を実行する場合でも、パディングが3つすべてを取り除いたため、各暗号文の出力として「ABC」を取得する必要があります。

(正確に言うと、OAEPエンコーディングスキームはもっと複雑です。RFC3447セクション7.1.1を参照してください。しかし、これらはおそらく気にしない詳細です。)

于 2012-11-15T03:32:21.110 に答える
0

エンコードの範囲は、rsa_encrypt 関数の最後で終了します。リターン ポインターはメモリの無効な領域を指し、他の誰か (別のスレッドなど) が上書きしたため、期待したものが含まれていない可能性があります。パディングを説明する答えは正しいです。

于 2014-01-13T23:16:55.440 に答える