Xcode 12:函数的隐式声明';SecKeyEncrypt';在C99中无效

Xcode 12:函数的隐式声明';SecKeyEncrypt';在C99中无效,xcode,rsa,Xcode,Rsa,升级到Xcode 12.0.1后,用于文件解密的我的命令行Mac应用程序(以Swift编写)在尝试构建时遇到以下错误: 函数“SecKeyEncrypt”的隐式声明在C99中无效 函数“SecKeyRawSign”的隐式声明在C99中无效 函数“SecKeyDecrypt”的隐式声明在C99中无效 en-/de-cryption代码(用Objective C编写)取自——它在Xcode 11中工作得很好。 它使用这个导入语句 #import <Security/Security.h&g

升级到Xcode 12.0.1后,用于文件解密的我的命令行Mac应用程序(以Swift编写)在尝试构建时遇到以下错误:

  • 函数“SecKeyEncrypt”的隐式声明在C99中无效
  • 函数“SecKeyRawSign”的隐式声明在C99中无效
  • 函数“SecKeyDecrypt”的隐式声明在C99中无效
en-/de-cryption代码(用Objective C编写)取自——它在Xcode 11中工作得很好。 它使用这个导入语句

#import <Security/Security.h>
引发错误的解密方法如下所示:

+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    size_t srclen = (size_t)data.length;
    
    size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    UInt8 *outbuf = malloc(block_size);
    size_t src_block_size = block_size;
    
    NSMutableData *ret = [[NSMutableData alloc] init];
    for(int idx=0; idx<srclen; idx+=src_block_size){
        //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
        size_t data_len = srclen - idx;
        if(data_len > src_block_size){
            data_len = src_block_size;
        }
        
        size_t outlen = block_size;
        OSStatus status = noErr;
        status = SecKeyDecrypt(keyRef,   // <<<<<<<<<<<<<<<<<<<<<< This raises the error
                               kSecPaddingNone,
                               srcbuf + idx,
                               data_len,
                               outbuf,
                               &outlen
                               );
        if (status != 0) {
            NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
            ret = nil;
            break;
        }else{
            //the actual decrypted data is in the middle, locate it!
            int idxFirstZero = -1;
            int idxNextZero = (int)outlen;
            for ( int i = 0; i < outlen; i++ ) {
                if ( outbuf[i] == 0 ) {
                    if ( idxFirstZero < 0 ) {
                        idxFirstZero = i;
                    } else {
                        idxNextZero = i;
                        break;
                    }
                }
            }
            
            [ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
        }
    }
    
    free(outbuf);
    CFRelease(keyRef);
    return ret;
}
#import <Foundation/Foundation.h>
#import <openssl/bio.h>
#import <openssl/pem.h>

NS_ASSUME_NONNULL_BEGIN

@interface RSACryptoOpenSSL : NSObject

+ (NSString *)decryptMacOsString:(NSString *)str privateKey:(NSString *)privKey;

@end

NS_ASSUME_NONNULL_END
+(NSData*)解密数据:(NSData*)使用keyRef的数据:(SecKeyRef)keyRef{
const uint8_t*srcbuf=(const uint8_t*)[数据字节];
size\u t srclen=(size\t)data.length;
大小块大小=SecKeyGetBlockSize(keyRef)*sizeof(uint8\u t);
UInt8*EXBUFF=malloc(块大小);
大小\u t src\u块大小=块大小;
NSMutableData*ret=[[NSMutableData alloc]init];
对于(int idx=0;idx src\u块大小){
数据长度=src块大小;
}
大小=块大小;
骨状态=noErr;

status=seckeydrocrypt(keyRef,//正如Phillip Mills指出的,如果secret/SecKey.h包含一个
#if SEC_OS_IPHONE
条件,而且事实上,如果我创建一个iOS应用程序而不是Mac应用程序,那么该项目可以无错误地构建。因此,我假设该条件已在Xcode 12中引入,并具有SecKeyEncrypt和SecKeyDecrypt canno等功能不要再在macOS上调用了(除非MacCatalyst)——可能从未得到过官方支持

无论如何,我现在已经通过CocoaPods添加了OpenSSL,并使解密部分正常工作。如果您感兴趣,我的头文件rsacyptoOpenSSL.h如下所示:

+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    size_t srclen = (size_t)data.length;
    
    size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    UInt8 *outbuf = malloc(block_size);
    size_t src_block_size = block_size;
    
    NSMutableData *ret = [[NSMutableData alloc] init];
    for(int idx=0; idx<srclen; idx+=src_block_size){
        //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
        size_t data_len = srclen - idx;
        if(data_len > src_block_size){
            data_len = src_block_size;
        }
        
        size_t outlen = block_size;
        OSStatus status = noErr;
        status = SecKeyDecrypt(keyRef,   // <<<<<<<<<<<<<<<<<<<<<< This raises the error
                               kSecPaddingNone,
                               srcbuf + idx,
                               data_len,
                               outbuf,
                               &outlen
                               );
        if (status != 0) {
            NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
            ret = nil;
            break;
        }else{
            //the actual decrypted data is in the middle, locate it!
            int idxFirstZero = -1;
            int idxNextZero = (int)outlen;
            for ( int i = 0; i < outlen; i++ ) {
                if ( outbuf[i] == 0 ) {
                    if ( idxFirstZero < 0 ) {
                        idxFirstZero = i;
                    } else {
                        idxNextZero = i;
                        break;
                    }
                }
            }
            
            [ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
        }
    }
    
    free(outbuf);
    CFRelease(keyRef);
    return ret;
}
#import <Foundation/Foundation.h>
#import <openssl/bio.h>
#import <openssl/pem.h>

NS_ASSUME_NONNULL_BEGIN

@interface RSACryptoOpenSSL : NSObject

+ (NSString *)decryptMacOsString:(NSString *)str privateKey:(NSString *)privKey;

@end

NS_ASSUME_NONNULL_END

感谢并感谢这些宝贵的信息。

正如Phillip Mills指出的那样,Security/SecKey.h中有一个
#if SEC_OS_IPHONE
条件,事实上,如果我创建了一个iOS应用程序而不是Mac应用程序,该项目可以毫无错误地构建。因此,我假设该条件是在Xcode 12和类似的函数中引入的在macOS上不能再调用SecKeyEncrypt和SecKeyDecrypt(除非Mac Catalyst)-可能从未得到官方支持

无论如何,我现在已经通过CocoaPods添加了OpenSSL,并使解密部分正常工作。如果您感兴趣,我的头文件rsacyptoOpenSSL.h如下所示:

+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    size_t srclen = (size_t)data.length;
    
    size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    UInt8 *outbuf = malloc(block_size);
    size_t src_block_size = block_size;
    
    NSMutableData *ret = [[NSMutableData alloc] init];
    for(int idx=0; idx<srclen; idx+=src_block_size){
        //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
        size_t data_len = srclen - idx;
        if(data_len > src_block_size){
            data_len = src_block_size;
        }
        
        size_t outlen = block_size;
        OSStatus status = noErr;
        status = SecKeyDecrypt(keyRef,   // <<<<<<<<<<<<<<<<<<<<<< This raises the error
                               kSecPaddingNone,
                               srcbuf + idx,
                               data_len,
                               outbuf,
                               &outlen
                               );
        if (status != 0) {
            NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
            ret = nil;
            break;
        }else{
            //the actual decrypted data is in the middle, locate it!
            int idxFirstZero = -1;
            int idxNextZero = (int)outlen;
            for ( int i = 0; i < outlen; i++ ) {
                if ( outbuf[i] == 0 ) {
                    if ( idxFirstZero < 0 ) {
                        idxFirstZero = i;
                    } else {
                        idxNextZero = i;
                        break;
                    }
                }
            }
            
            [ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
        }
    }
    
    free(outbuf);
    CFRelease(keyRef);
    return ret;
}
#import <Foundation/Foundation.h>
#import <openssl/bio.h>
#import <openssl/pem.h>

NS_ASSUME_NONNULL_BEGIN

@interface RSACryptoOpenSSL : NSObject

+ (NSString *)decryptMacOsString:(NSString *)str privateKey:(NSString *)privKey;

@end

NS_ASSUME_NONNULL_END

感谢并感谢这些有价值的信息。

我认为它在抱怨函数在没有声明的情况下被使用。导入包含这些函数的头文件应该可以修复它。(类似于
#import
,但您需要检查一下。)@PhillipMills我添加了有关使用的导入语句的有趣信息。该函数说它在OSX 10.7中可用,但文档页面没有声明在Catalyst之外支持Mac。这可能解释了如果SEC_OS_IPHONE有条件的话,
。我想它在抱怨函数在没有声明的情况下被使用。import修改包含这些函数的头文件应该可以修复它。(它可能类似于
#import
,但您需要检查它。)@PhillipMills I添加了有关使用的导入语句的信息。该函数表示它在OSX 10.7中可用,但文档页面并未声明在Catalyst之外支持Mac。这可能解释了如果SEC_OS_IPHONE
有条件的话。