/* @author: ideawu @link: https://github.com/ideawu/Objective-C-RSA */ #import "RSATool.h" // RSA加密需要头文件 #import // AES加密需要头文件 #import "CommonCrypto/CommonDigest.h" #import // 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 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 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