質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • C

    3809questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

RSAでtxtファイルを暗号化複合化したい。C言語。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,752

OpenSSLのライブラリを使ってRSAでファイルの中身を暗号化したいのですが、エラーが出てうまくいきません。
エラーの内容は"pkcs decoding error"や"data greater than mod len"が出てきます。

C言語でvisual stdioです。
プログラミング初心者なのでなにがなんだか分かりません。
とりあえず動くようにしたいのですが、分かる方教えてください。
よろしくお願いします。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/aes.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>

    int padding = RSA_PKCS1_PADDING;
//    int padding = RSA_PKCS1_OAEP_PADDING;
//    int padding = RSA_NO_PADDING;

RSA * createRSA(unsigned char * key, int public)
{
    RSA *rsa = NULL;
    BIO *keybio;
    keybio = BIO_new_mem_buf(key, -1);
    if (keybio == NULL)
    {
        printf("Failed to create key BIO");
        return 0;
    }
    if (public)
    {
        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
    }
    else
    {
        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
    }
    if (rsa == NULL)
    {
        printf("Failed to create RSA");
    }

    return rsa;
}
int public_encrypt(unsigned char * data, int data_len, unsigned char * key, unsigned char *encrypted)
{
    RSA * rsa = createRSA(key, 1);
    int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);
    RSA_free(rsa);
    return result;
}
int private_decrypt(unsigned char * enc_data, int data_len, unsigned char * key, unsigned char *decrypted)
{
    RSA * rsa = createRSA(key, 0);
    int  result = RSA_private_decrypt(data_len, enc_data, decrypted, rsa, padding);
    RSA_free(rsa);
    return result;
}
void printLastError(char *msg)
{
    char * err = malloc(130);;
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    printf("%s ERROR: %s\n", msg, err);
    free(err);
}

void encrypt(FILE *ifp, FILE *ofp)
{

    char Plaintext[2048 / 8];    
    int i;
    fgets(Plaintext, 2048/8, ifp);
//    Plaintext[strlen(Plaintext)] = '\0';

    // Check Plain Text.
    printf("Public Encrypt Section.\n");
    printf("Check Plaintext :\n%s\n", Plaintext);
    int PlainLength = strlen(Plaintext);
    printf("Plain Text Binary :\n");
    for (i = 0; i < PlainLength; i++) {
        printf("0x%X ", Plaintext[i]);
    }
    printf("\n");

    unsigned char encrypted[4098];
    unsigned char publicKey[] = "-----BEGIN PUBLIC KEY-----\n"\
        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"\
        "ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n"\
        "vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n"\
        "fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n"\
        "i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n"\
        "PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n"\
        "wQIDAQAB\n"\
        "-----END PUBLIC KEY-----\n";

    int encrypted_length = public_encrypt(Plaintext, strlen(Plaintext), publicKey, encrypted);

    if (encrypted_length == -1)
    {
        printLastError("Public Encrypt failed ");
        exit(0);
    }

    // Check Encrypted Text Binary.
    printf("Encrypted Text Binary :\n");
    for (i = 0; i < encrypted_length; i++) {
        printf("0x%X ", encrypted[i]);
    }
    printf("\n");
    printf("Encrypted Text length =%d\n\n", encrypted_length);

    fwrite(encrypted, sizeof(unsigned char), encrypted_length, ofp);
}

void decrypt(FILE *ifp, FILE *ofp)
{
    fseek(ifp, 0L, SEEK_END);
    long fsize = ftell(ifp);
    fseek(ifp, 0L, SEEK_SET);




    unsigned char CypherText[4098];
    char decrypted[4098];
    unsigned char privateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n"\
        "MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"\
        "vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9\n"\
        "Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9\n"\
        "yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l\n"\
        "WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q\n"\
        "gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8\n"\
        "omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e\n"\
        "N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG\n"\
        "X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd\n"\
        "gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl\n"\
        "vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF\n"\
        "1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu\n"\
        "m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ\n"\
        "uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D\n"\
        "JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D\n"\
        "4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV\n"\
        "WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5\n"\
        "nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG\n"\
        "PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA\n"\
        "SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1\n"\
        "I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96\n"\
        "ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF\n"\
        "yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5\n"\
        "w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX\n"\
        "uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw\n"\
        "-----END RSA PRIVATE KEY-----\n";

    fread(CypherText, sizeof(*CypherText), fsize, ifp);

    // Check CypherText Binary.
    int i;
    printf("Private Decrypt Section.\n");
    printf("Cypher Text Binary :\n");
    for (i = 0; i < fsize; i++) {
        printf("0x%X ", CypherText[i]);
    }
    printf("\n");




    int decrypted_length = private_decrypt(CypherText, strlen(CypherText), privateKey, decrypted);
    if (decrypted_length == -1)
    {
        printLastError("Private Decrypt failed \n");
        exit(0);
    }

    fwrite(decrypted, sizeof(*decrypted), decrypted_length, ofp);

}

int main(int argc, char *argv[])
{
    FILE *fIN;
    FILE *fOUT;
    errno_t error;
    char buf[255 + 1];

    if ((error = fopen_s(&fIN, "C://Projects/test_curl/Debug/plainRSA.txt", "r")) != 0) {
        strerror_s(buf, 255, error);
        printf("fopen_s error one \n%s\n", buf);
        return 0;
    }
    if ((error = fopen_s(&fOUT, "C://Projects/test_curl/Debug/cyphertextRSA.txt", "w+")) != 0) {
        strerror_s(buf, 255, error);
        printf("fopen_s error two \n%s\n", buf);
        return 0;
    }
    encrypt(fIN, fOUT);
    fclose(fIN);
    fclose(fOUT);

    if ((error = fopen_s(&fIN, "C://Projects/test_curl/Debug/cyphertextRSA.txt", "r+")) != 0) {
        strerror_s(buf, 255, error);
        printf("fopen_s error three \n%s\n", buf);
        return 0;
    }
    if ((error = fopen_s(&fOUT, "C://Projects/test_curl/Debug/decryptedRSA.txt", "w+")) != 0) {
        strerror_s(buf, 255, error);
        printf("fopen_s error four \n%s\n", buf);
        return 0;
    }
    decrypt(fIN, fOUT);
    fclose(fIN);
    fclose(fOUT);

    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

private_decryptにCypherTextの文字列の長さを取得するときに使っていた、strlenが原因でした!回答をくれた方ありがとうございました!!!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

詳しく調べたわけではないのですが、以下の一文が参考になるかもしれません。

関数の返り値は,暗号化あるいは復号結果のデータサイズである. 失敗時は-1となる. 暗号化の場合は,平文データのサイズをRSA_size(rsa)にしてしまうと,暗号文がRSA_size(rsa)を越えてしまってエラーになる. よくわからないのだが順に試すと, RSA_size(rsa) - 11 だとうまくいく. 

(出典: http://www.fireproject.jp/feature/c-language/openssl/rsa.html)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3809questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。