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

0 0
原创粉丝点击