RSA的具体内容就不讲了,自己搜搜就有。
但是要知道的是RSA加密有一个公钥一个私钥,用公钥可以验证是否是私钥加密过的内容,防止数据传输过程中劫持修改内容。
支付宝这边需要的是你给他一个公钥,和私钥一样是在你的本机生成。然后把公钥填到支付宝,支付宝也会给你一个公钥,用于验证支付完成后支付宝回调的数据是否正确。
生成比较简单就把官方文档的搬过来了,下面的选一个就行了。要注意的是填到支付宝里面的时候不要有空格换行。PHP需要的是.pem的文件,但是IOS这边模拟生成订单只需要把里面的字符串取出来用就行了。
Linux用户(以Ubuntu为例)
$ openssl 进入OpenSSL程序
OpenSSL> genrsa -out rsa_private_key.pem 1024 生成私钥
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt Java开发者需要将私钥转换成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥
OpenSSL> exit ## 退出OpenSSL程序
Windows用户在cmd窗口中进行以下操作:
C:\Users\Hammer>cd C:\OpenSSL-Win32\bin 进入OpenSSL安装目录
C:\OpenSSL-Win32\bin>openssl.exe 进入OpenSSL程序
OpenSSL> genrsa -out rsa_private_key.pem 1024 生成私钥
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt Java开发者需要将私钥转换成PKCS8格式
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥
OpenSSL> exit ## 退出OpenSSL程序
首先要到支付宝查到下面的值
NSString *partner = @"2088开头的16为数字";//商户ID
NSString *seller = @"账号ID,应该是邮箱";//账号ID
NSString *privateKey = @"本机生成的私钥";//调试用,应该放在服务器上进行签名
NSString *publicKey = @"支付宝给的公钥";//在后台找
-(void)createOrder{
//创建订单
Order *order = [[Order alloc] init];
order.partner = partner;//合作者ID
order.seller = seller;//账号ID
order.tradeNO = [self generateTradeNO]; //订单ID(由商家自行制定)设置订单号,随机生成
order.productName = product.subject; //商品标题
order.productDescription = product.body; //商品描述
order.amount = [NSString stringWithFormat:@"%.2f",product.price]; //商品价格
order.notifyURL = @"http://www.xxx.com"; //回调URL填你们的服务器接口,支付成功支付宝会通知后台。
order.service = @"mobile.securitypay.pay";//接口名称,固定值。
order.paymentType = @"1";//支付类型。默认值为:1(商品购买)。
order.inputCharset = @"utf-8";//参数编码字符集
order.itBPay = @"30m";//未付款交易的超时时间
//你应用的urlScheme,在info的URL types里面添加,用于支付完成的回调
NSString *appScheme = @"dsc";
//将商品信息拼接成字符串
NSString *orderSpec = [order description];
//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
id<DataSigner> signer = CreateRSADataSigner(privateKey);//实例化签名对象
NSString *signedString = [signer signString:orderSpec];//调用支付宝提供的函数,在Util文件夹里面
//将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = nil;
if (signedString != nil) {
//将订单信息,签名字符串,和签名方式拼接成字符串
orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
orderSpec, signedString, @"RSA"];
//如果是后台签名的话,前面的都不用写了,直接拿后台返回的字符串调用支付宝就OK了
//调用SDK发送支付请求
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
NSString *str = resultDic[@"result"];
NSArray *arr = [str componentsSeparatedByString:@"&sign_type=\"RSA\"&sign=\""];
NSString *information = [arr firstObject];
NSString *temp = [arr lastObject];
temp = [temp componentsSeparatedByString:@"\""].firstObject;
id<DataVerifier> publicSinger = CreateRSADataVerifier(publicKey);
//用支付宝给你的公钥进行验证
BOOL ret = [publicSinger verifyString:information withSign:temp];
if(ret){
NSLog(@"验证成功");
if([resultDic[@"resultStatus"] isEqualToString:@"9000"]){
NSLog(@"支付成功");
}
}
}];
}
}
和后台对接完成后,我创建了一个支付管理单例。得到后台返回签名后的字符串,调用这个方法就行了
-(void)aliPayWithDataPay:(NSString *)dataPay andScheme:(NSString *)scheme andSuc:(aliSuc)aliSuc andErr:(aliErr)aliErr{
if([dataPay isKindOfClass:[NSDictionary class]]){
[SVProgressHUD showErrorWithStatus:@"订单创建失败!"];
return;
}
[[AlipaySDK defaultService] payOrder:dataPay fromScheme:scheme callback:^(NSDictionary *resultDic) {
if([resultDic[@"resultStatus"] isEqualToString:@"9000"]){
if(aliSuc){
aliSuc();
}
}else{
[SVProgressHUD showErrorWithStatus:@"支付失败!"];
if(aliErr){
aliErr();
}
}
}];
}