0

Objective C で OpenSSL を試しています。SMIME 非対称キーで暗号化されたデータを書き込もうとしています。ファイルを開き、暗号化し、ディスクに書き込むことに問題はありません。単一のメモリ バッファを暗号化できます。私がやりたいのは、複数のメモリ バッファーを同じ暗号化 BIO に供給し、ディスクにシリアルに書き込む、一種のスキャッター ギャザー アプローチを実装することです。

私のコードは単純です。暗号を設定し、公開鍵/証明書を取得しPEM_read_bio_X509_AUX()ます。STACK_OF私はそれをX509sにプッシュcertssk_X509_push(certs,...)ます。で出力ファイルを開きますwriteBIO=BIO_new_file()。でメモリ BIO を作成し、readBIO=BIO_new_mem_buf(buf,len);で暗号化しp7=PKCS_encrypt(certs,readBIO,...);ます。最後に、これを出力に書き込みますi2d_PKCS7_bio(writeBIO,p7);。これは、1 つのメモリ バッファーに対してのみ正常に機能します。ループ内で複数のバッファーを渡そうとすると、最後のバッファーのみが出力されます。の呼び出しの間に構造化されたreadBIOabdを解放して再割り当てしようとしましたが、これは機能しません。p7BIO_new_mem_buf

何か案は?


更新 - 私は解決策を持っていますが、私が大喜びしているものではありません:

AETPublicKeyWrapper という OpenSSL のラッパーがあります。

    @interface AETPublicKeyWrapper : NSObject
    {
    @プライベート
       バイオ *readBIO;
       バイオ *writeBIO;
       STACK_OF(X509) *証明書;
       const char *rmode,*wmode;
       PKCS7 *p7;
       EVP_PKEY *privateKey;
       const EVP_CIPHER *暗号;
       int 入力形式、出力形式、フラグ;
    }

    ...
    -(BOOL)openInputFile:(const char*)fname;
    -(BOOL)openOutputFile:(const char*)fname;
    -(BOOL)openInputBuffer;
    -(int)writeToInputBuffer:(const void*)buf length:(unsigned long long)len;
    -(BOOL)loadPublicKeyCert:(const char*)certFileName;
    ...
    -(BOOL)encryptInput;
    -(BOOL)writeEncryptedOutput;
    -(BOOL)writeDecryptedOutput;
    ...

これにより、さまざまな OpenSSL API 呼び出しがカプセル化されます。-(BOOL)openOutputFile:たとえば、

    -(BOOL)openOutputFile:(const char*)fname
    {
       if(!(writeBIO=BIO_new_file((char*)fname,"wb")))
          いいえを返します。
       はいを返します。
    }

同じ出力への複数のバッファの暗号化ルーチンは次のようになります。

    AETPublicKeyWrapper *owrapper=[[AETPublicKeyWrapper alloc] init];
    [owrapper loadPublicKeyCert:[keyPath cStringUsingEncoding:NSASCIIStringEncoding]]
    [owrapper openOutputFile:[saveAsPath cStringUsingEncoding:NSASCIIStringEncoding]]
    [wrapper openInputBuffer]
    /* fileData はヘッダーです */
    [owrapper writeToInputBuffer:[fileData バイト] 長さ:[fileData 長さ]]
    /* dirArray はバッファの配列です */
    for(NSData *dirArray内のitemData)
       [owrapper writeToInputBuffer:[itemData バイト] length:[itemData 長さ]];
    [wrapper 暗号化入力]
    [owrapper writeEncryptedOutput]
    【ラッパーフラッシュ】
    【ラッパーリリース】

さまざまな方法があります(ほとんどのエラー処理は省略されています。キャストはコンパイラをシャットダウンするためのものです)

    -(BOOL)loadPublicKeyCert:(const char*)certFileName
    {
       X509 *x=NULL;
       略歴 *newCert;
       certs=sk_X509_new_null();
       newCert=BIO_new(BIO_s_file());
       BIO_read_filename(newCert,certFileName);
       x=PEM_read_bio_X509_AUX(newCert,NULL,NULL,NULL);
       sk_X509_push(証明書、x);
       はいを返します。
    }

    -(BOOL)openInputBuffer
    {
       if(!(readBIO=BIO_new(BIO_s_mem())))
          いいえを返します。
       はいを返します。
    }

    -(int)writeToInputBuffer:(const void*)buf length:(unsigned long long)len
    {
       return BIO_write(readBIO,(void*)buf,(int)len);
    }

    -(BOOL)encryptInput
    {
       if(!(p7=PKCS7_encrypt(certs,readBIO,cipher,flags)))
          いいえを返します。
       はいを返します。
    }

    -(BOOL)writeEncryptedOutput
    {
       if(i2d_PKCS7_bio(writeBIO,p7)<=0)
          いいえを返します。
       はいを返します。
    }

これは機能しますが、私の懸念は、入力バッファーが任意に大きくなる可能性があることです。そのため、最後に暗号化/書き込み全体を蓄積して実行するよりも、出力に書き込み、各書き込みでフラッシュできるようにすることをお勧めします。 .

4

0 に答える 0