IOS下集成支付宝RSA签名
来源:互联网 发布:cf辅助软件下载 编辑:程序博客网 时间:2024/05/16 16:58
Ios集成支付宝,网上已经有很多方法,响应的demo也有。也就不啰嗦了。最后因为是支付,所以使用了RSA(非对称加密密钥的一种)。demo中没用加密,主要是密钥签名,这样做的作用就是防止订单在传输工程中数据有没有被改。和我们最早做的串口传输协议中CRC校验是一个目的。
支付宝给的demo是基于OPENSLL库的,这是一个功能强大权威,但庞大又很丑,尤其对于我们爱好object C或者习惯了面向对象的语言的程序员来说,很不希望自己的工程内有这么个怪物。所以我决定用其他的库代替openssl进行支付宝的RSA签名。
在做这之前,淘宝的开发水平真不怎么让人敬仰。等到网上搜了一下,还真没有好的库,唯一的只有apple自己谢的一个《Objective-C-RSA-maste》例子中的SecKeyWrapper类,其他的人都是模仿此例子做的。然而很多时候都和支付宝签名不通。
首先我们看看ios自己的安全加密的库有哪些:
库
功能
支持平台
使用方法
Security Transform API
1. 签名 sign
2. 验证verify
3. base64 编码解码
仅支持Mac
SecItemImport导入密钥做成secKeyref。只支持pem格式。
Common Cypoto
1. 只支持对称密钥
2. 只能加密解码
Mac和IOS
1. 通过pkcs12import导入p12格式的证书,从中提取SecKeyref。
2. 手工拼凑SecKeyref
CDSA/CSSA
已经废弃
还有一些证书,密钥已经PKCS8术语需要整理,我以前只知道个有对称不对称CA什么的,这次被这些概念头疼了2天,才大概有一个概念:
名称
格式
内容特征
用途
文件
RSA
密钥
文本
明文PKCS#1
-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
非JAVA
*.pem
*.cer部分
加密
DES-EDE3-CBC或BASE64或MD5算法生成key
-----BEGINENCRYPTED PRIVATE KEY---- BASE64 ENCODED DATA
-----ENDENCRYPTED PRIVATE KEY-----
非JAVA
*.key
*.pem
*.cer部分
PKCS8
-----BEGIN PRIVATE KEY----
BASE64私钥内容
-----END PRIVATEKEY-----
PKCS8
加密
-----BEGIN ENCRYPTED PRIVATE KEY—
BASE64私钥内容
-----ENDENCRYPTED PRIVATE KEY-----
二进制
都加密(用DES)
JAVA
*.der
*.cer
RSA公钥
文本PKCS#1
-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
PKCS8
-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----
二进制
Der
Cer
PKCS12
加密的证书
证书内包括
*p12
*.pfx
密钥+签= 证书
源代码改写了前辈们写的RSA类文件。中间有包私密钥加密,私密钥解密等,这些都是使用手动增加密钥串。密钥字符串带有\n换行。如下:
NSString *pubkey = @"-----BEGIN PUBLICKEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLuwt30JLYFvKcFOUdjPuDRdqv\nSnDb5TSdA/w0ND/GwLExpT66DeRz9+6//G//Y0y3c/yWT14k/ab1vID4U6W3vOgr\nafC0RyuIgH8ooCTNQpU+LtIoZ6qCejnux7VZ5lwWeT/9DQjWOtf6TopeRdzmOX09\nwa7c5xGGUsmi29QxDQIDAQAB\n-----ENDPUBLIC KEY-----";
注意支付宝下还是用PKCS8格式的密钥。
类在Objective-C-RSA-master这个例子上进行了更改。
增加了以下两个签名函数:
+ (NSString *)signString:(NSString *)stringwithPrivatekey:(NSString *)privKey;
+ (NSString *)signString:(NSString *)stringbyP12File:(NSString*)fileName password:(NSString*)pwd_string;
一个是用导入p12格式的证书。如下例子
//************************************************** NSString** p12filename = @"yourp12filname";//不加后缀
NSString* p12pwd_string = @"890000";
NSString *signedString2 = [RSA signString:orderSpecbyP12File:p12filename password:p12pwd_string];
//**************************************************
签名完成按照支付宝的demo‘例子调用即可。
//**************************************************
NSString*signedString = [RSA signString:orderSpecwithPrivatekey:privateKey_formatstring ];
NSLog(@"signedString using RSA = %@",signedString );
//将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString*orderString = nil;
if(signedString != nil) {
orderString= [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
orderSpec, signedString,@"RSA"];
NSLog(@"orderString = %@",orderString);
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appSchemecallback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
}];
}
[tableView deselectRowAtIndexPath:indexPathanimated:YES];
还有第二个更简单,使用格式化好的含有PKCS8格式的密钥字符串调用。
//*******************************************************************************
NSString*signedString = [RSA signString:orderSpec withPr
ivatekey:privateKey_formatstring ];
这样可以用返回的签名串按照上面支付。
本来使用这个方法进行签名返回串,刚开始发现一直连不通,查看支付宝的例子发现他多进行网络的URL转码,一时也没查清楚为什么把BASE64转换成UrlEncode,将此函数加入后成功连接支付宝服务器。交易完成。将更改后的RAH类文件在附件内,希望能改大家方便。这里上传不了附件,就附在下面:
源代码:RSA.h
#import <Foundation/Foundation.h>
#define kChosenCipherBlockSize kCCBlockSizeAES128
#define kChosenCipherKeySize kCCKeySizeAES128
#define kChosenDigestLength CC_SHA1_DIGEST_LENGTH
// Global constants for padding schemes.
#define kPKCS111
#define kTypeOfSigPadding kSecPaddingPKCS1SHA1
@interface RSA : NSObject
// return base64 encoded string
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
// return raw data
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;
// return base64 encoded string
// enc with private key NOT working YET!
//+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey;
// return raw data
//+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey;
// decrypt base64 encoded string, convert result to string(not base64 encoded)
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey;
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey;
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey;
+ (NSString *)signString:(NSString *)string withPrivatekey:(NSString *)privKey;
+ (NSString *)signString:(NSString *)string byP12File:(NSString*)fileName password:(NSString*)pwd_string;
@end
源代码:RSA.m
#import "RSA.h"
#import <Security/Security.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
@implementation RSA
/*
static NSString *base64_encode(NSString *str){
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
if(!data){
return nil;
}
return base64_encode_data(data);
}
*/
static NSString *base64_encode_data(NSData *data){
data = [data base64EncodedDataWithOptions:0];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return ret;
}
static NSData *base64_decode(NSString *str){
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
return data;
}
+ (NSData *)stripPublicKeyHeader:(NSData *)d_key{
// Skip ASN.1 public key header
if (d_key == nil) return(nil);
unsigned long len = [d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int idx= 0;
if (c_key[idx++] != 0x30) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
// PKCS #1 rsaEncryption szOID_RSA_RSA
static unsigned char seqiod[] =
{ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x01, 0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
idx += 15;
if (c_key[idx++] != 0x03) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
if (c_key[idx++] != '\0') return(nil);
// Now make a new NSData from this buffer
return([NSData dataWithBytes:&c_key[idx] length:len - idx]);
}
//credit: http://hg.mozilla.org/services/fx-home/file/tip/Sources/NetworkAndStorage/CryptoUtils.m#l1036
+ (NSData *)stripPrivateKeyHeader:(NSData *)d_key{
// Skip ASN.1 private key header
if (d_key == nil) return(nil);
unsigned long len = [d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int idx= 22; //magic byte at offset 22
if (0x04 != c_key[idx++]) return nil;
//calculate length of the key
unsigned int c_len = c_key[idx++];
int det = c_len & 0x80;
if (!det) {
c_len = c_len & 0x7f;
} else {
int byteCount = c_len & 0x7f;
if (byteCount + idx > len) {
//rsa length field longer than buffer
return nil;
}
unsigned int accum = 0;
unsigned char *ptr = &c_key[idx];
idx += byteCount;
while (byteCount) {
accum = (accum << 8) + *ptr;
ptr++;
byteCount--;
}
c_len = accum;
}
// Now make a new NSData from this buffer
return [d_key subdataWithRange:NSMakeRange(idx, c_len)];
}
+ (SecKeyRef)addPublicKey:(NSString *)key{
NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];
if(spos.location != NSNotFound && epos.location != NSNotFound){
NSUInteger s = spos.location + spos.length;
NSUInteger e = epos.location;
NSRange range = NSMakeRange(s, e-s);
key = [key substringWithRange:range];
}
key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
// This will be base64 encoded, decode it.
NSData *data = base64_decode(key);
data = [RSA stripPublicKeyHeader:data];
if(!data){
return nil;
}
//a tag to read/write keychain storage
NSString *tag = @"RSAUtil_PubKey";
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;
}
+ (SecKeyRef)addPrivateKey:(NSString *)key{
NSRange spos;
NSRange epos;
spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];
if(spos.length > 0){
epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"];
}else{
spos = [key rangeOfString:@"-----BEGIN PRIVATE KEY-----"];
epos = [key rangeOfString:@"-----END PRIVATE KEY-----"];
}
if(spos.location != NSNotFound && epos.location != NSNotFound){
NSUInteger s = spos.location + spos.length;
NSUInteger e = epos.location;
NSRange range = NSMakeRange(s, e-s);
key = [key substringWithRange:range];
}
key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
// This will be base64 encoded, decode it.
NSData *data = base64_decode(key);
data = [RSA stripPrivateKeyHeader:data];
if(!data){
return nil;
}
//a tag to read/write keychain storage
NSString *tag = @"RSAUtil_PrivKey";
NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
// Delete any old lingering key with the same tag
NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];
[privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
[privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
SecItemDelete((__bridge CFDictionaryRef)privateKey);
// Add persistent version of the key to system keychain
[privateKey setObject:data forKey:(__bridge id)kSecValueData];
[privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)
kSecAttrKeyClass];
[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)
kSecReturnPersistentRef];
CFTypeRef persistKey = nil;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);
if (persistKey != nil){
CFRelease(persistKey);
}
if ((status != noErr) && (status != errSecDuplicateItem)) {
return nil;
}
[privateKey removeObjectForKey:(__bridge id)kSecValueData];
[privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
[privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
[privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef = nil;
status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
if(status != noErr){
return nil;
}
return keyRef;
}
/* START: Encryption & Decryption with RSA private key */
+ (NSData *)encryptData:(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);
void *outbuf = malloc(block_size);
size_t src_block_size = block_size - 11;
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 = SecKeyEncrypt(keyRef,
kSecPaddingPKCS1,
srcbuf + idx,
data_len,
outbuf,
&outlen
);
if (status != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
ret = nil;
break;
}else{
[ret appendBytes:outbuf length:outlen];
}
}
free(outbuf);
CFRelease(keyRef);
return ret;
}
+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] privateKey:privKey];
NSString *ret = base64_encode_data(data);
return ret;
}
+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
return nil;
}
SecKeyRef keyRef = [RSA addPrivateKey:privKey];
if(!keyRef){
return nil;
}
return [RSA encryptData:data withKeyRef:keyRef];
}
+ (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,
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;
}
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSA decryptData:data privateKey:privKey];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return ret;
}
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
return nil;
}
SecKeyRef keyRef = [RSA addPrivateKey:privKey];
if(!keyRef){
return nil;
}
return [RSA decryptData:data withKeyRef:keyRef];
}
/* END: Encryption & Decryption with RSA private key */
/* START: Encryption & Decryption with RSA public key */
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey];
NSString *ret = base64_encode_data(data);
return ret;
}
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
return nil;
}
SecKeyRef keyRef = [RSA addPublicKey:pubKey];
if(!keyRef){
return nil;
}
return [RSA encryptData:data withKeyRef:keyRef];
}
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSA decryptData:data publicKey:pubKey];
NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return ret;
}
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
return nil;
}
SecKeyRef keyRef = [RSA addPublicKey:pubKey];
if(!keyRef){
return nil;
}
return [RSA decryptData:data withKeyRef:keyRef];
}
/* END: Encryption & Decryption with RSA public key */
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ (NSData *)getHashBytes:(NSData *)plainText {
CC_SHA1_CTX ctx;
uint8_t * hashBytes = NULL;
NSData * hash = nil;
// Malloc a buffer to hold hash.
hashBytes = malloc( kChosenDigestLength * sizeof(uint8_t) );
memset((void *)hashBytes, 0x0, kChosenDigestLength);
// Initialize the context.
CC_SHA1_Init(&ctx);
// Perform the hash.
CC_SHA1_Update(&ctx, (void *)[plainText bytes], [plainText length] );
// Finalize the output.
CC_SHA1_Final(hashBytes, &ctx);
// Build up the SHA1 blob.
hash = [NSData dataWithBytes:(const void *)hashBytes length:(NSUInteger)kChosenDigestLength];
if (hashBytes) free(hashBytes);
return hash;
}
+ (NSString *)signString:(NSString *)plainText withPrivatekeyRef:(SecKeyRef) private_keyRef
{
uint8_t* signedBytes = NULL;
size_t signedBytesSize = 0;
OSStatus sanityCheck = noErr;
NSData* signedHash = nil;
if (nil == private_keyRef )
{
return nil;
}
signedBytesSize = SecKeyGetBlockSize(private_keyRef);
NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];
signedBytes = malloc( signedBytesSize * sizeof(uint8_t) ); // Malloc a buffer to hold signature.
memset((void *)signedBytes, 0x0, signedBytesSize);
sanityCheck = SecKeyRawSign( private_keyRef,
kTypeOfSigPadding,
(const uint8_t *)[[RSA getHashBytes:plainTextBytes] bytes],
kChosenDigestLength,
(uint8_t *)signedBytes,
&signedBytesSize);
if (sanityCheck == noErr)
{
signedHash = [NSData dataWithBytes:(const void *)signedBytes length:(NSUInteger)signedBytesSize];
}
else
{
return nil;
}
if (signedBytes)
{
free(signedBytes);
}
NSString *signatureResult = base64_encode_data(signedHash);
return signatureResult;
}
+(SecKeyRef) getPrivateKeyRefrenceFromData: (NSData*)p12Data password:(NSString*)password
{
SecKeyRef privateKeyRef_local = NULL;
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
[options setObject: password forKey:(__bridge id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data, (__bridge CFDictionaryRef)options, &items);
if (securityError == noErr && CFArrayGetCount(items) > 0)
{
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef_local);
if (securityError != noErr)
{
privateKeyRef_local = NULL;
}
}
CFRelease(items);
return privateKeyRef_local;
}
+(SecKeyRef)getPrivateKeyfromFile:(NSString*)p12file_name password:(NSString*)pwd_string
{
NSString* p12filepath = [[NSBundle mainBundle] pathForResource:p12file_name ofType:@"p12" ];
NSData* p12Data = [NSData dataWithContentsOfFile:p12filepath ];
if( nil == p12Data ) return nil;
SecKeyRef privateKeyRef_result = [RSA getPrivateKeyRefrenceFromData:p12Data password:pwd_string];
return privateKeyRef_result;
}
+(NSString*)urlEncodedString:(NSString *)string
{
NSString * encodedString = (__bridge_transfer NSString*) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8 );
return encodedString;
}
//*****************************************************************************************
//xuyan add
+ (NSString *)signString:(NSString *)plain_string withPrivatekey:(NSString *)privKey
{
SecKeyRef keyRef = [RSA addPrivateKey:privKey];
if(!keyRef)
{
return nil;
}
NSString * base64String = [RSA signString:plain_string withPrivatekeyRef:keyRef];
return [RSA urlEncodedString:base64String];
}
+ (NSString *)signString:(NSString *)plain_string byP12File:(NSString*)fileName password:(NSString*)pwd_string
{
SecKeyRef keyRef = [RSA getPrivateKeyfromFile:fileName password:pwd_string];
if(!keyRef)
{
return nil;
}
NSString * base64String = [RSA signString:plain_string withPrivatekeyRef:keyRef];
return [RSA urlEncodedString:base64String];
}
@end
- IOS下集成支付宝RSA签名
- 支付宝 rsa 签名-客户端支付
- Delphi支付宝RSA签名验签
- iOS 集成支付宝支付
- iOS集成支付宝支付
- iOS 集成支付宝支付
- iOS集成支付宝支付
- 集成iOS支付宝支付
- iOS支付宝支付集成
- 开发支付宝支付用DELPHI实现 RSA签名
- iOS集成支付宝
- iOS集成支付宝
- iOS集成支付宝
- iOS集成支付宝
- iOS集成支付宝
- iOS支付宝集成
- iOS集成支付宝
- iOS集成支付宝
- kmp习题大全
- 在顶点照明模式下如何取得光源信息
- 绝对原创,Cheapest PBR Shader EVER!!!!
- pinyin4j支持简拼和多音
- HDU 4908BestCoder Sequence
- IOS下集成支付宝RSA签名
- 6.10 Android 推送 极光推送
- 从头到尾彻底理解KMP(2014年8月22日版)
- POJ 1088滑雪
- Iframe的优点和缺点
- GPU图形流水线
- Lua Challenge -- From Python Challenge
- 编程之核
- Spring2.5与Quartz的整合