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 つのメモリ バッファーに対してのみ正常に機能します。ループ内で複数のバッファーを渡そうとすると、最後のバッファーのみが出力されます。の呼び出しの間に構造化された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)
いいえを返します。
はいを返します。
}
これは機能しますが、私の懸念は、入力バッファーが任意に大きくなる可能性があることです。そのため、最後に暗号化/書き込み全体を蓄積して実行するよりも、出力に書き込み、各書き込みでフラッシュできるようにすることをお勧めします。 .