IOS 加密实现
2015-12-10 15:02
507 查看
随着移动开发的火热,安全随之也越来越重要,各种加密md5,AES,sha1,RSA,加密方法,还有https 加密协议等,此文记录下平时用到的加密方法用来记录
sha1 加密;
md5;
base64
AES
RSA
目前自己学习用到的就这6中,以后用到的还会补充,
sha1,md5,base64 写在一起,里面用到的GTMBase64 自己可以下载
AES 加解密的使用
以上也是需要base64文件的,在使用的地方直接这样调用
上面的APP_PUBLIC_PASSWORD,是自己设计的key ,可以随便设置,如果加密后的data 想专为string 转码过去
RAS加密实现,后台当时用的是java实现的,RAS 加密算是笔记强的加密,非对称加密 ,现在使用的也比较多,因为时间比较久,只能把当时的代码贴出来,
参考了高手文章
http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/
/article/2129082.html
代码
里面的生成的 public_key.der ,private_key 是从终端生成了
命令:openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem
生成两个对应的秘钥,public_key.der放在客户端,private_key 放在服务端,然后跟服务端交互,发现服务器端私钥解密不出来,不知道为啥,然后网上找文章,发现说生成的私钥是-x509编码的什么,需要转码,然后把私钥转换了一下,看/article/2129082.html高手说要转换为pkcs8,后给服务端才能解密,所以把pirvate_key转换了一下:命令:openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt,然后把生成的pkcs8_private_key给服务端,然后我客户端发送的就能解密了,还有在用的时候,也不知道为什么要把加密的数据data要base64转码,还得用Ndatabase64文件,下面是代码:
因为当时的base64文件和上面的加密的文件的base64 不一样,所以这里贴出来代码,使用的时候
这样的话发送给服务端的字符串后才能解密,当时用的base64 类不一样,还是不能用,最后还是找到网上的NSDAata+base64这个类里面的方法才能解密,最后这样尝试就成功了,这个RSA 比较麻烦的就是证书的问题和key 的问题,一旦这个搞清楚了,就简单多了,
http://download.csdn.net/download/songbai1211/9344631
sha1 加密;
md5;
base64
AES
RSA
目前自己学习用到的就这6中,以后用到的还会补充,
sha1,md5,base64 写在一起,里面用到的GTMBase64 自己可以下载
[code]- (NSString*) sha1 { const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:self.length]; uint8_t digest[CC_SHA1_DIGEST_LENGTH]; CC_SHA1(data.bytes, (unsigned int)data.length, digest); NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) [output appendFormat:@"%02x", digest[i]]; return output; } -(NSString *) md5 { const char *cStr = [self UTF8String]; unsigned char digest[CC_MD5_DIGEST_LENGTH]; CC_MD5( cStr, (unsigned int)strlen(cStr), digest ); NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) [output appendFormat:@"%02x", digest[i]]; return output; } - (NSString *) sha1_base64 { const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:self.length]; uint8_t digest[CC_SHA1_DIGEST_LENGTH]; CC_SHA1(data.bytes, (unsigned int)data.length, digest); NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; base64 = [GTMBase64 encodeData:base64]; NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding]; return output; } - (NSString *) md5_base64 { const char *cStr = [self UTF8String]; unsigned char digest[CC_MD5_DIGEST_LENGTH]; CC_MD5( cStr, (unsigned int)strlen(cStr), digest ); NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_MD5_DIGEST_LENGTH]; base64 = [GTMBase64 encodeData:base64]; NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding]; return output; } - (NSString *) base64 { NSData * data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; data = [GTMBase64 encodeData:data]; NSString * output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return output; } - (NSString*) dBase64 { NSData*data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; data = [GTMBase64 decodeData:data]; NSString*base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ; return base64String; }
AES 加解密的使用
[code]#import "NSData+AES.h" #import <CommonCrypto/CommonCryptor.h> @implementation NSData (Encryption) - (NSData *)AES256EncryptWithKey:(NSString *)key {//加密 char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); return nil; } - (NSData *)AES256DecryptWithKey:(NSString *)key {//解密 char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil; } @end
以上也是需要base64文件的,在使用的地方直接这样调用
[code]#pragma mark - AES加密 //将string转成带密码的data +(NSData*)encryptAESData:(NSString*)string { //将nsstring转化为nsdata NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; //使用密码对nsdata进行加密 NSData *encryptedData = [data AES256EncryptWithKey:APP_PUBLIC_PASSWORD]; return encryptedData; } //将带密码的data转成string +(NSString*)decryptAESData:(NSData*)data { //使用密码对data进行解密 NSData *decryData = [data AES256DecryptWithKey:APP_PUBLIC_PASSWORD]; //将解了密码的nsdata转化为nsstring NSString *string = [[NSString alloc] initWithData:decryData encoding:NSUTF8StringEncoding]; return [string autorelease]; }
上面的APP_PUBLIC_PASSWORD,是自己设计的key ,可以随便设置,如果加密后的data 想专为string 转码过去
[code][data base64Encoding];
RAS加密实现,后台当时用的是java实现的,RAS 加密算是笔记强的加密,非对称加密 ,现在使用的也比较多,因为时间比较久,只能把当时的代码贴出来,
参考了高手文章
http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/
/article/2129082.html
代码
[code]#import <Foundation/Foundation.h> @interface RSA1 : NSObject + (SecKeyRef) getPublicKey; + (NSData*) rsaEncryptString:(NSString*) string; @end // // RSA.m // TPL-AUTO-CLAIM-iPad // // Created by shen pu on 13-1-11. // Copyright (c) 2013年 cisetech. All rights reserved. // #import "RSA1.h" #import "NSData+Base64.h" @implementation RSA1 //#define RSA_KEY_BASE64 @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbMr8bg5pqgpF2i6HbiFos4IJaaj+3WCEALnPGg1cgyeDh+mPagK96o0kLKu1zqtfhWQQ9bMB/BvVGfzW87bBfuiFxxTYEMmhs7UqBvx6tiwgrL7JPJgZWtZnGefqyOsXJaXBf8nBPLb5dJ+denkgRr/zbAsNXig6E9jf/ULcWQwIDAQAB" static SecKeyRef _public_key=nil; + (SecKeyRef) getPublicKey{ // 从公钥证书文件中获取到公钥的SecKeyRef指针 if(_public_key == nil){ NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"]; NSData *certificateData = [[NSData alloc]initWithContentsOfFile:publicKeyPath]; // NSString *RSA_KEY_BASE64=[Base64 stringByEncodingData:data]; // NSData *certificateData = [Base64 decodeString:RSA_KEY_BASE64]; SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certificateData); SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); SecTrustRef myTrust; OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust); SecTrustResultType trustResult; if (status == noErr) { status = SecTrustEvaluate(myTrust, &trustResult); } _public_key = SecTrustCopyPublicKey(myTrust); CFRelease(myCertificate); CFRelease(myPolicy); CFRelease(myTrust); } return _public_key; } + (NSData*) rsaEncryptString:(NSString*) string{ SecKeyRef key = [self getPublicKey]; size_t cipherBufferSize = SecKeyGetBlockSize(key); uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t)); NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding]; size_t blockSize = cipherBufferSize - 11; size_t blockCount = (size_t)ceil([stringBytes length] / (double)blockSize); NSMutableData *encryptedData = [[[NSMutableData alloc] init] autorelease]; for (int i=0; i<blockCount; i++) { int bufferSize = MIN(blockSize,[stringBytes length] - i * blockSize); NSData *buffer = [stringBytes subdataWithRange:NSMakeRange(i * blockSize, bufferSize)]; OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes], [buffer length], cipherBuffer, &cipherBufferSize); if (status == noErr){ NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize]; [encryptedData appendData:encryptedBytes]; [encryptedBytes release]; }else{ if (cipherBuffer) free(cipherBuffer); return nil; } } if (cipherBuffer){free(cipherBuffer);} NSLog(@"Encrypted text (%d bytes): %@", [encryptedData length], [encryptedData description]); // NSLog(@"Encrypted text base64: %@", [NSData base64EncodedString:encryptedData]); return encryptedData; } @end
里面的生成的 public_key.der ,private_key 是从终端生成了
命令:openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem
生成两个对应的秘钥,public_key.der放在客户端,private_key 放在服务端,然后跟服务端交互,发现服务器端私钥解密不出来,不知道为啥,然后网上找文章,发现说生成的私钥是-x509编码的什么,需要转码,然后把私钥转换了一下,看/article/2129082.html高手说要转换为pkcs8,后给服务端才能解密,所以把pirvate_key转换了一下:命令:openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt,然后把生成的pkcs8_private_key给服务端,然后我客户端发送的就能解密了,还有在用的时候,也不知道为什么要把加密的数据data要base64转码,还得用Ndatabase64文件,下面是代码:
[code]// // NSData+Base64.h // // Version 1.0.2 // // Created by Nick Lockwood on 12/01/2012. // Copyright (C) 2012 Charcoal Design // // Distributed under the permissive zlib License // Get the latest version from here: // // https://github.com/nicklockwood/Base64 // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source distribution. // #import <Foundation/Foundation.h> @interface NSData (Base64) + (NSData *)dataWithBase64EncodedString:(NSString *)string; - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth; - (NSString *)base64EncodedString; @end // // NSData+Base64.m // // Version 1.0.2 // // Created by Nick Lockwood on 12/01/2012. // Copyright (C) 2012 Charcoal Design // // Distributed under the permissive zlib License // Get the latest version from here: // // https://github.com/nicklockwood/Base64 // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source distribution. // #import "NSData+Base64.h" @implementation NSData (Base64) - (NSData*)formatWithData:(NSData*)data{ if (data && [data length]>76) { }return data; } + (NSData *)dataWithBase64EncodedString:(NSString *)string { const char lookup[] = { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 62, 99, 99, 99, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 99, 99, 99, 99, 99, 99, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99, 99, 99, 99, 99, 99, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 99, 99, 99, 99, 99 }; NSData *inputData = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; long long inputLength = [inputData length]; const unsigned char *inputBytes = [inputData bytes]; long long maxOutputLength = (inputLength / 4 + 1) * 3; NSMutableData *outputData = [NSMutableData dataWithLength:maxOutputLength]; unsigned char *outputBytes = (unsigned char *)[outputData mutableBytes]; int accumulator = 0; long long outputLength = 0; unsigned char accumulated[] = {0, 0, 0, 0}; for (long long i = 0; i < inputLength; i++) { unsigned char decoded = lookup[inputBytes[i] & 0x7F]; if (decoded != 99) { accumulated[accumulator] = decoded; if (accumulator == 3) { outputBytes[outputLength++] = (accumulated[0] << 2) | (accumulated[1] >> 4); outputBytes[outputLength++] = (accumulated[1] << 4) | (accumulated[2] >> 2); outputBytes[outputLength++] = (accumulated[2] << 6) | accumulated[3]; } accumulator = (accumulator + 1) % 4; } } //handle left-over data if (accumulator > 0) outputBytes[outputLength] = (accumulated[0] << 2) | (accumulated[1] >> 4); if (accumulator > 1) outputBytes[++outputLength] = (accumulated[1] << 4) | (accumulated[2] >> 2); if (accumulator > 2) outputLength++; //truncate data to match actual output length outputData.length = outputLength; return outputLength? outputData: nil; } - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth { //ensure wrapWidth is a multiple of 4 wrapWidth = (wrapWidth / 4) * 4; const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; long long inputLength = [self length]; const unsigned char *inputBytes = [self bytes]; long long maxOutputLength = (inputLength / 3 + 1) * 4; maxOutputLength += wrapWidth? (maxOutputLength / wrapWidth) * 2: 0; unsigned char *outputBytes = (unsigned char *)malloc(maxOutputLength); long long i; long long outputLength = 0; for (i = 0; i < inputLength - 2; i += 3) { outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)]; outputBytes[outputLength++] = lookup[((inputBytes[i + 1] & 0x0F) << 2) | ((inputBytes[i + 2] & 0xC0) >> 6)]; outputBytes[outputLength++] = lookup[inputBytes[i + 2] & 0x3F]; //add line break if (wrapWidth && (outputLength + 2) % (wrapWidth + 2) == 0) { outputBytes[outputLength++] = '\r'; outputBytes[outputLength++] = '\n'; } } //handle left-over data if (i == inputLength - 2) { // = terminator outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)]; outputBytes[outputLength++] = lookup[(inputBytes[i + 1] & 0x0F) << 2]; outputBytes[outputLength++] = '='; } else if (i == inputLength - 1) { // == terminator outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2]; outputBytes[outputLength++] = lookup[(inputBytes[i] & 0x03) << 4]; outputBytes[outputLength++] = '='; outputBytes[outputLength++] = '='; } //truncate data to match actual output length outputBytes = realloc(outputBytes, outputLength); NSString *result = [[NSString alloc] initWithBytesNoCopy:outputBytes length:outputLength encoding:NSASCIIStringEncoding freeWhenDone:YES]; #if !__has_feature(objc_arc) [result autorelease]; #endif return (outputLength >= 4)? result: nil; } - (NSString *)base64EncodedString { return [self base64EncodedStringWithWrapWidth:0]; } @end
因为当时的base64文件和上面的加密的文件的base64 不一样,所以这里贴出来代码,使用的时候
[code]NSData *data1=[RSA1 rsaEncryptString:@"TEST"]; [data1 base64EncodedString]; NSLog(@"data1===========%@", [data1 base64EncodedString]);
这样的话发送给服务端的字符串后才能解密,当时用的base64 类不一样,还是不能用,最后还是找到网上的NSDAata+base64这个类里面的方法才能解密,最后这样尝试就成功了,这个RSA 比较麻烦的就是证书的问题和key 的问题,一旦这个搞清楚了,就简单多了,
以上就是自己平时使用的加密方法,谢谢
上面用到的GMTbase64 文件类http://download.csdn.net/download/songbai1211/9344631
相关文章推荐
- ios 虚化
- 学iOS开发之前需要那些准备工作
- [iOS] 初探 iOS8 中的 Size Class
- iOS关于拍照旋转90度的问题
- 学iOS开发之前需要那些准备工作
- iOS编程之前
- 创建class时Xcode自动给每一个类加上前缀
- ios 设计模式
- iOS开发中 一些零碎的知识点,
- iOS---设置圆形imageView
- iOS9 未受信任的企业级开发者
- IOS atomic与nonatomic,assign,copy与retain的定义和区别
- IOS:dispatch_group_enter的学习
- 【资源集合】94个iOS开发资源推荐,帮你加速应用开发
- nagios
- ios 3D Touch功能的实现
- iOS循环饮用的三种情况
- iOS9适配 之 关于info.plist 第三方登录 添加URL Schemes白名单
- iOS检查更新的方法
- ios mvc设计模式