Cryptography OpenSSL将多个内存BIOs写入同一接收器BIO

Cryptography OpenSSL将多个内存BIOs写入同一接收器BIO,cryptography,openssl,Cryptography,Openssl,我正在Objective C下试验OpenSSL。我试图编写SMIME非对称密钥加密数据。我在打开文件、加密文件并将其写入磁盘方面没有问题。我可以加密单个内存缓冲区。我想做的是实现一种分散-聚集方法,将多个内存缓冲区送入同一个加密BIO并串行写入磁盘 我的代码很简单。我设置了密码并使用PEM\u read\u bio\u X509\u AUX()获取公钥/证书。我用sk\ux509\upush(certs,…)将它推到一堆证书上。我用writeBIO=BIO\u new\u file()打开输出

我正在Objective C下试验OpenSSL。我试图编写SMIME非对称密钥加密数据。我在打开文件、加密文件并将其写入磁盘方面没有问题。我可以加密单个内存缓冲区。我想做的是实现一种分散-聚集方法,将多个内存缓冲区送入同一个加密BIO并串行写入磁盘

我的代码很简单。我设置了密码并使用
PEM\u read\u bio\u X509\u AUX()
获取公钥/证书。我用
sk\ux509\upush(certs,…)
将它推到一堆
证书上。我用
writeBIO=BIO\u new\u file()
打开输出文件。我用
readBIO=BIO\u new\u mem\u buf(buf,len)创建一个内存BIO并使用
p7=PKCS\u encrypt(certs,readBIO,…)对其进行加密。最后,我使用
i2d_PKCS7_bio(writeBIO,p7)将其写入输出这只适用于一个内存缓冲区。如果我尝试在一个循环中传递多个缓冲区,则只输出最后一个缓冲区。我已经尝试释放并重新分配
readBIO
abd
p7
在调用
BIO\u new\u mem\u buf
之间构建的
readBIO,但这不起作用

有什么想法吗


更新-我有一个解决方案,但不是一个让我欣喜若狂的:

我有一个名为AETPublicKeyRapper的OpenSSL包装器

@interface AETPublicKeyWrapper : NSObject { @private BIO *readBIO; BIO *writeBIO; STACK_OF(X509) *certs; const char *rmode,*wmode; PKCS7 *p7; EVP_PKEY *privateKey; const EVP_CIPHER *cipher; int informat,outformat,flags; } ... -(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; ... 将多个缓冲区加密到同一输出的加密例程如下所示:

AETPublicKeyWrapper *owrapper=[[AETPublicKeyWrapper alloc] init]; [owrapper loadPublicKeyCert:[keyPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openOutputFile:[saveAsPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openInputBuffer] /* fileData is a header */ [owrapper writeToInputBuffer:[fileData bytes] length:[fileData length]] /* dirArray is an array of buffers */ for(NSData *itemData in dirArray) [owrapper writeToInputBuffer:[itemData bytes] length:[itemData length]]; [owrapper encryptInput] [owrapper writeEncryptedOutput] [owrapper flush] [owrapper release] AETPubliceWrapper*owrapper=[[AETPubliceWrapper alloc]init]; [owrapper loadPublicKeyCert:[keyPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openOutputFile:[saveAsPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openInputBuffer] /*fileData是一个标头*/ [owrapper WriteInputBuffer:[fileData字节]长度:[fileData长度]] /*dirArray是一个缓冲区数组*/ 用于(NSData*dirArray中的itemData) [Owraper WriteInputBuffer:[itemData字节]长度:[itemData长度]]; [owrapper encryptInput] [owrapper writeEncryptedOutput] [owrapper冲洗] [owrapper发布] 各种方法包括(省略了大多数错误处理;强制转换用于关闭编译器)

-(BOOL)loadPublicKeyCert:(const char*)certFileName { X509*x=NULL; 生物*新证书; 证书=sk_X509_new_null(); newCert=BIO_new(BIO_s_file()); BIO_读取_文件名(新证书、证书文件名); x=PEM_read_bio_X509_AUX(新证书,空,空,空); sk_X509_推送(证书,x); 返回YES; } -(BOOL)openInputBuffer { 如果(!(readBIO=BIO_new(BIO_s_mem())) 返回否; 返回YES; } -(int)WriteInputBuffer:(const void*)buf长度:(无符号长)len { 返回BIO_write(readBIO,(void*)buf,(int)len); } -(BOOL)加密输入 { 如果(!(p7=PKCS7_加密(证书、readBIO、密码、标志))) 返回否; 返回YES; } -(BOOL)写入加密输出 {
如果(i2d_PKCS7_bio)(书面形式,第7页)你获得答案的最好机会是展示你的代码。你好,大卫,欢迎你。你应该试着问一些具体的问题,而不是征求意见。此外,如果上面的代码包含一个答案,它应该作为一个答案发布。试着尽可能完整但稀疏,并允许其他人在进行全面检查之前发布答案。嗯,上面的评论说“显示你的代码”,我也这么做了。至于我的“解决方案”:这是我在问这个问题之前使用的方法。它是有效的,但如果我收集多个文件,其大小之和很大,可能会影响我的应用程序的内存占用。目前我将保留我的代码,但如果我确定更好的解决方案,我会保留我的代码我会把它寄出去的。 AETPublicKeyWrapper *owrapper=[[AETPublicKeyWrapper alloc] init]; [owrapper loadPublicKeyCert:[keyPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openOutputFile:[saveAsPath cStringUsingEncoding:NSASCIIStringEncoding]] [owrapper openInputBuffer] /* fileData is a header */ [owrapper writeToInputBuffer:[fileData bytes] length:[fileData length]] /* dirArray is an array of buffers */ for(NSData *itemData in dirArray) [owrapper writeToInputBuffer:[itemData bytes] length:[itemData length]]; [owrapper encryptInput] [owrapper writeEncryptedOutput] [owrapper flush] [owrapper release] -(BOOL)loadPublicKeyCert:(const char*)certFileName { X509 *x=NULL; BIO *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(certs,x); return YES; } -(BOOL)openInputBuffer { if(!(readBIO=BIO_new(BIO_s_mem()))) return NO; return YES; } -(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))) return NO; return YES; } -(BOOL)writeEncryptedOutput { if(i2d_PKCS7_bio(writeBIO,p7)<=0) return NO; return YES; }