// // RQHTTPService+RQGetPlaceList.m // JiaPei // // Created by 张嵘 on 2023/4/14. // 查询考场信息列表 #import "RQHTTPService+RQGetPlaceList.h" #include @implementation RQPlaceListModel - (void)checkWithComplete:(VoidBlock_Bool)complete { __block BOOL isVerify; //rsa 公钥 NSString *publicKey = [NSString stringWithFormat:@"%@%@%@",@"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCzR04LMmDlwyVRfK+Kgsm/vFMOFyqvGk4QIVC",@"Gj2CKKfhycRExm15N3tKOOouIjl/EU79It45oS+ltJkscvYrJn1zz+1bSoBLelZzJrn7K0NpHF8k", @"bCprsFHd60x+YJ4l8C3SDxfFebo4kqveJzx6JNZKwzFm7LPEO5XB9pEBRwIDAQAB"]; // 构造被签名串 NSMutableString *mutableVerifyString = [[NSMutableString alloc] initWithString:[NSString stringWithFormat:@"%@",self.userId]]; if (RQStringIsNotEmpty(self.expirationTime)) { [mutableVerifyString appendFormat:@"%ld",[RQ_SHARE_FUNCTION getTimeStampWithTimeStr:self.expirationTime formatter:@"yyyy-MM-dd HH:mm:ss"]]; } [mutableVerifyString appendFormat:@"%ld",self.isVip]; //公钥验签 isVerify = [self verify:mutableVerifyString.copy signature:RQStringIsNotEmpty(self.sign)? self.sign : @"" withPublivKey:publicKey]; NSLog(@"验签通过了吧------%@", isVerify ? @"YES":@"NO"); BOOL isVip = self.isVip == 1; self.isCheckVip = isVip; if (complete) { complete(isVerify? isVip : NO); } } #pragma mark - PrivateMethods // verify Signature - (BOOL)verify:(NSString *)content signature:(NSString *)signature withPublivKey:(NSString *)publicKey { SecKeyRef publicKeyRef = [self addPublicKey:publicKey]; if (!publicKeyRef) { NSLog(@"添加公钥失败"); return NO; } NSData *originData = [self sha256:content]; NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signature options:NSDataBase64DecodingIgnoreUnknownCharacters]; if (!originData || !signatureData) { return NO; } OSStatus status = SecKeyRawVerify(publicKeyRef, kSecPaddingPKCS1SHA256, [originData bytes], originData.length, [signatureData bytes], signatureData.length); if (status ==noErr) { return YES; } else{ NSLog(@"验签失败:%d",status); return NO; } } // digest message with sha1 - (NSData *)sha256:(NSString *)str { const void *data = [str cStringUsingEncoding:NSUTF8StringEncoding]; CC_LONG len = (CC_LONG)strlen(data); uint8_t * md = malloc( CC_SHA256_DIGEST_LENGTH * sizeof(uint8_t) );; CC_SHA256(data, len, md); return [NSData dataWithBytes:md length:CC_SHA256_DIGEST_LENGTH]; } - (SecKeyRef)addPublicKey:(NSString *)pubKey { NSData *data = [[NSData alloc] initWithBase64EncodedString:pubKey options:NSDataBase64DecodingIgnoreUnknownCharacters]; //a tag to read/write keychain storage NSString *tag = @"RSA_PUBLIC_KEY"; NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; // Delete any old lingering key with the same tag NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init]; [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass]; [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag]; SecItemDelete((__bridge CFDictionaryRef)publicKey); // Add persistent version of the key to system keychain [publicKey setObject:data forKey:(__bridge id)kSecValueData]; [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass]; [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef]; CFTypeRef persistKey = nil; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey); if (persistKey != nil){ CFRelease(persistKey); } if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; } [publicKey removeObjectForKey:(__bridge id)kSecValueData]; [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef]; [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; // Now fetch the SecKeyRef version of the key SecKeyRef keyRef = nil; status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef); if(status != noErr){ return nil; } return keyRef; } @end @implementation RQHTTPService (RQGetPlaceList) /** 查询考场信息列表 @param pageNum 当前页码 @param pageSize 每页数据量 @param locationModel 定位信息 @param placeName 搜索关键字 @return Returns a signal which will send complete, or error. */ - (RACSignal *)getPlaceListWithPageNum:(NSInteger)pageNum pageSize:(NSInteger)pageSize placeName:(NSString *)placeName { /// 1. 配置参数 RQKeyedSubscript *subscript = [RQKeyedSubscript subscript]; if (pageNum != 0 && pageSize != 0) { /// 当前页码 subscript[@"pageNum"] = @(pageNum); /// 每页数据量 subscript[@"pageSize"] = @(pageSize); } if (RQStringIsNotEmpty(placeName)) { /// 考场名称 subscript[@"name"] = placeName; } /// 城市ID subscript[@"cityId"] = RQ_USER_MANAGER.currentUser.city; /// 用户id subscript[@"userId"] = RQ_USER_MANAGER.currentUser._id; /// 2. 配置参数模型 RQURLParameters *paramters = [RQURLParameters urlParametersWithMethod:RQ_HTTTP_METHOD_GET path: RQ_GET_PlaceList parameters:subscript.dictionary]; /// 3.发起请求 return [[[RQHTTPRequest requestWithParameters:paramters] enqueueResultClass:[RQPlaceListModel class]] rq_parsedResults]; } @end