• iOS RSA加密解密


    最近项目中用到了rsa加密解密,在此记录一下。

    1.使用公钥、私钥串来加密解密

    2.使用公钥der文件与私钥的p12文件来加密解密(使用p12文件解密时需要生成私钥文件时的密码)

    3.下面就附上网上找的大神代码

    .h文件

     1 @interface RSA : NSObject
     2 
     3 //使用'.der'公钥文件加密
     4 + (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
     5 
     6 //使用'.12'私钥文件解密
     7 + (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password;
     8 
     9 
    10 //使用公钥字符串加密
    11 + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
    12 
    13 //使用私钥字符串解密
    14 + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
    15 
    16 @end
    查看完整代码

    .m文件

      1 #import "RSA.h"
      2 #import <Security/Security.h>
      3 
      4 @implementation RSA
      5 
      6 static NSString *base64_encode_data(NSData *data){
      7     data = [data base64EncodedDataWithOptions:0];
      8     NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
      9     return ret;
     10 }
     11  
     12 static NSData *base64_decode(NSString *str){
     13     NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
     14     return data;
     15 }
     16  
     17 #pragma mark - 使用'.der'公钥文件加密
     18 //加密
     19 + (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path{
     20     if (!str || !path)  return nil;
     21     return [self encryptString:str publicKeyRef:[self getPublicKeyRefWithContentsOfFile:path]];
     22 }
     23  
     24 //获取公钥
     25 + (SecKeyRef)getPublicKeyRefWithContentsOfFile:(NSString *)filePath{
     26     NSData *certData = [NSData dataWithContentsOfFile:filePath];
     27     if (!certData) {
     28         return nil;
     29     }
     30     SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);
     31     SecKeyRef key = NULL;
     32     SecTrustRef trust = NULL;
     33     SecPolicyRef policy = NULL;
     34     if (cert != NULL) {
     35         policy = SecPolicyCreateBasicX509();
     36         if (policy) {
     37             if (SecTrustCreateWithCertificates((CFTypeRef)cert, policy, &trust) == noErr) {
     38                 SecTrustResultType result;
     39                 if (SecTrustEvaluate(trust, &result) == noErr) {
     40                     key = SecTrustCopyPublicKey(trust);
     41                 }
     42             }
     43         }
     44     }
     45     if (policy) CFRelease(policy);
     46     if (trust) CFRelease(trust);
     47     if (cert) CFRelease(cert);
     48     return key;
     49 }
     50  
     51 + (NSString *)encryptString:(NSString *)str publicKeyRef:(SecKeyRef)publicKeyRef{
     52     if(![str dataUsingEncoding:NSUTF8StringEncoding]){
     53         return nil;
     54     }
     55     if(!publicKeyRef){
     56         return nil;
     57     }
     58     NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] withKeyRef:publicKeyRef];
     59     NSString *ret = base64_encode_data(data);
     60     return ret;
     61 }
     62  
     63 #pragma mark - 使用'.12'私钥文件解密
     64 //解密
     65 + (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password{
     66     if (!str || !path) return nil;
     67     if (!password) password = @"";
     68     return [self decryptString:str privateKeyRef:[self getPrivateKeyRefWithContentsOfFile:path password:password]];
     69 }
     70  
     71 //获取私钥
     72 + (SecKeyRef)getPrivateKeyRefWithContentsOfFile:(NSString *)filePath password:(NSString*)password{
     73      
     74     NSData *p12Data = [NSData dataWithContentsOfFile:filePath];
     75     if (!p12Data) {
     76         return nil;
     77     }
     78     SecKeyRef privateKeyRef = NULL;
     79     NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
     80     [options setObject: password forKey:(__bridge id)kSecImportExportPassphrase];
     81     CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
     82     OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data, (__bridge CFDictionaryRef)options, &items);
     83     if (securityError == noErr && CFArrayGetCount(items) > 0) {
     84         CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
     85         SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
     86         securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
     87         if (securityError != noErr) {
     88             privateKeyRef = NULL;
     89         }
     90     }
     91     CFRelease(items);
     92     return privateKeyRef;
     93 }
     94  
     95 + (NSString *)decryptString:(NSString *)str privateKeyRef:(SecKeyRef)privKeyRef{
     96     NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
     97     if (!privKeyRef) {
     98         return nil;
     99     }
    100     data = [self decryptData:data withKeyRef:privKeyRef];
    101     NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    102     return ret;
    103 }
    104  
    105 #pragma mark - 使用公钥字符串加密
    106 /* START: Encryption with RSA public key */
    107  
    108 //使用公钥字符串加密
    109 + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
    110     NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey];
    111     NSString *ret = base64_encode_data(data);
    112     return ret;
    113 }
    114  
    115 + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{
    116     if(!data || !pubKey){
    117         return nil;
    118     }
    119     SecKeyRef keyRef = [self addPublicKey:pubKey];
    120     if(!keyRef){
    121         return nil;
    122     }
    123     return [self encryptData:data withKeyRef:keyRef];
    124 }
    125  
    126 + (SecKeyRef)addPublicKey:(NSString *)key{
    127     NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
    128     NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];
    129     if(spos.location != NSNotFound && epos.location != NSNotFound){
    130         NSUInteger s = spos.location + spos.length;
    131         NSUInteger e = epos.location;
    132         NSRange range = NSMakeRange(s, e-s);
    133         key = [key substringWithRange:range];
    134     }
    135     key = [key stringByReplacingOccurrencesOfString:@"
    " withString:@""];
    136     key = [key stringByReplacingOccurrencesOfString:@"
    " withString:@""];
    137     key = [key stringByReplacingOccurrencesOfString:@"	" withString:@""];
    138     key = [key stringByReplacingOccurrencesOfString:@" "  withString:@""];
    139      
    140     // This will be base64 encoded, decode it.
    141     NSData *data = base64_decode(key);
    142     data = [self stripPublicKeyHeader:data];
    143     if(!data){
    144         return nil;
    145     }
    146      
    147     //a tag to read/write keychain storage
    148     NSString *tag = @"RSAUtil_PubKey";
    149     NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
    150      
    151     // Delete any old lingering key with the same tag
    152     NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
    153     [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
    154     [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    155     [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
    156     SecItemDelete((__bridge CFDictionaryRef)publicKey);
    157      
    158     // Add persistent version of the key to system keychain
    159     [publicKey setObject:data forKey:(__bridge id)kSecValueData];
    160     [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)
    161      kSecAttrKeyClass];
    162     [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)
    163      kSecReturnPersistentRef];
    164      
    165     CFTypeRef persistKey = nil;
    166     OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
    167     if (persistKey != nil){
    168         CFRelease(persistKey);
    169     }
    170     if ((status != noErr) && (status != errSecDuplicateItem)) {
    171         return nil;
    172     }
    173      
    174     [publicKey removeObjectForKey:(__bridge id)kSecValueData];
    175     [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
    176     [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
    177     [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    178      
    179     // Now fetch the SecKeyRef version of the key
    180     SecKeyRef keyRef = nil;
    181     status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
    182     if(status != noErr){
    183         return nil;
    184     }
    185     return keyRef;
    186 }
    187  
    188 + (NSData *)stripPublicKeyHeader:(NSData *)d_key{
    189     // Skip ASN.1 public key header
    190     if (d_key == nil) return(nil);
    191      
    192     unsigned long len = [d_key length];
    193     if (!len) return(nil);
    194      
    195     unsigned char *c_key = (unsigned char *)[d_key bytes];
    196     unsigned int  idx     = 0;
    197      
    198     if (c_key[idx++] != 0x30) return(nil);
    199      
    200     if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
    201     else idx++;
    202      
    203     // PKCS #1 rsaEncryption szOID_RSA_RSA
    204     static unsigned char seqiod[] =
    205     { 0x30,   0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
    206         0x01, 0x05, 0x00 };
    207     if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
    208     idx += 15;
    209     if (c_key[idx++] != 0x03) return(nil);
    210     if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
    211     else idx++;
    212     if (c_key[idx++] != '') return(nil);
    213     // Now make a new NSData from this buffer
    214     return ([NSData dataWithBytes:&c_key[idx] length:len - idx]);
    215 }
    216  
    217 + (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    218     const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    219     size_t srclen = (size_t)data.length;
    220      
    221     size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    222     void *outbuf = malloc(block_size);
    223     size_t src_block_size = block_size - 11;
    224      
    225     NSMutableData *ret = [[NSMutableData alloc] init];
    226     for(int idx=0; idx<srclen; idx+=src_block_size){
    227         //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
    228         size_t data_len = srclen - idx;
    229         if(data_len > src_block_size){
    230             data_len = src_block_size;
    231         }
    232         size_t outlen = block_size;
    233         OSStatus status = noErr;
    234         status = SecKeyEncrypt(keyRef,
    235                                kSecPaddingPKCS1,
    236                                srcbuf + idx,
    237                                data_len,
    238                                outbuf,
    239                                &outlen
    240                                );
    241         if (status != 0) {
    242             NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
    243             ret = nil;
    244             break;
    245         }else{
    246             [ret appendBytes:outbuf length:outlen];
    247         }
    248     }
    249     free(outbuf);
    250     CFRelease(keyRef);
    251     return ret;
    252 }
    253  
    254 
    255 #pragma mark - 使用私钥字符串解密
    256 
    257  
    258 //使用私钥字符串解密
    259 + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{
    260     if (!str) return nil;
    261     NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    262     data = [self decryptData:data privateKey:privKey];
    263     NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    264     return ret;
    265 }
    266  
    267 + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{
    268     if(!data || !privKey){
    269         return nil;
    270     }
    271     SecKeyRef keyRef = [self addPrivateKey:privKey];
    272     if(!keyRef){
    273         return nil;
    274     }
    275     return [self decryptData:data withKeyRef:keyRef];
    276 }
    277  
    278 + (SecKeyRef)addPrivateKey:(NSString *)key{
    279     NSRange spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];
    280     NSRange epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"];
    281     if(spos.location != NSNotFound && epos.location != NSNotFound){
    282         NSUInteger s = spos.location + spos.length;
    283         NSUInteger e = epos.location;
    284         NSRange range = NSMakeRange(s, e-s);
    285         key = [key substringWithRange:range];
    286     }
    287     key = [key stringByReplacingOccurrencesOfString:@"
    " withString:@""];
    288     key = [key stringByReplacingOccurrencesOfString:@"
    " withString:@""];
    289     key = [key stringByReplacingOccurrencesOfString:@"	" withString:@""];
    290     key = [key stringByReplacingOccurrencesOfString:@" "  withString:@""];
    291      
    292     // This will be base64 encoded, decode it.
    293     NSData *data = base64_decode(key);
    294     data = [self stripPrivateKeyHeader:data];
    295     if(!data){
    296         return nil;
    297     }
    298      
    299     //a tag to read/write keychain storage
    300     NSString *tag = @"RSAUtil_PrivKey";
    301     NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
    302      
    303     // Delete any old lingering key with the same tag
    304     NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];
    305     [privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
    306     [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    307     [privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
    308     SecItemDelete((__bridge CFDictionaryRef)privateKey);
    309      
    310     // Add persistent version of the key to system keychain
    311     [privateKey setObject:data forKey:(__bridge id)kSecValueData];
    312     [privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)
    313      kSecAttrKeyClass];
    314     [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)
    315      kSecReturnPersistentRef];
    316      
    317     CFTypeRef persistKey = nil;
    318     OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);
    319     if (persistKey != nil){
    320         CFRelease(persistKey);
    321     }
    322     if ((status != noErr) && (status != errSecDuplicateItem)) {
    323         return nil;
    324     }
    325     [privateKey removeObjectForKey:(__bridge id)kSecValueData];
    326     [privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
    327     [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
    328     [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    329      
    330     // Now fetch the SecKeyRef version of the key
    331     SecKeyRef keyRef = nil;
    332     status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
    333     if(status != noErr){
    334         return nil;
    335     }
    336     return keyRef;
    337 }
    338  
    339 + (NSData *)stripPrivateKeyHeader:(NSData *)d_key{
    340     // Skip ASN.1 private key header
    341     if (d_key == nil) return(nil);
    342      
    343     unsigned long len = [d_key length];
    344     if (!len) return(nil);
    345      
    346     unsigned char *c_key = (unsigned char *)[d_key bytes];
    347     unsigned int  idx     = 22; //magic byte at offset 22
    348      
    349     if (0x04 != c_key[idx++]) return nil;
    350      
    351     //calculate length of the key
    352     unsigned int c_len = c_key[idx++];
    353     int det = c_len & 0x80;
    354     if (!det) {
    355         c_len = c_len & 0x7f;
    356     } else {
    357         int byteCount = c_len & 0x7f;
    358         if (byteCount + idx > len) {
    359             //rsa length field longer than buffer
    360             return nil;
    361         }
    362         unsigned int accum = 0;
    363         unsigned char *ptr = &c_key[idx];
    364         idx += byteCount;
    365         while (byteCount) {
    366             accum = (accum << 8) + *ptr;
    367             ptr++;
    368             byteCount--;
    369         }
    370         c_len = accum;
    371     }
    372     // Now make a new NSData from this buffer
    373     return [d_key subdataWithRange:NSMakeRange(idx, c_len)];
    374 }
    375  
    376 + (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
    377     const uint8_t *srcbuf = (const uint8_t *)[data bytes];
    378     size_t srclen = (size_t)data.length;
    379      
    380     size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
    381     UInt8 *outbuf = malloc(block_size);
    382     size_t src_block_size = block_size;
    383      
    384     NSMutableData *ret = [[NSMutableData alloc] init];
    385     for(int idx=0; idx<srclen; idx+=src_block_size){
    386         //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
    387         size_t data_len = srclen - idx;
    388         if(data_len > src_block_size){
    389             data_len = src_block_size;
    390         }
    391          
    392         size_t outlen = block_size;
    393         OSStatus status = noErr;
    394         status = SecKeyDecrypt(keyRef,
    395                                kSecPaddingNone,
    396                                srcbuf + idx,
    397                                data_len,
    398                                outbuf,
    399                                &outlen
    400                                );
    401         if (status != 0) {
    402             NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
    403             ret = nil;
    404             break;
    405         }else{
    406             //the actual decrypted data is in the middle, locate it!
    407             int idxFirstZero = -1;
    408             int idxNextZero = (int)outlen;
    409             for ( int i = 0; i < outlen; i++ ) {
    410                 if ( outbuf[i] == 0 ) {
    411                     if ( idxFirstZero < 0 ) {
    412                         idxFirstZero = i;
    413                     } else {
    414                         idxNextZero = i;
    415                         break;
    416                     }
    417                 }
    418             }
    419              
    420             [ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
    421         }
    422     }
    423     free(outbuf);
    424     CFRelease(keyRef);
    425     return ret;
    426 }
    427 
    428 @end
    查看完整代码

     4.生成公钥、私钥方法请参考这篇文章 《PHP、Android、iOS接口RSA加密解密》

  • 相关阅读:
    *Reverse Linked List II
    *Insertion Sort List
    Convert Sorted List to Binary Search Tree
    Reverse Integer
    read cache return null
    纳秒和随机数
    libthread_db
    gdb
    tls session resumption
    http://www.linux-commands-examples.com/xmllint
  • 原文地址:https://www.cnblogs.com/widgetbox/p/14693428.html
Copyright © 2020-2023  润新知