Objective C で OpenSSL を試しています。SMIME 非対称キーで暗号化されたデータを書き込もうとしています。ファイルを開き、暗号化し、ディスクに書き込むことに問題はありません。単一のメモリ バッファを暗号化できます。私がやりたいのは、複数のメモリ バッファーを同じ暗号化 BIO に供給し、ディスクにシリアルに書き込む、一種のスキャッター ギャザー アプローチを実装することです。
私のコードは単純です。暗号を設定し、公開鍵/証明書を取得しPEM_read_bio_X509_AUX()
ます。STACK_OF
私はそれをX509sにプッシュcerts
しsk_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 つのメモリ バッファーに対してのみ正常に機能します。ループ内で複数のバッファーを渡そうとすると、最後のバッファーのみが出力されます。の呼び出しの間に構造化されたreadBIO
abdを解放して再割り当てしようとしましたが、これは機能しません。p7
BIO_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) いいえを返します。 はいを返します。 }
これは機能しますが、私の懸念は、入力バッファーが任意に大きくなる可能性があることです。そのため、最後に暗号化/書き込み全体を蓄積して実行するよりも、出力に書き込み、各書き込みでフラッシュできるようにすることをお勧めします。 .