Cryptography OpenSSL将多个内存BIOs写入同一接收器BIO
我正在Objective C下试验OpenSSL。我试图编写SMIME非对称密钥加密数据。我在打开文件、加密文件并将其写入磁盘方面没有问题。我可以加密单个内存缓冲区。我想做的是实现一种分散-聚集方法,将多个内存缓冲区送入同一个加密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()打开输出
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
abdp7
在调用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;
}