我正在目标 C 下试验 OpenSSL。我正在尝试编写 SMIME 非对称密钥加密数据。我打开文件、加密文件并将其写入磁盘没有问题。我可以加密单个内存缓冲区。我想要做的是实现一种分散收集方法,将多个内存缓冲区馈入相同的加密 BIO 并串行写入磁盘。
我的代码很简单。我设置了一个密码并使用PEM_read_bio_X509_AUX(). 我把它推到STACK_OFX509s 上,certs,sk_X509_push(certs,...)。我打开我的输出文件writeBIO=BIO_new_file()。我创建了一个内存 BIOreadBIO=BIO_new_mem_buf(buf,len);并使用p7=PKCS_encrypt(certs,readBIO,...);. 最后,我将其写入输出,i2d_PKCS7_bio(writeBIO,p7);这仅适用于一个内存缓冲区。如果我尝试在循环中传递多个缓冲区,则仅输出最后一个。我已经尝试释放并重新分配在调用之间构建的readBIOabd ,但这不起作用。p7BIO_new_mem_buf
有任何想法吗?
更新 - 我有一个解决方案,但没有一个让我喜出望外的解决方案:
我有一个名为 AETPublicKeyWrapper 的 OpenSSL 包装器
@interface AETPublicKeyWrapper : NSObject
{
@私人的
生物*读取生物;
生物*写生物;
STACK_OF(X509) *证书;
常量字符 *rmode,*wmode;
PKCS7 *p7;
EVP_PKEY *privateKey;
常量 EVP_CIPHER *密码;
int 信息、输出格式、标志;
}
...
-(BOOL)openInputFile:(const char*)fname;
-(BOOL)openOutputFile:(const char*)fname;
-(BOOL)打开输入缓冲区;
-(int)writeToInputBuffer:(const void*)buf 长度:(unsigned long long)len;
-(BOOL)loadPublicKeyCert:(const char*)certFileName;
...
-(BOOL)加密输入;
-(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]]
[owrapper openInputBuffer]
/* fileData 是一个标题 */
[owrapper writeToInputBuffer:[fileData bytes] length:[fileData length]]
/* dirArray 是一个缓冲区数组 */
for(NSData *itemData in dirArray)
[owrapper writeToInputBuffer:[itemData bytes] 长度:[itemData length]];
[owrapper 加密输入]
[owrapper writeEncryptedOutput]
[owrapper 冲洗]
[owrapper 发布]
各种方法是(省略了大多数错误处理;强制转换是为了关闭编译器)
-(BOOL)loadPublicKeyCert:(const char*)certFileName
{
X509 *x=NULL;
生物*新证书;
证书=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 长度:(unsigned long long)len
{
返回 BIO_write(readBIO,(void*)buf,(int)len);
}
-(BOOL)加密输入
{
if(!(p7=PKCS7_encrypt(certs,readBIO,cipher,flags)))
返回否;
返回是;
}
-(BOOL)writeEncryptedOutput
{
如果(i2d_PKCS7_bio(writeBIO,p7)<=0)
返回否;
返回是;
}
这可行,但我担心输入缓冲区可能会变得任意大,所以我希望能够写入输出并让它在每次写入时刷新,而不是在最后累积并执行整个加密/写入操作.