123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- /*
- @author: ideawu
- @link: https://github.com/ideawu/Objective-C-RSA
- */
- #import "RSATool.h"
- // RSA加密需要头文件
- #import <Security/Security.h>
- // AES加密需要头文件
- #import "CommonCrypto/CommonDigest.h"
- #import <CommonCrypto/CommonCrypto.h>
- // Base64加密需要的key
- static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- @implementation RSATool
- /*
- static NSString *base64_encode(NSString *str){
- NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
- if(!data){
- return nil;
- }
- return base64_encode_data(data);
- }
- */
- #pragma mark RSATool 自带方法
- 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 RSAToolEncryption szOID_RSATool_RSATool
- 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
- #pragma mark RAS加密(公钥签名 私钥解密)
- + (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) {
- //RSATool 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 = [RSATool stripPublicKeyHeader:data];
- if(!data){
- return nil;
- }
- //a tag to read/write keychain storage
- NSString *tag = @"RSAToolUtil_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 RSATool PRIVATE KEY-----"];
- if(spos.length > 0){
- epos = [key rangeOfString:@"-----END RSATool 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 = [RSATool stripPrivateKeyHeader:data];
- if(!data){
- return nil;
- }
- //a tag to read/write keychain storage
- NSString *tag = @"RSAToolUtil_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 RSATool private key */
- + (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef isSign:(BOOL)isSign {
- 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){
- //KyoLog(@"%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;
-
- if (isSign) {
- status = SecKeyRawSign(keyRef,
- kSecPaddingPKCS1,
- srcbuf + idx,
- data_len,
- outbuf,
- &outlen
- );
- } else {
- status = SecKeyEncrypt(keyRef,
- kSecPaddingPKCS1,
- srcbuf + idx,
- data_len,
- outbuf,
- &outlen
- );
- }
- if (status != 0) {
- KyoLog(@"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 = [RSATool 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 = [RSATool addPrivateKey:privKey];
- if(!keyRef){
- return nil;
- }
- return [RSATool encryptData:data withKeyRef:keyRef isSign:YES];
- }
- + (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){
- //KyoLog(@"%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) {
- KyoLog(@"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 = [RSATool 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 = [RSATool addPrivateKey:privKey];
- if(!keyRef){
- return nil;
- }
- return [RSATool decryptData:data withKeyRef:keyRef];
- }
- /* END: Encryption & Decryption with RSATool private key */
- /* START: Encryption & Decryption with RSATool public key */
- + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
- NSData *data = [RSATool 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 = [RSATool addPublicKey:pubKey];
- if(!keyRef){
- return nil;
- }
- return [RSATool encryptData:data withKeyRef:keyRef isSign:NO];
- }
- + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{
- NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
- data = [RSATool 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 = [RSATool addPublicKey:pubKey];
- if(!keyRef){
- return nil;
- }
- return [RSATool decryptData:data withKeyRef:keyRef];
- }
- /* END: Encryption & Decryption with RSATool public key */
- #pragma mark RSA签名 (私钥签名 公钥验签)
- //// 1. PKCS1格式的RSA私钥的字符串转SecKeyRef
- //+ (SecKeyRef)addRSAPrivateKey:(NSString *)key {
- //
- // // This is a base64 encoded key. so, decode it.
- // NSData *data = [[NSData alloc] initWithBase64EncodedString:key options:NSDataBase64DecodingIgnoreUnknownCharacters];
- //
- // if(!data){ return nil; }
- // //a tag to read/write keychain storage
- // NSString *tag = @"RSA_PRIVATE_KEY";
- // 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;
- //}
- //
- //// 2. 公钥字符串转SeckeyRef
- //+ (SecKeyRef)addRSAPublicKey:(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;
- //}
- // 3.1 SHA1算法的实现
- + (NSData *)sha1:(NSString *)str
- {
- const void *data = [str cStringUsingEncoding:NSUTF8StringEncoding];
- CC_LONG len = (CC_LONG)strlen(data);
- uint8_t * md = malloc( CC_SHA1_DIGEST_LENGTH * sizeof(uint8_t) );;
- CC_SHA1(data, len, md);
- return [NSData dataWithBytes:md length:CC_SHA1_DIGEST_LENGTH];
- }
- // 3.2 SHA256算法的实现
- + (NSData *)sha256:(NSString *)str
- {
- // const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
- // NSData*data=[NSData dataWithBytes:cstr length:self.length];
- // uint8_t digest[CC_SHA256_DIGEST_LENGTH];
- // CC_SHA256(data.bytes, data.length,digest);
- // NSMutableString *output=[NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
- // for(inti=0; i < CC_SHA256_DIGEST_LENGTH; i++)
- // [output appendFormat:@"%02x", digest[i]];
- // return output;CC_SHA256_BLOCK_BYTES
- 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];
- }
- + (NSMutableString *)sha256_64:(NSString *)str
- {
- const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
- NSData*data=[NSData dataWithBytes:cstr length:str.length];
- uint8_t digest[CC_SHA256_DIGEST_LENGTH];
- CC_SHA256(data.bytes, data.length,digest);
- NSMutableString *output=[NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
- for(int i=0; i < CC_SHA256_DIGEST_LENGTH; i++)
- [output appendFormat:@"%02x", digest[i]];
- return output;
- }
- + (NSString *)sha256_8:(NSString *)str
- {
- NSMutableString * str64 = [self sha256_64:str];
- NSString *str8 = [str64 substringToIndex:8];
- str8 = [str8 uppercaseString];
-
- return str8;
- }
- // 4. 使用RSA私钥签名的实现
- + (NSString *)sign:(NSString *)content withPriKey:(NSString *)priKey
- {
- SecKeyRef privateKeyRef = [self addPrivateKey:priKey];
- if (!privateKeyRef) { KyoLog(@"添加私钥失败"); return nil; }
- NSData *sha256Data = [self sha256:content];
- unsigned char *sig = (unsigned char *)malloc(256);
- size_t sig_len;
- OSStatus status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1SHA256, [sha256Data bytes], CC_SHA256_DIGEST_LENGTH, sig, &sig_len);
-
- if (status != noErr) { KyoLog(@"加签失败:%d",status); return nil; }
-
- NSData *outData = [NSData dataWithBytes:sig length:sig_len];
- return [outData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
- }
- // 5. 使用RSA公钥验签的实现
- + (BOOL)verify:(NSString *)content signature:(NSString *)signature withPublivKey:(NSString *)publicKey {
-
- SecKeyRef publicKeyRef = [self addPublicKey:publicKey];
- if (!publicKeyRef) { KyoLog(@"添加公钥失败"); 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{ KyoLog(@"验签失败:%d",status); return NO; }
- }
- #pragma mark 加密/解密(AES RSA base64 md5)
- // AES加密
- + (NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key
- {
- char keyPtr[kCCKeySizeAES128+1];
- memset(keyPtr, 0, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
-
- NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
- NSUInteger dataLength = [data length];
-
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
- size_t numBytesEncrypted = 0;
- CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
- kCCAlgorithmAES128,
- kCCOptionPKCS7Padding|kCCOptionECBMode,
- keyPtr,
- kCCBlockSizeAES128,
- NULL,
- [data bytes],
- dataLength,
- buffer,
- bufferSize,
- &numBytesEncrypted);
- if (cryptStatus == kCCSuccess) {
- NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
-
- return [resultData base64EncodedStringWithOptions:(NSDataBase64Encoding64CharacterLineLength)];
- }
- free(buffer);
- return nil;
- }
- //AES解密
- + (NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key
- {
- char keyPtr[kCCKeySizeAES128 + 1];
- memset(keyPtr, 0, sizeof(keyPtr));
- [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
-
- NSData *data = [[NSData alloc] initWithBase64EncodedString:encryptText options:NSDataBase64DecodingIgnoreUnknownCharacters];//base64解码
-
- NSUInteger dataLength = [data length];
- size_t bufferSize = dataLength + kCCBlockSizeAES128;
- void *buffer = malloc(bufferSize);
-
- size_t numBytesCrypted = 0;
- CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
- kCCAlgorithmAES128,
- kCCOptionPKCS7Padding|kCCOptionECBMode,
- keyPtr,
- kCCBlockSizeAES128,
- NULL,
- [data bytes],
- dataLength,
- buffer,
- bufferSize,
- &numBytesCrypted);
- if (cryptStatus == kCCSuccess) {
- NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
-
- return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
- }
- free(buffer);
- return nil;
- }
- /**RSA加密-publicKey-公钥*/
- + (NSString *)RSAEncrypt:(NSString *)plainText key:(NSString *)publicKey {
- NSString *encrypted = [RSATool encryptString:plainText publicKey:publicKey];
- return encrypted;
- }
- /**RSA解密-privateKey-私钥*/
- + (NSString *)RSADecrypt:(NSString *)encryptText key:(NSString *)privateKey {
- NSString *decrypted = [RSATool decryptString:encryptText privateKey:privateKey];
- return decrypted;
- }
- /**RSA私钥签名-privateKey-私钥*/
- + (NSString *)RSASignEncrypt:(NSString *)plainText key:(NSString *)privateKey {
- NSString *encrypted = [RSATool sign:plainText withPriKey:privateKey];
- return encrypted;
- }
- /**RSA公钥验签-publicKey-公钥 encryptText-密文 plainText-明文*/
- + (BOOL)RSASignDecrypt:(NSString *)encryptText Encrypt:(NSString *)plainText key:(NSString *)publicKey {
- BOOL decrypted = [RSATool verify:plainText signature:encryptText withPublivKey:publicKey];
- return decrypted;
- }
- /**Base64加密*/
- + (NSString *)Base64Encrypt:(NSString *)plainText {
-
- NSData *data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
-
- return [data base64EncodedStringWithOptions:0];
- }
- /**base64解密*/
- + (NSString *)Base64Decrypt:(NSString *)encryptText {
-
- NSData *data = [self dataWithBase64EncodedString:encryptText];
- return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- }
- /**base64格式字符串转换为文本数据*/
- + (NSData *)dataWithBase64EncodedString:(NSString *)string
- {
- if (string == nil)
- [NSException raise:NSInvalidArgumentException format:@""];
- if ([string length] == 0)
- return [NSData data];
-
- static char *decodingTable = NULL;
- if (decodingTable == NULL)
- {
- decodingTable = (char *)malloc(256);
- if (decodingTable == NULL)
- return nil;
- memset(decodingTable, CHAR_MAX, 256);
- NSUInteger i;
- for (i = 0; i < 64; i++)
- decodingTable[(short)encodingTable[i]] = i;
- }
-
- const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
- if (characters == NULL) // Not an ASCII string!
- return nil;
- char *bytes = (char *)malloc((([string length] + 3) / 4) * 3);
- if (bytes == NULL)
- return nil;
- NSUInteger length = 0;
-
- NSUInteger i = 0;
- while (YES)
- {
- char buffer[4];
- short bufferLength;
- for (bufferLength = 0; bufferLength < 4; i++)
- {
- if (characters[i] == '\0')
- break;
- if (isspace(characters[i]) || characters[i] == '=')
- continue;
- buffer[bufferLength] = decodingTable[(short)characters[i]];
- if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
- {
- free(bytes);
- return nil;
- }
- }
-
- if (bufferLength == 0)
- break;
- if (bufferLength == 1) // At least two characters are needed to produce one byte!
- {
- free(bytes);
- return nil;
- }
-
- // Decode the characters in the buffer to bytes.
- bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
- if (bufferLength > 2)
- bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
- if (bufferLength > 3)
- bytes[length++] = (buffer[2] << 6) | buffer[3];
- }
-
- bytes = (char *)realloc(bytes, length);
- return [NSData dataWithBytesNoCopy:bytes length:length];
- }
- /**md5加密*/
- + (NSString *)md5Encrypt:(NSString *)encryptText{
- const char *cStr = [encryptText UTF8String];
- unsigned char result[CC_MD5_DIGEST_LENGTH];
- CC_MD5(cStr, strlen(cStr), result);
-
- return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-
- result[0], result[1], result[2], result[3],
-
- result[4], result[5], result[6], result[7],
-
- result[8], result[9], result[10], result[11],
-
- result[12], result[13], result[14], result[15]
-
- ] lowercaseString];
-
- }
- #pragma mark - RSA加密demo
- - (void)RSA {
-
- NSString *pubkey = @"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI2bvVLVYrb4B0raZgFP60VXY\ncvRmk9q56QiTmEm9HXlSPq1zyhyPQHGti5FokYJMzNcKm0bwL1q6ioJuD4EFI56D\na+70XdRz1CjQPQE3yXrXXVvOsmq9LsdxTFWsVBTehdCmrapKZVVx6PKl7myh0cfX\nQmyveT/eqyZK1gYjvQIDAQAB\n-----END PUBLIC KEY-----";
- NSString *privkey = @"-----BEGIN PRIVATE KEY-----\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMMjZu9UtVitvgHS\ntpmAU/rRVdhy9GaT2rnpCJOYSb0deVI+rXPKHI9Aca2LkWiRgkzM1wqbRvAvWrqK\ngm4PgQUjnoNr7vRd1HPUKNA9ATfJetddW86yar0ux3FMVaxUFN6F0KatqkplVXHo\n8qXubKHRx9dCbK95P96rJkrWBiO9AgMBAAECgYBO1UKEdYg9pxMX0XSLVtiWf3Na\n2jX6Ksk2Sfp5BhDkIcAdhcy09nXLOZGzNqsrv30QYcCOPGTQK5FPwx0mMYVBRAdo\nOLYp7NzxW/File//169O3ZFpkZ7MF0I2oQcNGTpMCUpaY6xMmxqN22INgi8SHp3w\nVU+2bRMLDXEc/MOmAQJBAP+Sv6JdkrY+7WGuQN5O5PjsB15lOGcr4vcfz4vAQ/uy\nEGYZh6IO2Eu0lW6sw2x6uRg0c6hMiFEJcO89qlH/B10CQQDDdtGrzXWVG457vA27\nkpduDpM6BQWTX6wYV9zRlcYYMFHwAQkE0BTvIYde2il6DKGyzokgI6zQyhgtRJ1x\nL6fhAkB9NvvW4/uWeLw7CHHVuVersZBmqjb5LWJU62v3L2rfbT1lmIqAVr+YT9CK\n2fAhPPtkpYYo5d4/vd1sCY1iAQ4tAkEAm2yPrJzjMn2G/ry57rzRzKGqUChOFrGs\nlm7HF6CQtAs4HC+2jC0peDyg97th37rLmPLB9txnPl50ewpkZuwOAQJBAM/eJnFw\nF5QAcL4CYDbfBKocx82VX/pFXng50T7FODiWbbL4UnxICE0UBFInNNiWJxNEb6jL\n5xd0pcy9O2DOeso=\n-----END PRIVATE KEY-----";
- NSString *encrypted = [RSATool encryptString:@"hello world!" publicKey:pubkey];
- HLog(@"encrypted: %@", encrypted);
- NSString *decrypted = [RSATool decryptString:encrypted privateKey:privkey];
- HLog(@"decrypted: %@", decrypted);
- }
- #pragma mark 其他
- // 传入一个原始字典,依据ascii码从小到大排序,回传一个排好序的待签名字符串
- + (NSString *)sortArrWithDictionary:(NSDictionary *)dictionary {
- // 取出所有的key值
- NSArray *keys = [dictionary allKeys];
- //按字母顺序排序
- NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
- return [obj1 compare:obj2 options:NSNumericSearch];
- }];
- // 将排好的序的key值重新赋值
- NSMutableArray *jsonArr = [NSMutableArray array];
- [sortedArray enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- // 取出每一个keyValue值
- id value = dictionary[obj];
- NSString *str = @"";
- if ([value isKindOfClass:[NSString class]]) {
- str = [NSString stringWithFormat:@"\"%@\":\"%@\"", obj, dictionary[obj]];
- }else {
- str = [NSString stringWithFormat:@"\"%@\":%@", obj, dictionary[obj]];
- }
- [jsonArr addObject:str];
- }];
- // 将做好排序的数组转出字符串
- NSString *result = [jsonArr componentsJoinedByString:@","];
- result = [NSString stringWithFormat:@"{%@}", result];
- return result;
- }
- /**删除字符串里的换行符 \r 和 \n */
- + (NSString *)deleteNewlineCharactersWithString:(NSString *)text {
- // //去除掉首尾的空白字符和换行字符
- text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- text = [text stringByReplacingOccurrencesOfString:@"\r" withString:@""];
- text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@""];
- return text;
- }
- //#pragma mark 登录密码加密算法:MD5➕RSA
- //+ (NSString *)getRSAStringFrom:(NSString *)pwd {
- // /**密码加密算法:MD5➕RSA*/
- // NSString *publicKey = [HWDataManager getStringWithKey:Const_HWRSAPublicKey];
- // NSString *pwdMD5 = [RSATool md5Encrypt:pwd];
- // NSString *pwdRSA = [RSATool RSAEncrypt:pwdMD5 key:publicKey];
- // return pwdRSA;
- //}
- @end
|