├── SecurityiOS ├── src.txt ├── CPPRI.p12 ├── CPPUB.cer ├── public.pem ├── AppDelegate.h ├── main.m ├── ViewController.h ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── private.pem ├── Info.plist ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── AppDelegate.m └── ViewController.m ├── SecurityiOS.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── project.pbxproj ├── NSData+KKRSA.h ├── SecKeyTools.h ├── NSData+KKHASH.h ├── NSData+KKSignVerify.h ├── NSData+KKAES.h ├── .gitignore ├── NSData+KKRSA.m ├── NSData+KKSignVerify.m ├── NSData+KKAES.m ├── NSData+KKHASH.m ├── SecKeyTools.m └── README.md /SecurityiOS/src.txt: -------------------------------------------------------------------------------- 1 | 0123456789 -------------------------------------------------------------------------------- /SecurityiOS/CPPRI.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoajin/Security-iOS/HEAD/SecurityiOS/CPPRI.p12 -------------------------------------------------------------------------------- /SecurityiOS/CPPUB.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cocoajin/Security-iOS/HEAD/SecurityiOS/CPPUB.cer -------------------------------------------------------------------------------- /SecurityiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SecurityiOS/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2ldMdFa6Ziu7PMSw5r4cxty2u 3 | ZtUOXuZctXVwAYbC7xeeAxb/bP+2MLudZLERhLFiAd3fBplg5mPNsWlM1rnTUFgn 4 | /g2YlHt912hQ48hQ0CJbokZANMrmzMej16pvNPC06/tTJ7/Sr5Zw4bwoPNUzDUU7 5 | kkZLpwzJbDUkb0QuOwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /SecurityiOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/14. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /SecurityiOS/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/14. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SecurityiOS/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/14. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | #define kRSA_KEY_SIZE 1024 14 | 15 | @interface ViewController : UIViewController 16 | { 17 | SecKeyRef publicKeyRef; //公钥 18 | SecKeyRef privateKeyRef;//私钥 19 | } 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /SecurityiOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /NSData+KKRSA.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKRSA.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | //分组加密,支持最大的加密块为 block 和填充方式有关 13 | 14 | typedef enum : NSUInteger { 15 | //不填充,最大数据块为 blockSize 16 | RSAPaddingNONE, 17 | //填充方式pkcs1,最大数据块为 blockSize -11 18 | RSAPaddingPKCS1, 19 | //填充方式OAEP, 最大数据块为 blockSize -42 20 | RSAPaddingOAEP, 21 | } RSAPaddingTYPE; 22 | 23 | @interface NSData (KKRSA) 24 | 25 | /** 26 | 公钥加密 27 | */ 28 | - (NSData *)RSAEncryptWith:(SecKeyRef )publicKey paddingType:(RSAPaddingTYPE )pdType; 29 | 30 | /** 31 | 私钥解密 32 | */ 33 | - (NSData *)RSADecryptWith:(SecKeyRef )privateKey paddingType:(RSAPaddingTYPE )pdType; 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /SecKeyTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecKeyTools.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/16. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | /** 13 | 从文件中载入公钥和密钥,把密钥以文件形式放在手机里是不安全的;视业务场景定吧 14 | */ 15 | @interface SecKeyTools : NSObject 16 | 17 | 18 | /** 19 | 从x509 cer证书中读取公钥 20 | */ 21 | + (SecKeyRef )publicKeyFromCer:(NSString *)cerFile; 22 | 23 | 24 | /** 25 | 从 p12 文件中读取私钥,一般p12都有密码 26 | */ 27 | + (SecKeyRef )privateKeyFromP12:(NSString *)p12File password:(NSString *)pwd; 28 | 29 | 30 | /** 31 | iOS 10 上可用如下接口SecKeyCreateWithData 从pem文件中读取私钥或公钥 32 | */ 33 | + (SecKeyRef )publicKeyFromPem:(NSString *)pemFile keySize:(size_t )size; 34 | 35 | + (SecKeyRef )privaKeyFromPem:(NSString *)pemFile keySize:(size_t )size; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /NSData+KKHASH.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKHASH.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum : NSUInteger { 12 | //md2 16字节长度 13 | CCDIGEST_MD2 = 1000, 14 | //md4 16字节长度 15 | CCDIGEST_MD4, 16 | //md5 16字节长度 17 | CCDIGEST_MD5, 18 | //sha1 20字节长度 19 | CCDIGEST_SHA1, 20 | //SHA224 28字节长度 21 | CCDIGEST_SHA224, 22 | //SHA256 32字节长度 23 | CCDIGEST_SHA256, 24 | //SHA384 48字节长度 25 | CCDIGEST_SHA384, 26 | //SHA512 64字节长度 27 | CCDIGEST_SHA512, 28 | } CCDIGESTAlgorithm; 29 | 30 | @interface NSData (KKHASH) 31 | 32 | /** 33 | 计算数据的hash值,根据不同的算法 34 | */ 35 | - (NSData *)hashDataWith:(CCDIGESTAlgorithm )ccAlgorithm; 36 | 37 | 38 | /** 39 | 返回 hex string的 data 40 | */ 41 | - (NSString *)hexString; 42 | 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /NSData+KKSignVerify.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKSignVerify.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | //主要使用PKCS1 方式的填充,最大签名数据长度为blockSize-11 14 | //签名数据 一般签名,数据的HASH值; 15 | //签名算法从ios5以后不再支持md5,md2 16 | typedef enum : NSUInteger { 17 | SEC_PKCS1SHA1 = 2000, 18 | SEC_PKCS1SHA224, 19 | SEC_PKCS1SHA256, 20 | SEC_PKCS1SHA384, 21 | SEC_PKCS1SHA512, 22 | } SEC_PKCS1_ALGORITHM; 23 | 24 | @interface NSData (KKSignVerify) 25 | 26 | 27 | /** 28 | 根据不同的算法,签名数据, 29 | */ 30 | - (NSData *)signDataWith:(SecKeyRef)privateKey algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm; 31 | 32 | /** 33 | 验证签名数据 34 | */ 35 | - (BOOL)verifySignWith:(SecKeyRef)publicKey signData:(NSData *)signData algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm; 36 | 37 | 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /SecurityiOS/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQC2ldMdFa6Ziu7PMSw5r4cxty2uZtUOXuZctXVwAYbC7xeeAxb/ 3 | bP+2MLudZLERhLFiAd3fBplg5mPNsWlM1rnTUFgn/g2YlHt912hQ48hQ0CJbokZA 4 | NMrmzMej16pvNPC06/tTJ7/Sr5Zw4bwoPNUzDUU7kkZLpwzJbDUkb0QuOwIDAQAB 5 | AoGAHNXAh4FbF6iXWmVbpKiR40oYjshysVhPbSjDKTM0gyibRDscsK4YHD/KAWtb 6 | g3a/RMkirwwtwN3huSRhit8GbZKWeaMTWIoYdWcORGuJykpi2Bk9jw/8F8g7wdZB 7 | rLFBmKp+pV+ll2hPRREsCxjs4BBJGv3ABx0dXF0SNwisDKECQQDgja6V5IYYGHIr 8 | xn2ToGzSoqu04ITDUjIXBvpMJad2RqKuljT9BYXzEHbNeyLAOk9cbLEGHv/kvCy1 9 | 8ne3ZXQzAkEA0CeRjwS46X1svWZHOQx9PVWtJ64MPJxHkvzQefgqwgVkZ6h/UOTE 10 | Z0Wu4Dwqtm870Ky6220sd3UIsPP3sNGV2QJBANFCF00mDfRMa7Dxozq8iEzuPNct 11 | V2txoK4m2X+2o00sXBQYdD7KM96kHCI2utaqQCSgQYOzxcHRvlS8JOYqTFMCQQCo 12 | tpmdQSebYKTFcuPhkoTkNNBPLBwQ+F5u/ekAIyyM7A/wkLr41yN1zR4r87hu/AOQ 13 | ZKBjf76d6EcuHeAx+f4pAkEA4HhfUPLxmIn2ykVa+EaY+pZ6curQdUuhw2P0zMPw 14 | gW6tv+1DdAKvzjewfKxXt8xN3tm6xBW6kl2obvmO7gQ0Gw== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /NSData+KKAES.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKAES.h 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | 支持的AES key size 有 128位,192位,256位 13 | 数据填充方式:kCCOptionPKCS7Padding 14 | 分组模式:cbc,ecb 15 | */ 16 | 17 | @interface NSData (KKAES) 18 | 19 | /** 20 | AES cbc 模式加密, 21 | @key 长度16字节,24字节,32字节 22 | @iv 16字节 23 | */ 24 | - (NSData *)AES_CBC_EncryptWith:(NSData *)key iv:(NSData *)iv; 25 | 26 | /** 27 | AES cbc 模式解密, 28 | @key 长度16字节,24字节,32字节 29 | @iv 16字节 30 | */ 31 | - (NSData *)AES_CBC_DecryptWith:(NSData *)key iv:(NSData *)iv; 32 | 33 | /** 34 | AES ecb 模式加密, 35 | @key 长度16字节,24字节,32字节 36 | */ 37 | - (NSData *)AES_ECB_EncryptWith:(NSData *)key; 38 | 39 | /** 40 | AES ecb 模式解密, 41 | @key 长度16字节,24字节,32字节 42 | */ 43 | - (NSData *)AES_ECB_DecryptWith:(NSData *)key; 44 | 45 | 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /SecurityiOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /SecurityiOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 26 | 27 | -------------------------------------------------------------------------------- /SecurityiOS/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SecurityiOS/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/14. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /NSData+KKRSA.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKRSA.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "NSData+KKRSA.h" 10 | #import 11 | 12 | @implementation NSData (KKRSA) 13 | 14 | /** 15 | 公钥加密 16 | */ 17 | - (NSData *)RSAEncryptWith:(SecKeyRef )publicKey paddingType:(RSAPaddingTYPE )pdType 18 | { 19 | if (!publicKey || self.length <1) { 20 | return nil; 21 | } 22 | OSStatus ret; 23 | NSData *retData = nil; 24 | size_t blockSize = SecKeyGetBlockSize(publicKey); 25 | uint8_t *encData = malloc(blockSize); 26 | bzero(encData, blockSize); 27 | 28 | SecPadding rsaPdd; 29 | switch (pdType) { 30 | case RSAPaddingNONE: 31 | rsaPdd = kSecPaddingNone; 32 | break; 33 | case RSAPaddingPKCS1: 34 | rsaPdd = kSecPaddingPKCS1; 35 | break; 36 | case RSAPaddingOAEP: 37 | rsaPdd = kSecPaddingOAEP; 38 | break; 39 | 40 | default: 41 | rsaPdd = kSecPaddingPKCS1; 42 | break; 43 | } 44 | 45 | ret = SecKeyEncrypt(publicKey, rsaPdd, self.bytes, self.length, encData, &blockSize); 46 | if (ret==errSecSuccess) { 47 | retData = [NSData dataWithBytes:encData length:blockSize]; 48 | } 49 | free(encData); 50 | encData = NULL; 51 | 52 | return retData; 53 | } 54 | 55 | /** 56 | 私钥解密 57 | */ 58 | - (NSData *)RSADecryptWith:(SecKeyRef )privateKey paddingType:(RSAPaddingTYPE )pdType 59 | { 60 | if (!privateKey || self.length <1) { 61 | return nil; 62 | } 63 | NSData *retData = nil; 64 | OSStatus ret; 65 | size_t blockSize = SecKeyGetBlockSize(privateKey); 66 | uint8_t *decData = malloc(blockSize); 67 | bzero(decData, blockSize); 68 | SecPadding rsaPdd; 69 | switch (pdType) { 70 | case RSAPaddingNONE: 71 | rsaPdd = kSecPaddingNone; 72 | break; 73 | case RSAPaddingPKCS1: 74 | rsaPdd = kSecPaddingPKCS1; 75 | break; 76 | case RSAPaddingOAEP: 77 | rsaPdd = kSecPaddingOAEP; 78 | break; 79 | 80 | default: 81 | rsaPdd = kSecPaddingPKCS1; 82 | break; 83 | } 84 | 85 | ret = SecKeyDecrypt(privateKey, rsaPdd, self.bytes, self.length, decData, &blockSize); 86 | if (ret==errSecSuccess) { 87 | retData = [NSData dataWithBytes:decData length:blockSize]; 88 | } 89 | free(decData); 90 | decData = NULL; 91 | return retData; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /NSData+KKSignVerify.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKSignVerify.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "NSData+KKSignVerify.h" 10 | #import 11 | 12 | @implementation NSData (KKSignVerify) 13 | 14 | /** 15 | 根据不同的算法,签名数据, 16 | */ 17 | - (NSData *)signDataWith:(SecKeyRef)privateKey algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm 18 | { 19 | if (!privateKey || self.length <1) { 20 | return nil; 21 | } 22 | 23 | OSStatus ret; 24 | NSData *retData = nil; 25 | size_t siglen = SecKeyGetBlockSize(privateKey); 26 | uint8_t *sig = malloc(siglen); 27 | bzero(sig, siglen); 28 | 29 | SecPadding secpdal ; 30 | switch (ccAlgorithm) { 31 | case SEC_PKCS1SHA1: 32 | secpdal = kSecPaddingPKCS1SHA1; 33 | break; 34 | case SEC_PKCS1SHA224: 35 | secpdal = kSecPaddingPKCS1SHA224; 36 | break; 37 | case SEC_PKCS1SHA256: 38 | secpdal = kSecPaddingPKCS1SHA256; 39 | break; 40 | case SEC_PKCS1SHA384: 41 | secpdal = kSecPaddingPKCS1SHA384; 42 | break; 43 | case SEC_PKCS1SHA512: 44 | secpdal = kSecPaddingPKCS1SHA512; 45 | break; 46 | default: 47 | secpdal = kSecPaddingPKCS1SHA1; 48 | break; 49 | } 50 | 51 | ret = SecKeyRawSign(privateKey, secpdal, self.bytes, self.length, sig, &siglen); 52 | if (ret==errSecSuccess) { 53 | retData = [NSData dataWithBytes:sig length:siglen]; 54 | } 55 | 56 | free(sig); 57 | sig = NULL; 58 | 59 | return retData; 60 | } 61 | 62 | /** 63 | 验证签名 64 | */ 65 | - (BOOL)verifySignWith:(SecKeyRef)publicKey signData:(NSData *)signData algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm 66 | { 67 | if (!publicKey || self.length <1) { 68 | return NO; 69 | } 70 | OSStatus ret; 71 | BOOL retStatus = NO; 72 | SecPadding secpdal ; 73 | switch (ccAlgorithm) { 74 | case SEC_PKCS1SHA1: 75 | secpdal = kSecPaddingPKCS1SHA1; 76 | break; 77 | case SEC_PKCS1SHA224: 78 | secpdal = kSecPaddingPKCS1SHA224; 79 | break; 80 | case SEC_PKCS1SHA256: 81 | secpdal = kSecPaddingPKCS1SHA256; 82 | break; 83 | case SEC_PKCS1SHA384: 84 | secpdal = kSecPaddingPKCS1SHA384; 85 | break; 86 | case SEC_PKCS1SHA512: 87 | secpdal = kSecPaddingPKCS1SHA512; 88 | break; 89 | default: 90 | secpdal = kSecPaddingPKCS1SHA1; 91 | break; 92 | } 93 | ret = SecKeyRawVerify(publicKey, secpdal, self.bytes, self.length,signData.bytes, signData.length); 94 | if (ret==errSecSuccess) { 95 | retStatus = YES; 96 | } 97 | return retStatus; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /NSData+KKAES.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKAES.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "NSData+KKAES.h" 10 | #import 11 | 12 | @implementation NSData (KKAES) 13 | - (NSData *)AES_CBC_EncryptWith:(NSData *)key iv:(NSData *)iv 14 | { 15 | NSData *retData = nil; 16 | NSUInteger dataLength = [self length]; 17 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 18 | void *buffer = malloc(bufferSize); 19 | bzero(buffer, bufferSize); 20 | size_t numBytesEncrypted = 0; 21 | CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 22 | kCCOptionPKCS7Padding, 23 | key.bytes, key.length, 24 | iv.bytes, 25 | self.bytes, self.length, 26 | buffer, bufferSize, 27 | &numBytesEncrypted); 28 | if (cryptStatus == kCCSuccess) { 29 | retData = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 30 | } 31 | free(buffer); 32 | return retData; 33 | 34 | } 35 | 36 | - (NSData *)AES_CBC_DecryptWith:(NSData *)key iv:(NSData *)iv 37 | { 38 | NSData *retData = nil; 39 | NSUInteger dataLength = [self length]; 40 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 41 | void *buffer = malloc(bufferSize); 42 | bzero(buffer, bufferSize); 43 | size_t numBytesEncrypted = 0; 44 | CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 45 | kCCOptionPKCS7Padding, 46 | key.bytes, key.length, 47 | iv.bytes, 48 | self.bytes, self.length, 49 | buffer, bufferSize, 50 | &numBytesEncrypted); 51 | if (cryptStatus == kCCSuccess) { 52 | retData = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 53 | } 54 | free(buffer); 55 | return retData; 56 | } 57 | 58 | 59 | - (NSData *)AES_ECB_EncryptWith:(NSData *)key 60 | { 61 | NSData *retData = nil; 62 | NSUInteger dataLength = [self length]; 63 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 64 | void *buffer = malloc(bufferSize); 65 | bzero(buffer, bufferSize); 66 | size_t numBytesEncrypted = 0; 67 | CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 68 | kCCOptionPKCS7Padding|kCCOptionECBMode, 69 | key.bytes, key.length, 70 | NULL, 71 | self.bytes, self.length, 72 | buffer, bufferSize, 73 | &numBytesEncrypted); 74 | if (cryptStatus == kCCSuccess) { 75 | retData = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 76 | } 77 | free(buffer); 78 | return retData; 79 | } 80 | 81 | - (NSData *)AES_ECB_DecryptWith:(NSData *)key 82 | { 83 | NSData *retData = nil; 84 | NSUInteger dataLength = [self length]; 85 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 86 | void *buffer = malloc(bufferSize); 87 | bzero(buffer, bufferSize); 88 | size_t numBytesEncrypted = 0; 89 | CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 90 | kCCOptionPKCS7Padding|kCCOptionECBMode, 91 | key.bytes, key.length, 92 | NULL, 93 | self.bytes, self.length, 94 | buffer, bufferSize, 95 | &numBytesEncrypted); 96 | if (cryptStatus == kCCSuccess) { 97 | retData = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 98 | } 99 | free(buffer); 100 | return retData; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /NSData+KKHASH.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+KKHASH.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/15. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "NSData+KKHASH.h" 10 | #include 11 | 12 | @implementation NSData (KKHASH) 13 | - (NSData *)hashDataWith:(CCDIGESTAlgorithm )ccAlgorithm 14 | { 15 | NSData *retData = nil; 16 | if (self.length <1) { 17 | return nil; 18 | } 19 | 20 | unsigned char *md; 21 | 22 | switch (ccAlgorithm) { 23 | case CCDIGEST_MD2: 24 | { 25 | md = malloc(CC_MD2_DIGEST_LENGTH); 26 | bzero(md, CC_MD2_DIGEST_LENGTH); 27 | CC_MD2(self.bytes, (CC_LONG)self.length, md); 28 | retData = [NSData dataWithBytes:md length:CC_MD2_DIGEST_LENGTH]; 29 | } 30 | break; 31 | case CCDIGEST_MD4: 32 | { 33 | md = malloc(CC_MD4_DIGEST_LENGTH); 34 | bzero(md, CC_MD4_DIGEST_LENGTH); 35 | CC_MD4(self.bytes, (CC_LONG)self.length, md); 36 | retData = [NSData dataWithBytes:md length:CC_MD4_DIGEST_LENGTH]; 37 | 38 | } 39 | break; 40 | case CCDIGEST_MD5: 41 | { 42 | md = malloc(CC_MD5_DIGEST_LENGTH); 43 | bzero(md, CC_MD5_DIGEST_LENGTH); 44 | CC_MD5(self.bytes, (CC_LONG)self.length, md); 45 | retData = [NSData dataWithBytes:md length:CC_MD5_DIGEST_LENGTH]; 46 | 47 | } 48 | break; 49 | case CCDIGEST_SHA1: 50 | { 51 | md = malloc(CC_SHA1_DIGEST_LENGTH); 52 | bzero(md, CC_SHA1_DIGEST_LENGTH); 53 | CC_SHA1(self.bytes, (CC_LONG)self.length, md); 54 | retData = [NSData dataWithBytes:md length:CC_SHA1_DIGEST_LENGTH]; 55 | 56 | } 57 | break; 58 | case CCDIGEST_SHA224: 59 | { 60 | md = malloc(CC_SHA224_DIGEST_LENGTH); 61 | bzero(md, CC_SHA224_DIGEST_LENGTH); 62 | CC_SHA224(self.bytes, (CC_LONG)self.length, md); 63 | retData = [NSData dataWithBytes:md length:CC_SHA224_DIGEST_LENGTH]; 64 | 65 | } 66 | break; 67 | case CCDIGEST_SHA256: 68 | { 69 | md = malloc(CC_SHA256_DIGEST_LENGTH); 70 | bzero(md, CC_SHA256_DIGEST_LENGTH); 71 | CC_SHA256(self.bytes, (CC_LONG)self.length, md); 72 | retData = [NSData dataWithBytes:md length:CC_SHA256_DIGEST_LENGTH]; 73 | 74 | } 75 | break; 76 | case CCDIGEST_SHA384: 77 | { 78 | md = malloc(CC_SHA384_DIGEST_LENGTH); 79 | bzero(md, CC_SHA384_DIGEST_LENGTH); 80 | CC_SHA384(self.bytes, (CC_LONG)self.length, md); 81 | retData = [NSData dataWithBytes:md length:CC_SHA384_DIGEST_LENGTH]; 82 | 83 | } 84 | break; 85 | case CCDIGEST_SHA512: 86 | { 87 | md = malloc(CC_SHA512_DIGEST_LENGTH); 88 | bzero(md, CC_SHA512_DIGEST_LENGTH); 89 | CC_SHA512(self.bytes, (CC_LONG)self.length, md); 90 | retData = [NSData dataWithBytes:md length:CC_SHA512_DIGEST_LENGTH]; 91 | 92 | } 93 | break; 94 | 95 | default: 96 | md = malloc(1); 97 | break; 98 | } 99 | 100 | free(md); 101 | md = NULL; 102 | 103 | return retData; 104 | 105 | } 106 | 107 | 108 | - (NSString *)hexString 109 | { 110 | NSMutableString *result = nil; 111 | if (self.length <1) { 112 | return nil; 113 | } 114 | result = [[NSMutableString alloc] initWithCapacity:self.length * 2]; 115 | for (size_t i = 0; i < self.length; i++) { 116 | [result appendFormat:@"%02x", ((const uint8_t *) self.bytes)[i]]; 117 | } 118 | return result; 119 | } 120 | 121 | 122 | + (NSData *)dataWithHexString:(NSString *)hexString { 123 | NSMutableData * result; 124 | NSUInteger cursor; 125 | NSUInteger limit; 126 | 127 | NSParameterAssert(hexString != nil); 128 | 129 | result = nil; 130 | cursor = 0; 131 | limit = hexString.length; 132 | if ((limit % 2) == 0) { 133 | result = [[NSMutableData alloc] init]; 134 | 135 | while (cursor != limit) { 136 | unsigned int thisUInt; 137 | uint8_t thisByte; 138 | 139 | if ( sscanf([hexString substringWithRange:NSMakeRange(cursor, 2)].UTF8String, "%x", &thisUInt) != 1 ) { 140 | result = nil; 141 | break; 142 | } 143 | thisByte = (uint8_t) thisUInt; 144 | [result appendBytes:&thisByte length:sizeof(thisByte)]; 145 | cursor += 2; 146 | } 147 | } 148 | 149 | return result; 150 | } 151 | @end 152 | -------------------------------------------------------------------------------- /SecKeyTools.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecKeyTools.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/16. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "SecKeyTools.h" 10 | 11 | @implementation SecKeyTools 12 | 13 | /** 14 | 从x509 cer证书中读取公钥 15 | */ 16 | + (SecKeyRef )publicKeyFromCer:(NSString *)cerFile 17 | { 18 | OSStatus err; 19 | NSData * certData; 20 | SecCertificateRef cert; 21 | SecPolicyRef policy; 22 | SecTrustRef trust; 23 | SecTrustResultType trustResult; 24 | SecKeyRef publicKeyRef; 25 | 26 | certData = [NSData dataWithContentsOfFile:cerFile]; 27 | cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData); 28 | policy = SecPolicyCreateBasicX509(); 29 | err = SecTrustCreateWithCertificates(cert, policy, &trust); 30 | NSAssert(err==errSecSuccess,@"证书加载失败"); 31 | err = SecTrustEvaluate(trust, &trustResult); 32 | NSAssert(err==errSecSuccess,@"公钥加载失败"); 33 | publicKeyRef = SecTrustCopyPublicKey(trust); 34 | 35 | CFRelease(policy); 36 | CFRelease(cert); 37 | return publicKeyRef; 38 | } 39 | 40 | 41 | 42 | /** 43 | 从 p12 文件中读取私钥,一般p12都有密码 44 | */ 45 | + (SecKeyRef )privateKeyFromP12:(NSString *)p12File password:(NSString *)pwd 46 | 47 | { 48 | NSData * pkcs12Data; 49 | CFArrayRef imported; 50 | NSDictionary * importedItem; 51 | SecIdentityRef identity; 52 | OSStatus err; 53 | SecKeyRef privateKeyRef; 54 | 55 | pkcs12Data = [NSData dataWithContentsOfFile:p12File]; 56 | err = SecPKCS12Import((__bridge CFDataRef)pkcs12Data,(__bridge CFDictionaryRef) @{(__bridge NSString *)kSecImportExportPassphrase:pwd}, &imported); 57 | NSAssert(err==errSecSuccess,@"p12加载失败"); 58 | importedItem = (__bridge NSDictionary *) CFArrayGetValueAtIndex(imported, 0); 59 | identity = (__bridge SecIdentityRef) importedItem[(__bridge NSString *) kSecImportItemIdentity]; 60 | 61 | err = SecIdentityCopyPrivateKey(identity, &privateKeyRef); 62 | NSAssert(err==errSecSuccess,@"私钥加载失败"); 63 | CFRelease(imported); 64 | 65 | 66 | return privateKeyRef; 67 | } 68 | 69 | 70 | + (SecKeyRef )publicKeyFromPem:(NSString *)pemFile keySize:(size_t )size 71 | { 72 | SecKeyRef pubkeyref; 73 | NSError *readFErr = nil; 74 | CFErrorRef errref = noErr; 75 | NSString *pemStr = [NSString stringWithContentsOfFile:pemFile encoding:NSASCIIStringEncoding error:&readFErr]; 76 | NSAssert(readFErr==nil, @"pem文件加载失败"); 77 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----" withString:@""]; 78 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 79 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 80 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"-----END PUBLIC KEY-----" withString:@""]; 81 | NSData *dataPubKey = [[NSData alloc]initWithBase64EncodedString:pemStr options:0]; 82 | 83 | NSMutableDictionary *dicPubkey = [[NSMutableDictionary alloc]initWithCapacity:1]; 84 | [dicPubkey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 85 | [dicPubkey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass]; 86 | [dicPubkey setObject:@(size) forKey:(__bridge id)kSecAttrKeySizeInBits]; 87 | 88 | pubkeyref = SecKeyCreateWithData((__bridge CFDataRef)dataPubKey, (__bridge CFDictionaryRef)dicPubkey, &errref); 89 | 90 | NSAssert(errref==noErr, @"公钥加载错误"); 91 | 92 | return pubkeyref; 93 | } 94 | 95 | + (SecKeyRef )privaKeyFromPem:(NSString *)pemFile keySize:(size_t )size 96 | { 97 | SecKeyRef prikeyRef; 98 | NSError *readFErr = nil; 99 | CFErrorRef err = noErr; 100 | 101 | NSString *pemStr = [NSString stringWithContentsOfFile:pemFile encoding:NSASCIIStringEncoding error:&readFErr]; 102 | NSAssert(readFErr==nil, @"pem文件加载失败"); 103 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"-----BEGIN RSA PRIVATE KEY-----" withString:@""]; 104 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 105 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 106 | pemStr = [pemStr stringByReplacingOccurrencesOfString:@"-----END RSA PRIVATE KEY-----" withString:@""]; 107 | NSData *pemData = [[NSData alloc]initWithBase64EncodedString:pemStr options:0]; 108 | 109 | NSMutableDictionary *dicPrikey = [[NSMutableDictionary alloc]initWithCapacity:1]; 110 | [dicPrikey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 111 | [dicPrikey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)kSecAttrKeyClass]; 112 | [dicPrikey setObject:@(size) forKey:(__bridge id)kSecAttrKeySizeInBits]; 113 | 114 | prikeyRef = SecKeyCreateWithData((__bridge CFDataRef)pemData, (__bridge CFDictionaryRef)dicPrikey, &err); 115 | NSAssert(err==noErr, @"私钥加载错误"); 116 | 117 | 118 | return prikeyRef; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /SecurityiOS/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SecurityiOS 4 | // 5 | // Created by cocoa on 16/12/14. 6 | // Copyright © 2016年 dev.keke@gmail.com. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import "NSData+KKHASH.h" 12 | #import "NSData+KKSignVerify.h" 13 | #import "NSData+KKRSA.h" 14 | #import "NSData+KKAES.h" 15 | #import "SecKeyTools.h" 16 | 17 | @interface ViewController () 18 | 19 | @end 20 | 21 | @implementation ViewController 22 | 23 | //生成RSA密钥对,公钥和私钥,支持的SIZE有 24 | // sizes for RSA keys are: 512, 768, 1024, 2048. 25 | - (void)generateRSAKeyPair:(int )keySize 26 | { 27 | if (publicKeyRef) { 28 | return; 29 | } 30 | OSStatus ret = 0; 31 | publicKeyRef = NULL; 32 | privateKeyRef = NULL; 33 | ret = SecKeyGeneratePair((CFDictionaryRef)@{(id)kSecAttrKeyType:(id)kSecAttrKeyTypeRSA,(id)kSecAttrKeySizeInBits:@(keySize)}, &publicKeyRef, &privateKeyRef); 34 | NSAssert(ret==errSecSuccess, @"密钥对生成失败:%d",ret); 35 | 36 | NSLog(@"%@",publicKeyRef); 37 | NSLog(@"%@",privateKeyRef); 38 | NSLog(@"max size:%lu",SecKeyGetBlockSize(privateKeyRef)); 39 | 40 | } 41 | 42 | //公钥加密私钥密钥测试 43 | /** 三种填充方式区别 44 | kSecPaddingNone = 0, 要加密的数据块大小<=SecKeyGetBlockSize的大小,如这里128 45 | kSecPaddingPKCS1 = 1, 要加密的数据块大小<=128-11 46 | kSecPaddingOAEP = 2, 要加密的数据块大小<=128-42 47 | 密码学中的设计原则,一般用RSA来加密 对称密钥,用对称密钥加密大量的数据 48 | 非对称加密速度慢,对称加密速度快 49 | */ 50 | - (void)testRSAEncryptAndDecrypt 51 | { 52 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 53 | 54 | NSData *srcData = [@"0123456789" dataUsingEncoding:NSUTF8StringEncoding]; 55 | NSLog(@"%@",srcData); 56 | uint8_t encData[kRSA_KEY_SIZE/8] = {0}; 57 | uint8_t decData[kRSA_KEY_SIZE/8] = {0}; 58 | size_t blockSize = kRSA_KEY_SIZE / 8 ; 59 | OSStatus ret; 60 | 61 | 62 | ret = SecKeyEncrypt(publicKeyRef, kSecPaddingNone, srcData.bytes, srcData.length, encData, &blockSize); 63 | NSAssert(ret==errSecSuccess, @"加密失败"); 64 | 65 | 66 | ret = SecKeyDecrypt(privateKeyRef, kSecPaddingNone, encData, blockSize, decData, &blockSize); 67 | NSAssert(ret==errSecSuccess, @"解密失败"); 68 | 69 | NSData *dedData = [NSData dataWithBytes:decData length:blockSize]; 70 | NSLog(@"dec:%@",dedData); 71 | if (memcmp(srcData.bytes, dedData.bytes, srcData.length)==0) { 72 | NSLog(@"PASS"); 73 | } 74 | } 75 | 76 | 77 | //测试哈希函数 78 | - (void)testKKHASHTools 79 | { 80 | //以下结果由openssl dtsg 命令得出的结果,并和这里相比对 81 | NSString *tpath = [[NSBundle mainBundle] pathForResource:@"src.txt" ofType:nil]; 82 | NSData *test = [NSData dataWithContentsOfFile:tpath]; 83 | NSLog(@"%@",[[test hashDataWith:CCDIGEST_MD2] hexString]); 84 | if([[[test hashDataWith:CCDIGEST_MD4] hexString] isEqualToString:@"a695ea9f14a89c4e82ca5cf52a28d45d"]) 85 | { 86 | NSLog(@"MD4 TEST PASS"); 87 | } 88 | if([[[test hashDataWith:CCDIGEST_MD5] hexString] isEqualToString:@"781e5e245d69b566979b86e28d23f2c7"]) 89 | { 90 | NSLog(@"MD5 TEST PASS"); 91 | } 92 | if([[[test hashDataWith:CCDIGEST_SHA1] hexString] isEqualToString:@"87acec17cd9dcd20a716cc2cf67417b71c8a7016"]) 93 | { 94 | NSLog(@"SHA1 TEST PASS"); 95 | } 96 | if([[[test hashDataWith:CCDIGEST_SHA224] hexString] isEqualToString:@"f28ad8ecd48ba6f914c114821685ad08f0d6103649ff156599a90426"]) 97 | { 98 | NSLog(@"SHA224 TEST PASS"); 99 | } 100 | if([[[test hashDataWith:CCDIGEST_SHA256] hexString] isEqualToString:@"84d89877f0d4041efb6bf91a16f0248f2fd573e6af05c19f96bedb9f882f7882"]) 101 | { 102 | NSLog(@"SHA256 TEST PASS"); 103 | } 104 | if([[[test hashDataWith:CCDIGEST_SHA384] hexString] isEqualToString:@"90ae531f24e48697904a4d0286f354c50a350ebb6c2b9efcb22f71c96ceaeffc11c6095e9ca0df0ec30bf685dcf2e5e5"]) 105 | { 106 | NSLog(@"SHA384 TEST PASS"); 107 | } 108 | if([[[test hashDataWith:CCDIGEST_SHA512] hexString] isEqualToString:@"bb96c2fc40d2d54617d6f276febe571f623a8dadf0b734855299b0e107fda32cf6b69f2da32b36445d73690b93cbd0f7bfc20e0f7f28553d2a4428f23b716e90"]) 109 | { 110 | NSLog(@"SHA512 TEST PASS"); 111 | } 112 | 113 | } 114 | 115 | /** 116 | 签名与验证签名 117 | */ 118 | 119 | - (void)testSignAndVerify 120 | { 121 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 122 | 123 | 124 | NSString *tpath = [[NSBundle mainBundle] pathForResource:@"src.txt" ofType:nil]; 125 | NSData *ttDt = [NSData dataWithContentsOfFile:tpath]; 126 | NSData *sha1dg = [ttDt hashDataWith:CCDIGEST_SHA1]; 127 | 128 | OSStatus ret; 129 | 130 | 131 | //私钥签名,公钥验证签名 132 | size_t siglen = SecKeyGetBlockSize(privateKeyRef); 133 | uint8_t *sig = malloc(siglen); 134 | bzero(sig, siglen); 135 | ret = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1SHA256, sha1dg.bytes, sha1dg.length, sig, &siglen); 136 | NSAssert(ret==errSecSuccess, @"签名失败"); 137 | 138 | 139 | ret = SecKeyRawVerify(publicKeyRef, kSecPaddingPKCS1SHA256, sha1dg.bytes, sha1dg.length,sig, siglen); 140 | NSAssert(ret==errSecSuccess, @"验证签名失败"); 141 | 142 | if (ret==errSecSuccess) { 143 | NSLog(@"SIGN VERIFY PASS"); 144 | } 145 | } 146 | 147 | 148 | //测试签名与验证签名工具 149 | - (void)testkksignVerifyTools 150 | { 151 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 152 | 153 | NSString *tpath = [[NSBundle mainBundle] pathForResource:@"src.txt" ofType:nil]; 154 | NSData *ttDt = [NSData dataWithContentsOfFile:tpath]; 155 | NSData *sha1dg = [ttDt hashDataWith:CCDIGEST_MD4]; 156 | 157 | 158 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA1] algorithm:SEC_PKCS1SHA1]) { 159 | NSLog(@"SIGN-VERIFY sha1 PASS"); 160 | } 161 | 162 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA224] algorithm:SEC_PKCS1SHA224]) { 163 | NSLog(@"SIGN-VERIFY sha224 PASS"); 164 | } 165 | 166 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA256] algorithm:SEC_PKCS1SHA256]) { 167 | NSLog(@"SIGN-VERIFY sha256 PASS"); 168 | } 169 | 170 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA384] algorithm:SEC_PKCS1SHA384]) { 171 | NSLog(@"SIGN-VERIFY sha384 PASS"); 172 | } 173 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA512] algorithm:SEC_PKCS1SHA512]) { 174 | NSLog(@"SIGN-VERIFY sha512 PASS"); 175 | } 176 | 177 | 178 | } 179 | 180 | - (void)testKKRSATools 181 | { 182 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 183 | NSData *srcData = [@"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567" dataUsingEncoding:NSASCIIStringEncoding]; 184 | //max 128 185 | NSData *decData = [[srcData RSAEncryptWith:publicKeyRef paddingType:RSAPaddingNONE] RSADecryptWith:privateKeyRef paddingType:RSAPaddingNONE]; 186 | 187 | if (memcmp(srcData.bytes, decData.bytes, srcData.length)==0) { 188 | NSLog(@"RSA RSAPaddingNONE TEST PASS"); 189 | } 190 | 191 | 192 | NSData *srcData2 = [@"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" dataUsingEncoding:NSASCIIStringEncoding]; 193 | //max 128-11 117 194 | NSData *decData2 = [[srcData2 RSAEncryptWith:publicKeyRef paddingType:RSAPaddingPKCS1] 195 | RSADecryptWith:privateKeyRef paddingType:RSAPaddingPKCS1]; 196 | 197 | if (memcmp(srcData2.bytes, decData2.bytes, srcData2.length)==0) { 198 | NSLog(@"RSA RSAPaddingPKCS1 TEST PASS"); 199 | } 200 | 201 | 202 | NSData *srcData3 = [@"01234567890123456789012345678901234567890123456789012345678901234567890123456789123456" dataUsingEncoding:NSASCIIStringEncoding]; 203 | //max 128-42 86 204 | NSData *decData3 = [[srcData3 RSAEncryptWith:publicKeyRef paddingType:RSAPaddingOAEP] RSADecryptWith:privateKeyRef paddingType:RSAPaddingOAEP]; 205 | 206 | if (memcmp(srcData3.bytes, decData3.bytes, srcData3.length)==0) { 207 | NSLog(@"RSA RSAPaddingOAEP TEST PASS"); 208 | } 209 | 210 | 211 | 212 | } 213 | 214 | 215 | - (void)testAESKKTools 216 | { 217 | NSData *key16 = [@"0123456789123456" dataUsingEncoding:NSUTF8StringEncoding]; 218 | NSData *key24 = [@"012345678901234567891234" dataUsingEncoding:NSUTF8StringEncoding]; 219 | NSData *key32 = [@"01234567890123456789012345678912" dataUsingEncoding:NSUTF8StringEncoding]; 220 | NSData *iv16 = [@"0123456789654321" dataUsingEncoding:NSUTF8StringEncoding]; 221 | NSData *srcData = [@"this is src test data" dataUsingEncoding:NSUTF8StringEncoding]; 222 | NSLog(@"%@",srcData); 223 | 224 | 225 | 226 | NSData *dec16 = [[srcData AES_CBC_EncryptWith:key16 iv:iv16] AES_CBC_DecryptWith:key16 iv:iv16]; 227 | if (memcmp(srcData.bytes, dec16.bytes, srcData.length)==0) { 228 | NSLog(@"AES_cbc_16 PASS"); 229 | } 230 | 231 | 232 | NSData *dec24 = [[srcData AES_CBC_EncryptWith:key24 iv:iv16] AES_CBC_DecryptWith:key24 iv:iv16]; 233 | if (memcmp(srcData.bytes, dec24.bytes, srcData.length)==0) { 234 | NSLog(@"AES_cbc_24 PASS"); 235 | } 236 | 237 | 238 | NSData *dec32 = [[srcData AES_CBC_EncryptWith:key32 iv:iv16] AES_CBC_DecryptWith:key32 iv:iv16]; 239 | if (memcmp(srcData.bytes, dec32.bytes, srcData.length)==0) { 240 | NSLog(@"AES_cbc_32 PASS"); 241 | } 242 | 243 | 244 | 245 | 246 | NSData *edec16 = [[srcData AES_ECB_EncryptWith:key16] AES_ECB_DecryptWith:key16]; 247 | if (memcmp(srcData.bytes, edec16.bytes, srcData.length)==0) { 248 | NSLog(@"AES_ecb_16 PASS"); 249 | } 250 | 251 | 252 | NSData *edec24 = [[srcData AES_ECB_EncryptWith:key24] AES_ECB_DecryptWith:key24]; 253 | if (memcmp(srcData.bytes, edec24.bytes, srcData.length)==0) { 254 | NSLog(@"AES_ecb_24 PASS"); 255 | } 256 | 257 | 258 | NSData *edec32 = [[srcData AES_ECB_EncryptWith:key32] AES_ECB_DecryptWith:key32]; 259 | if (memcmp(srcData.bytes, edec32.bytes, srcData.length)==0) { 260 | NSLog(@"AES_ecb_32 PASS"); 261 | } 262 | 263 | 264 | 265 | } 266 | 267 | - (void)testReadKeyFromFiles 268 | { 269 | NSString *cerPA = [[NSBundle mainBundle] pathForResource:@"CPPUB.cer" ofType:nil]; 270 | NSString *p12PA = [[NSBundle mainBundle] pathForResource:@"CPPRI.p12" ofType:nil]; 271 | 272 | SecKeyRef pubkey = [SecKeyTools publicKeyFromCer:cerPA]; 273 | SecKeyRef prikey = [SecKeyTools privateKeyFromP12:p12PA password:@"test"]; 274 | 275 | NSLog(@"%@",pubkey); 276 | NSLog(@"%@",prikey); 277 | 278 | NSLog(@"%lu",SecKeyGetBlockSize(prikey)); 279 | 280 | 281 | NSData *srcData = [@"0123456789" dataUsingEncoding:NSUTF8StringEncoding]; 282 | NSLog(@"%@",srcData); 283 | NSData *encDT = [srcData RSAEncryptWith:pubkey paddingType:RSAPaddingPKCS1]; 284 | NSData *decDT = [encDT RSADecryptWith:prikey paddingType:RSAPaddingPKCS1]; 285 | NSLog(@"%@",decDT); 286 | 287 | 288 | 289 | NSString *pripem = [[NSBundle mainBundle] pathForResource:@"private.pem" ofType:nil]; 290 | NSString *pubpem = [[NSBundle mainBundle] pathForResource:@"public.pem" ofType:nil]; 291 | SecKeyRef pubKK = [SecKeyTools publicKeyFromPem:pubpem keySize:kRSA_KEY_SIZE]; 292 | SecKeyRef priKK = [SecKeyTools privaKeyFromPem:pripem keySize:kRSA_KEY_SIZE]; 293 | NSLog(@"%@",pubKK); 294 | NSLog(@"%@",priKK); 295 | 296 | NSLog(@"%lu",SecKeyGetBlockSize(priKK)); 297 | NSData *srcData2 = [@"0123456789" dataUsingEncoding:NSUTF8StringEncoding]; 298 | NSLog(@"%@",srcData2); 299 | NSData *encDT2 = [srcData2 RSAEncryptWith:pubKK paddingType:RSAPaddingPKCS1]; 300 | NSData *decDT2 = [encDT2 RSADecryptWith:priKK paddingType:RSAPaddingPKCS1]; 301 | NSLog(@"%@",decDT2); 302 | 303 | 304 | } 305 | 306 | - (void)viewDidLoad { 307 | [super viewDidLoad]; 308 | 309 | 310 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 311 | 312 | [self testRSAEncryptAndDecrypt]; 313 | [self testKKHASHTools]; 314 | [self testSignAndVerify]; 315 | [self testkksignVerifyTools]; 316 | 317 | [self testKKRSATools]; 318 | [self testAESKKTools]; 319 | 320 | [self testReadKeyFromFiles]; 321 | 322 | 323 | 324 | 325 | 326 | 327 | } 328 | 329 | 330 | 331 | 332 | 333 | - (void)didReceiveMemoryWarning { 334 | [super didReceiveMemoryWarning]; 335 | // Dispose of any resources that can be recreated. 336 | } 337 | 338 | 339 | @end 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Security-iOS 2 | 3 | 封装了一些iOS上使用的NSData分类,主要用于 `RSA加密`,`AES加密`,`数据签名`,`签名校验`,`MD5 SHA1 SHA256 常用hash`等工具。 4 | 5 | 主要使用的是iOS上 `Security.framework` 和 `CommonCrypto` 接口 6 | 7 | 支持iOS2.0+开发 8 | 9 | 10 | ## md5,sha1,sha256常用hash 11 | 12 | 接口文件和源码 `NSData+KKHASH.h`,`NSData+KKHASH.m` 13 | 14 | 支持的hash算法有 15 | 16 | ```objective-c 17 | typedef enum : NSUInteger { 18 | //md2 16字节长度 19 | CCDIGEST_MD2 = 1000, 20 | //md4 16字节长度 21 | CCDIGEST_MD4, 22 | //md5 16字节长度 23 | CCDIGEST_MD5, 24 | //sha1 20字节长度 25 | CCDIGEST_SHA1, 26 | //SHA224 28字节长度 27 | CCDIGEST_SHA224, 28 | //SHA256 32字节长度 29 | CCDIGEST_SHA256, 30 | //SHA384 48字节长度 31 | CCDIGEST_SHA384, 32 | //SHA512 64字节长度 33 | CCDIGEST_SHA512, 34 | } CCDIGESTAlgorithm; 35 | ``` 36 | 37 | 调用接口 38 | 39 | ```objective-c 40 | /** 41 | 计算数据的hash值,根据不同的算法 42 | */ 43 | - (NSData *)hashDataWith:(CCDIGESTAlgorithm )ccAlgorithm; 44 | 45 | 46 | /** 47 | 返回 hex string的 data 48 | */ 49 | - (NSString *)hexString; 50 | ``` 51 | 52 | 调用示例 53 | 54 | ```objective-c 55 | //测试哈希函数 56 | - (void)testKKHASHTools 57 | { 58 | //以下结果由openssl dtsg 命令得出的结果,并和这里相比对 59 | NSString *tpath = [[NSBundle mainBundle] pathForResource:@"src.txt" ofType:nil]; 60 | NSData *test = [NSData dataWithContentsOfFile:tpath]; 61 | NSLog(@"%@",[[test hashDataWith:CCDIGEST_MD2] hexString]); 62 | if([[[test hashDataWith:CCDIGEST_MD4] hexString] isEqualToString:@"a695ea9f14a89c4e82ca5cf52a28d45d"]) 63 | { 64 | NSLog(@"MD4 TEST PASS"); 65 | } 66 | if([[[test hashDataWith:CCDIGEST_MD5] hexString] isEqualToString:@"781e5e245d69b566979b86e28d23f2c7"]) 67 | { 68 | NSLog(@"MD5 TEST PASS"); 69 | } 70 | if([[[test hashDataWith:CCDIGEST_SHA1] hexString] isEqualToString:@"87acec17cd9dcd20a716cc2cf67417b71c8a7016"]) 71 | { 72 | NSLog(@"SHA1 TEST PASS"); 73 | } 74 | if([[[test hashDataWith:CCDIGEST_SHA224] hexString] isEqualToString:@"f28ad8ecd48ba6f914c114821685ad08f0d6103649ff156599a90426"]) 75 | { 76 | NSLog(@"SHA224 TEST PASS"); 77 | } 78 | if([[[test hashDataWith:CCDIGEST_SHA256] hexString] isEqualToString:@"84d89877f0d4041efb6bf91a16f0248f2fd573e6af05c19f96bedb9f882f7882"]) 79 | { 80 | NSLog(@"SHA256 TEST PASS"); 81 | } 82 | if([[[test hashDataWith:CCDIGEST_SHA384] hexString] isEqualToString:@"90ae531f24e48697904a4d0286f354c50a350ebb6c2b9efcb22f71c96ceaeffc11c6095e9ca0df0ec30bf685dcf2e5e5"]) 83 | { 84 | NSLog(@"SHA384 TEST PASS"); 85 | } 86 | if([[[test hashDataWith:CCDIGEST_SHA512] hexString] isEqualToString:@"bb96c2fc40d2d54617d6f276febe571f623a8dadf0b734855299b0e107fda32cf6b69f2da32b36445d73690b93cbd0f7bfc20e0f7f28553d2a4428f23b716e90"]) 87 | { 88 | NSLog(@"SHA512 TEST PASS"); 89 | } 90 | 91 | } 92 | ``` 93 | 94 | ## AES 加密解密 95 | 96 | 接口文件和源码 `NSData+KKAES.h`,`NSData+KKAES.m` 97 | 98 | 支持AES cbc,ecb两种模式,默认使用的填充方式 `kCCOptionPKCS7Padding`. 99 | 可以参考更多 [iOS CommonCrypto 对称加密 AES ecb,cbc](http://www.cnblogs.com/cocoajin/p/6150203.html) 100 | 101 | 主要接口 102 | 103 | ```objective-c 104 | /** 105 | AES cbc 模式加密, 106 | @key 长度16字节,24字节,32字节 107 | @iv 16字节 108 | */ 109 | - (NSData *)AES_CBC_EncryptWith:(NSData *)key iv:(NSData *)iv; 110 | 111 | /** 112 | AES cbc 模式解密, 113 | @key 长度16字节,24字节,32字节 114 | @iv 16字节 115 | */ 116 | - (NSData *)AES_CBC_DecryptWith:(NSData *)key iv:(NSData *)iv; 117 | 118 | /** 119 | AES ecb 模式加密, 120 | @key 长度16字节,24字节,32字节 121 | */ 122 | - (NSData *)AES_ECB_EncryptWith:(NSData *)key; 123 | 124 | /** 125 | AES ecb 模式解密, 126 | @key 长度16字节,24字节,32字节 127 | */ 128 | - (NSData *)AES_ECB_DecryptWith:(NSData *)key; 129 | ``` 130 | 131 | 调用示例 132 | 133 | ```objective-c 134 | NSData *key16 = [@"0123456789123456" dataUsingEncoding:NSUTF8StringEncoding]; 135 | NSData *key24 = [@"012345678901234567891234" dataUsingEncoding:NSUTF8StringEncoding]; 136 | NSData *key32 = [@"01234567890123456789012345678912" dataUsingEncoding:NSUTF8StringEncoding]; 137 | NSData *iv16 = [@"0123456789654321" dataUsingEncoding:NSUTF8StringEncoding]; 138 | NSData *srcData = [@"this is src test data" dataUsingEncoding:NSUTF8StringEncoding]; 139 | NSLog(@"%@",srcData); 140 | 141 | 142 | 143 | NSData *dec16 = [[srcData AES_CBC_EncryptWith:key16 iv:iv16] AES_CBC_DecryptWith:key16 iv:iv16]; 144 | if (memcmp(srcData.bytes, dec16.bytes, srcData.length)==0) { 145 | NSLog(@"AES_cbc_16 PASS"); 146 | } 147 | 148 | 149 | NSData *dec24 = [[srcData AES_CBC_EncryptWith:key24 iv:iv16] AES_CBC_DecryptWith:key24 iv:iv16]; 150 | if (memcmp(srcData.bytes, dec24.bytes, srcData.length)==0) { 151 | NSLog(@"AES_cbc_24 PASS"); 152 | } 153 | 154 | 155 | NSData *dec32 = [[srcData AES_CBC_EncryptWith:key32 iv:iv16] AES_CBC_DecryptWith:key32 iv:iv16]; 156 | if (memcmp(srcData.bytes, dec32.bytes, srcData.length)==0) { 157 | NSLog(@"AES_cbc_32 PASS"); 158 | } 159 | 160 | 161 | 162 | 163 | NSData *edec16 = [[srcData AES_ECB_EncryptWith:key16] AES_ECB_DecryptWith:key16]; 164 | if (memcmp(srcData.bytes, edec16.bytes, srcData.length)==0) { 165 | NSLog(@"AES_ecb_16 PASS"); 166 | } 167 | 168 | 169 | NSData *edec24 = [[srcData AES_ECB_EncryptWith:key24] AES_ECB_DecryptWith:key24]; 170 | if (memcmp(srcData.bytes, edec24.bytes, srcData.length)==0) { 171 | NSLog(@"AES_ecb_24 PASS"); 172 | } 173 | 174 | 175 | NSData *edec32 = [[srcData AES_ECB_EncryptWith:key32] AES_ECB_DecryptWith:key32]; 176 | if (memcmp(srcData.bytes, edec32.bytes, srcData.length)==0) { 177 | NSLog(@"AES_ecb_32 PASS"); 178 | } 179 | ``` 180 | 181 | 182 | ## RSA 加密解密 183 | 184 | 接口和源码 `NSData+KKRSA.h`,`NSData+KKRSA.m` 185 | 186 | 支持的RSA密钥位数:512,768,1024,2048等; 187 | 可以参考更多 [iOS使用Security.framework进行RSA 加密解密签名和验证签名](http://www.cnblogs.com/cocoajin/p/6183443.html) 188 | 189 | 支持的填充方式 190 | 191 | ```objective-c 192 | //分组加密,支持最大的加密块为 block 和填充方式有关 193 | typedef enum : NSUInteger { 194 | //不填充,最大数据块为 blockSize 195 | RSAPaddingNONE, 196 | //填充方式pkcs1,最大数据块为 blockSize -11 197 | RSAPaddingPKCS1, 198 | //填充方式OAEP, 最大数据块为 blockSize -42 199 | RSAPaddingOAEP, 200 | } RSAPaddingTYPE; 201 | ``` 202 | 203 | 调用接口 204 | 205 | ```objective-c 206 | /** 207 | 公钥加密 208 | */ 209 | - (NSData *)RSAEncryptWith:(SecKeyRef )publicKey paddingType:(RSAPaddingTYPE )pdType; 210 | 211 | /** 212 | 私钥解密 213 | */ 214 | - (NSData *)RSADecryptWith:(SecKeyRef )privateKey paddingType:(RSAPaddingTYPE )pdType; 215 | ``` 216 | 217 | 调用示例 218 | 219 | ```objective-c 220 | //生成RSA密钥对,公钥和私钥,支持的SIZE有 221 | // sizes for RSA keys are: 512, 768, 1024, 2048. 222 | - (void)generateRSAKeyPair:(int )keySize 223 | { 224 | if (publicKeyRef) { 225 | return; 226 | } 227 | OSStatus ret = 0; 228 | publicKeyRef = NULL; 229 | privateKeyRef = NULL; 230 | ret = SecKeyGeneratePair((CFDictionaryRef)@{(id)kSecAttrKeyType:(id)kSecAttrKeyTypeRSA,(id)kSecAttrKeySizeInBits:@(keySize)}, &publicKeyRef, &privateKeyRef); 231 | NSAssert(ret==errSecSuccess, @"密钥对生成失败:%d",ret); 232 | 233 | NSLog(@"%@",publicKeyRef); 234 | NSLog(@"%@",privateKeyRef); 235 | NSLog(@"max size:%lu",SecKeyGetBlockSize(privateKeyRef)); 236 | 237 | } 238 | 239 | //生成密钥对 240 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 241 | 242 | NSData *srcData = [@"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567" dataUsingEncoding:NSASCIIStringEncoding]; 243 | //max 128 244 | NSData *decData = [[srcData RSAEncryptWith:publicKeyRef paddingType:RSAPaddingNONE] RSADecryptWith:privateKeyRef paddingType:RSAPaddingNONE]; 245 | 246 | if (memcmp(srcData.bytes, decData.bytes, srcData.length)==0) { 247 | NSLog(@"RSA RSAPaddingNONE TEST PASS"); 248 | } 249 | 250 | 251 | NSData *srcData2 = [@"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" dataUsingEncoding:NSASCIIStringEncoding]; 252 | //max 128-11 117 253 | NSData *decData2 = [[srcData2 RSAEncryptWith:publicKeyRef paddingType:RSAPaddingPKCS1] 254 | RSADecryptWith:privateKeyRef paddingType:RSAPaddingPKCS1]; 255 | 256 | if (memcmp(srcData2.bytes, decData2.bytes, srcData2.length)==0) { 257 | NSLog(@"RSA RSAPaddingPKCS1 TEST PASS"); 258 | } 259 | 260 | 261 | NSData *srcData3 = [@"01234567890123456789012345678901234567890123456789012345678901234567890123456789123456" dataUsingEncoding:NSASCIIStringEncoding]; 262 | //max 128-42 86 263 | NSData *decData3 = [[srcData3 RSAEncryptWith:publicKeyRef paddingType:RSAPaddingOAEP] RSADecryptWith:privateKeyRef paddingType:RSAPaddingOAEP]; 264 | 265 | if (memcmp(srcData3.bytes, decData3.bytes, srcData3.length)==0) { 266 | NSLog(@"RSA RSAPaddingOAEP TEST PASS"); 267 | } 268 | ``` 269 | 270 | 271 | ## RSA签名验证签名 272 | 273 | 接口文件和源码 `NSData+KKSignVerify.h`,`NSData+KKSignVerify.m` 274 | 275 | 数据签名一般签名数据的hash值,配合上面的HASH函数使用 276 | 277 | 支持的签名算法 278 | 279 | ```objective-c 280 | //主要使用PKCS1 方式的填充,最大签名数据长度为blockSize-11 281 | //签名算法从ios5以后不再支持md5,md2 282 | typedef enum : NSUInteger { 283 | SEC_PKCS1SHA1 = 2000, 284 | SEC_PKCS1SHA224, 285 | SEC_PKCS1SHA256, 286 | SEC_PKCS1SHA384, 287 | SEC_PKCS1SHA512, 288 | } SEC_PKCS1_ALGORITHM; 289 | ``` 290 | 291 | 主要接口 292 | 293 | ```objective-c 294 | /** 295 | 根据不同的算法,签名数据, 296 | */ 297 | - (NSData *)signDataWith:(SecKeyRef)privateKey algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm; 298 | 299 | /** 300 | 验证签名数据 301 | */ 302 | - (BOOL)verifySignWith:(SecKeyRef)publicKey signData:(NSData *)signData algorithm:(SEC_PKCS1_ALGORITHM )ccAlgorithm; 303 | ``` 304 | 305 | 调用示例 306 | 307 | ```objective-c 308 | //生成RSA密钥对, 309 | [self generateRSAKeyPair:kRSA_KEY_SIZE]; 310 | 311 | NSString *tpath = [[NSBundle mainBundle] pathForResource:@"src.txt" ofType:nil]; 312 | NSData *ttDt = [NSData dataWithContentsOfFile:tpath]; 313 | NSData *sha1dg = [ttDt hashDataWith:CCDIGEST_MD4]; 314 | 315 | 316 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA1] algorithm:SEC_PKCS1SHA1]) { 317 | NSLog(@"SIGN-VERIFY sha1 PASS"); 318 | } 319 | 320 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA224] algorithm:SEC_PKCS1SHA224]) { 321 | NSLog(@"SIGN-VERIFY sha224 PASS"); 322 | } 323 | 324 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA256] algorithm:SEC_PKCS1SHA256]) { 325 | NSLog(@"SIGN-VERIFY sha256 PASS"); 326 | } 327 | 328 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA384] algorithm:SEC_PKCS1SHA384]) { 329 | NSLog(@"SIGN-VERIFY sha384 PASS"); 330 | } 331 | if ([sha1dg verifySignWith:publicKeyRef signData:[sha1dg signDataWith:privateKeyRef algorithm:SEC_PKCS1SHA512] algorithm:SEC_PKCS1SHA512]) { 332 | NSLog(@"SIGN-VERIFY sha512 PASS"); 333 | } 334 | ``` 335 | 336 | ## RSA密钥管理 337 | 338 | 接口文件和源码 `SecKeyTools.h`,`SecKeyTools.m` 339 | 340 | 主要用于读取密钥文件中的密钥,如从证书中读取公钥,从p12文件中读取私钥等操作; 341 | RSA相关的密钥放在手机上是不安全的,但是也没有绝对的安全,视业务情况来定吧。 342 | 343 | 主要接口 344 | 345 | ```objective-c 346 | 347 | /** 348 | 从x509 cer证书中读取公钥 349 | */ 350 | + (SecKeyRef )publicKeyFromCer:(NSString *)cerFile; 351 | 352 | 353 | /** 354 | 从 p12 文件中读取私钥,一般p12都有密码 355 | */ 356 | + (SecKeyRef )privateKeyFromP12:(NSString *)p12File password:(NSString *)pwd; 357 | 358 | 359 | /** 360 | iOS 10 上可用如下接口SecKeyCreateWithData 从pem文件中读取私钥或公钥 361 | */ 362 | + (SecKeyRef )publicKeyFromPem:(NSString *)pemFile keySize:(size_t )size; 363 | 364 | + (SecKeyRef )privaKeyFromPem:(NSString *)pemFile keySize:(size_t )size; 365 | ``` 366 | 367 | 调用示例 368 | 369 | ```objective-c 370 | NSString *cerPA = [[NSBundle mainBundle] pathForResource:@"CPPUB.cer" ofType:nil]; 371 | NSString *p12PA = [[NSBundle mainBundle] pathForResource:@"CPPRI.p12" ofType:nil]; 372 | 373 | SecKeyRef pubkey = [SecKeyTools publicKeyFromCer:cerPA]; 374 | SecKeyRef prikey = [SecKeyTools privateKeyFromP12:p12PA password:@"test"]; 375 | 376 | NSLog(@"%@",pubkey); 377 | NSLog(@"%@",prikey); 378 | 379 | NSLog(@"%lu",SecKeyGetBlockSize(prikey)); 380 | 381 | 382 | NSData *srcData = [@"0123456789" dataUsingEncoding:NSUTF8StringEncoding]; 383 | NSLog(@"%@",srcData); 384 | NSData *encDT = [srcData RSAEncryptWith:pubkey paddingType:RSAPaddingPKCS1]; 385 | NSData *decDT = [encDT RSADecryptWith:prikey paddingType:RSAPaddingPKCS1]; 386 | NSLog(@"%@",decDT); 387 | 388 | 389 | 390 | NSString *pripem = [[NSBundle mainBundle] pathForResource:@"private.pem" ofType:nil]; 391 | NSString *pubpem = [[NSBundle mainBundle] pathForResource:@"public.pem" ofType:nil]; 392 | SecKeyRef pubKK = [SecKeyTools publicKeyFromPem:pubpem keySize:kRSA_KEY_SIZE]; 393 | SecKeyRef priKK = [SecKeyTools privaKeyFromPem:pripem keySize:kRSA_KEY_SIZE]; 394 | NSLog(@"%@",pubKK); 395 | NSLog(@"%@",priKK); 396 | 397 | NSLog(@"%lu",SecKeyGetBlockSize(priKK)); 398 | NSData *srcData2 = [@"0123456789" dataUsingEncoding:NSUTF8StringEncoding]; 399 | NSLog(@"%@",srcData2); 400 | NSData *encDT2 = [srcData2 RSAEncryptWith:pubKK paddingType:RSAPaddingPKCS1]; 401 | NSData *decDT2 = [encDT2 RSADecryptWith:priKK paddingType:RSAPaddingPKCS1]; 402 | NSLog(@"%@",decDT2); 403 | ``` 404 | 405 | 406 | ## 其他 407 | 408 | 409 | - 密钥对的生成 410 | 411 | ```objective-c 412 | //生成RSA密钥对,公钥和私钥,支持的SIZE有 413 | // sizes for RSA keys are: 512, 768, 1024, 2048. 414 | - (void)generateRSAKeyPair:(int )keySize 415 | { 416 | if (publicKeyRef) { 417 | return; 418 | } 419 | OSStatus ret = 0; 420 | publicKeyRef = NULL; 421 | privateKeyRef = NULL; 422 | ret = SecKeyGeneratePair((CFDictionaryRef)@{(id)kSecAttrKeyType:(id)kSecAttrKeyTypeRSA,(id)kSecAttrKeySizeInBits:@(keySize)}, &publicKeyRef, &privateKeyRef); 423 | NSAssert(ret==errSecSuccess, @"密钥对生成失败:%d",ret); 424 | 425 | NSLog(@"%@",publicKeyRef); 426 | NSLog(@"%@",privateKeyRef); 427 | NSLog(@"max size:%lu",SecKeyGetBlockSize(privateKeyRef)); 428 | 429 | } 430 | ``` 431 | 432 | - RSA上几种填充方式的区别 433 | 434 | ```objective-c 435 | /** 三种填充方式区别 436 | kSecPaddingNone = 0, 要加密的数据块大小<=SecKeyGetBlockSize的大小,如这里128 437 | kSecPaddingPKCS1 = 1, 要加密的数据块大小<=128-11 438 | kSecPaddingOAEP = 2, 要加密的数据块大小<=128-42 439 | 密码学中的设计原则,一般用RSA来加密 对称密钥,用对称密钥加密大量的数据 440 | 非对称加密速度慢,对称加密速度快 441 | */ 442 | ``` 443 | 444 | - 示例工程 `SecurityiOS.xcodeproj` 445 | 446 | 447 | -------------------------------------------------------------------------------- /SecurityiOS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B4B46B8A1E02302E008F2451 /* src.txt in Resources */ = {isa = PBXBuildFile; fileRef = B4B46B891E02302E008F2451 /* src.txt */; }; 11 | B4B935781E037E7F00C75C37 /* CPPUB.cer in Resources */ = {isa = PBXBuildFile; fileRef = B4B935771E037E7F00C75C37 /* CPPUB.cer */; }; 12 | B4B9357A1E037E8600C75C37 /* CPPRI.p12 in Resources */ = {isa = PBXBuildFile; fileRef = B4B935791E037E8600C75C37 /* CPPRI.p12 */; }; 13 | B4B935861E038DA500C75C37 /* private.pem in Resources */ = {isa = PBXBuildFile; fileRef = B4B935841E038DA500C75C37 /* private.pem */; }; 14 | B4B935871E038DA500C75C37 /* public.pem in Resources */ = {isa = PBXBuildFile; fileRef = B4B935851E038DA500C75C37 /* public.pem */; }; 15 | B4B935A21E03B78800C75C37 /* NSData+KKAES.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B935991E03B78800C75C37 /* NSData+KKAES.m */; }; 16 | B4B935A31E03B78800C75C37 /* NSData+KKHASH.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B9359B1E03B78800C75C37 /* NSData+KKHASH.m */; }; 17 | B4B935A41E03B78800C75C37 /* NSData+KKRSA.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B9359D1E03B78800C75C37 /* NSData+KKRSA.m */; }; 18 | B4B935A51E03B78800C75C37 /* NSData+KKSignVerify.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B9359F1E03B78800C75C37 /* NSData+KKSignVerify.m */; }; 19 | B4B935A61E03B78800C75C37 /* SecKeyTools.m in Sources */ = {isa = PBXBuildFile; fileRef = B4B935A11E03B78800C75C37 /* SecKeyTools.m */; }; 20 | B4C4A6321E014EB30077C972 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B4C4A6311E014EB30077C972 /* main.m */; }; 21 | B4C4A6351E014EB30077C972 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B4C4A6341E014EB30077C972 /* AppDelegate.m */; }; 22 | B4C4A6381E014EB30077C972 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B4C4A6371E014EB30077C972 /* ViewController.m */; }; 23 | B4C4A63B1E014EB30077C972 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4C4A6391E014EB30077C972 /* Main.storyboard */; }; 24 | B4C4A63D1E014EB30077C972 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4C4A63C1E014EB30077C972 /* Assets.xcassets */; }; 25 | B4C4A6401E014EB30077C972 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4C4A63E1E014EB30077C972 /* LaunchScreen.storyboard */; }; 26 | B4C4A6491E0151BD0077C972 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4C4A6481E0151BD0077C972 /* Security.framework */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | B4B46B891E02302E008F2451 /* src.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = src.txt; sourceTree = ""; }; 31 | B4B935771E037E7F00C75C37 /* CPPUB.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = CPPUB.cer; sourceTree = ""; }; 32 | B4B935791E037E8600C75C37 /* CPPRI.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = CPPRI.p12; sourceTree = ""; }; 33 | B4B935841E038DA500C75C37 /* private.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = private.pem; sourceTree = ""; }; 34 | B4B935851E038DA500C75C37 /* public.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = public.pem; sourceTree = ""; }; 35 | B4B935981E03B78800C75C37 /* NSData+KKAES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+KKAES.h"; sourceTree = SOURCE_ROOT; }; 36 | B4B935991E03B78800C75C37 /* NSData+KKAES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+KKAES.m"; sourceTree = SOURCE_ROOT; }; 37 | B4B9359A1E03B78800C75C37 /* NSData+KKHASH.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+KKHASH.h"; sourceTree = SOURCE_ROOT; }; 38 | B4B9359B1E03B78800C75C37 /* NSData+KKHASH.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+KKHASH.m"; sourceTree = SOURCE_ROOT; }; 39 | B4B9359C1E03B78800C75C37 /* NSData+KKRSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+KKRSA.h"; sourceTree = SOURCE_ROOT; }; 40 | B4B9359D1E03B78800C75C37 /* NSData+KKRSA.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+KKRSA.m"; sourceTree = SOURCE_ROOT; }; 41 | B4B9359E1E03B78800C75C37 /* NSData+KKSignVerify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+KKSignVerify.h"; sourceTree = SOURCE_ROOT; }; 42 | B4B9359F1E03B78800C75C37 /* NSData+KKSignVerify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+KKSignVerify.m"; sourceTree = SOURCE_ROOT; }; 43 | B4B935A01E03B78800C75C37 /* SecKeyTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecKeyTools.h; sourceTree = SOURCE_ROOT; }; 44 | B4B935A11E03B78800C75C37 /* SecKeyTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecKeyTools.m; sourceTree = SOURCE_ROOT; }; 45 | B4C4A62D1E014EB30077C972 /* SecurityiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SecurityiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | B4C4A6311E014EB30077C972 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | B4C4A6331E014EB30077C972 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | B4C4A6341E014EB30077C972 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | B4C4A6361E014EB30077C972 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 50 | B4C4A6371E014EB30077C972 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 51 | B4C4A63A1E014EB30077C972 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 52 | B4C4A63C1E014EB30077C972 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 53 | B4C4A63F1E014EB30077C972 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54 | B4C4A6411E014EB30077C972 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | B4C4A6481E0151BD0077C972 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | B4C4A62A1E014EB30077C972 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | B4C4A6491E0151BD0077C972 /* Security.framework in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | B4B935971E03B75A00C75C37 /* NSData-Security */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | B4B935981E03B78800C75C37 /* NSData+KKAES.h */, 74 | B4B935991E03B78800C75C37 /* NSData+KKAES.m */, 75 | B4B9359A1E03B78800C75C37 /* NSData+KKHASH.h */, 76 | B4B9359B1E03B78800C75C37 /* NSData+KKHASH.m */, 77 | B4B9359C1E03B78800C75C37 /* NSData+KKRSA.h */, 78 | B4B9359D1E03B78800C75C37 /* NSData+KKRSA.m */, 79 | B4B9359E1E03B78800C75C37 /* NSData+KKSignVerify.h */, 80 | B4B9359F1E03B78800C75C37 /* NSData+KKSignVerify.m */, 81 | B4B935A01E03B78800C75C37 /* SecKeyTools.h */, 82 | B4B935A11E03B78800C75C37 /* SecKeyTools.m */, 83 | ); 84 | name = "NSData-Security"; 85 | sourceTree = ""; 86 | }; 87 | B4C4A6241E014EB30077C972 = { 88 | isa = PBXGroup; 89 | children = ( 90 | B4C4A62F1E014EB30077C972 /* SecurityiOS */, 91 | B4C4A62E1E014EB30077C972 /* Products */, 92 | B4C4A6471E0151BC0077C972 /* Frameworks */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | B4C4A62E1E014EB30077C972 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | B4C4A62D1E014EB30077C972 /* SecurityiOS.app */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | B4C4A62F1E014EB30077C972 /* SecurityiOS */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | B4C4A6331E014EB30077C972 /* AppDelegate.h */, 108 | B4C4A6341E014EB30077C972 /* AppDelegate.m */, 109 | B4B935971E03B75A00C75C37 /* NSData-Security */, 110 | B4C4A6361E014EB30077C972 /* ViewController.h */, 111 | B4C4A6371E014EB30077C972 /* ViewController.m */, 112 | B4B46B891E02302E008F2451 /* src.txt */, 113 | B4B935841E038DA500C75C37 /* private.pem */, 114 | B4B935851E038DA500C75C37 /* public.pem */, 115 | B4B935771E037E7F00C75C37 /* CPPUB.cer */, 116 | B4B935791E037E8600C75C37 /* CPPRI.p12 */, 117 | B4C4A6391E014EB30077C972 /* Main.storyboard */, 118 | B4C4A63C1E014EB30077C972 /* Assets.xcassets */, 119 | B4C4A63E1E014EB30077C972 /* LaunchScreen.storyboard */, 120 | B4C4A6411E014EB30077C972 /* Info.plist */, 121 | B4C4A6301E014EB30077C972 /* Supporting Files */, 122 | ); 123 | path = SecurityiOS; 124 | sourceTree = ""; 125 | }; 126 | B4C4A6301E014EB30077C972 /* Supporting Files */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | B4C4A6311E014EB30077C972 /* main.m */, 130 | ); 131 | name = "Supporting Files"; 132 | sourceTree = ""; 133 | }; 134 | B4C4A6471E0151BC0077C972 /* Frameworks */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | B4C4A6481E0151BD0077C972 /* Security.framework */, 138 | ); 139 | name = Frameworks; 140 | sourceTree = ""; 141 | }; 142 | /* End PBXGroup section */ 143 | 144 | /* Begin PBXNativeTarget section */ 145 | B4C4A62C1E014EB30077C972 /* SecurityiOS */ = { 146 | isa = PBXNativeTarget; 147 | buildConfigurationList = B4C4A6441E014EB30077C972 /* Build configuration list for PBXNativeTarget "SecurityiOS" */; 148 | buildPhases = ( 149 | B4C4A6291E014EB30077C972 /* Sources */, 150 | B4C4A62A1E014EB30077C972 /* Frameworks */, 151 | B4C4A62B1E014EB30077C972 /* Resources */, 152 | ); 153 | buildRules = ( 154 | ); 155 | dependencies = ( 156 | ); 157 | name = SecurityiOS; 158 | productName = SecurityiOS; 159 | productReference = B4C4A62D1E014EB30077C972 /* SecurityiOS.app */; 160 | productType = "com.apple.product-type.application"; 161 | }; 162 | /* End PBXNativeTarget section */ 163 | 164 | /* Begin PBXProject section */ 165 | B4C4A6251E014EB30077C972 /* Project object */ = { 166 | isa = PBXProject; 167 | attributes = { 168 | LastUpgradeCheck = 0810; 169 | ORGANIZATIONNAME = "dev.keke@gmail.com"; 170 | TargetAttributes = { 171 | B4C4A62C1E014EB30077C972 = { 172 | CreatedOnToolsVersion = 8.1; 173 | ProvisioningStyle = Manual; 174 | }; 175 | }; 176 | }; 177 | buildConfigurationList = B4C4A6281E014EB30077C972 /* Build configuration list for PBXProject "SecurityiOS" */; 178 | compatibilityVersion = "Xcode 3.2"; 179 | developmentRegion = English; 180 | hasScannedForEncodings = 0; 181 | knownRegions = ( 182 | en, 183 | Base, 184 | ); 185 | mainGroup = B4C4A6241E014EB30077C972; 186 | productRefGroup = B4C4A62E1E014EB30077C972 /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | B4C4A62C1E014EB30077C972 /* SecurityiOS */, 191 | ); 192 | }; 193 | /* End PBXProject section */ 194 | 195 | /* Begin PBXResourcesBuildPhase section */ 196 | B4C4A62B1E014EB30077C972 /* Resources */ = { 197 | isa = PBXResourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | B4C4A6401E014EB30077C972 /* LaunchScreen.storyboard in Resources */, 201 | B4B935871E038DA500C75C37 /* public.pem in Resources */, 202 | B4B935861E038DA500C75C37 /* private.pem in Resources */, 203 | B4B46B8A1E02302E008F2451 /* src.txt in Resources */, 204 | B4B9357A1E037E8600C75C37 /* CPPRI.p12 in Resources */, 205 | B4C4A63D1E014EB30077C972 /* Assets.xcassets in Resources */, 206 | B4C4A63B1E014EB30077C972 /* Main.storyboard in Resources */, 207 | B4B935781E037E7F00C75C37 /* CPPUB.cer in Resources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXResourcesBuildPhase section */ 212 | 213 | /* Begin PBXSourcesBuildPhase section */ 214 | B4C4A6291E014EB30077C972 /* Sources */ = { 215 | isa = PBXSourcesBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | B4B935A51E03B78800C75C37 /* NSData+KKSignVerify.m in Sources */, 219 | B4C4A6381E014EB30077C972 /* ViewController.m in Sources */, 220 | B4B935A41E03B78800C75C37 /* NSData+KKRSA.m in Sources */, 221 | B4C4A6351E014EB30077C972 /* AppDelegate.m in Sources */, 222 | B4B935A21E03B78800C75C37 /* NSData+KKAES.m in Sources */, 223 | B4B935A61E03B78800C75C37 /* SecKeyTools.m in Sources */, 224 | B4C4A6321E014EB30077C972 /* main.m in Sources */, 225 | B4B935A31E03B78800C75C37 /* NSData+KKHASH.m in Sources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXSourcesBuildPhase section */ 230 | 231 | /* Begin PBXVariantGroup section */ 232 | B4C4A6391E014EB30077C972 /* Main.storyboard */ = { 233 | isa = PBXVariantGroup; 234 | children = ( 235 | B4C4A63A1E014EB30077C972 /* Base */, 236 | ); 237 | name = Main.storyboard; 238 | sourceTree = ""; 239 | }; 240 | B4C4A63E1E014EB30077C972 /* LaunchScreen.storyboard */ = { 241 | isa = PBXVariantGroup; 242 | children = ( 243 | B4C4A63F1E014EB30077C972 /* Base */, 244 | ); 245 | name = LaunchScreen.storyboard; 246 | sourceTree = ""; 247 | }; 248 | /* End PBXVariantGroup section */ 249 | 250 | /* Begin XCBuildConfiguration section */ 251 | B4C4A6421E014EB30077C972 /* Debug */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_ANALYZER_NONNULL = YES; 256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 257 | CLANG_CXX_LIBRARY = "libc++"; 258 | CLANG_ENABLE_MODULES = YES; 259 | CLANG_ENABLE_OBJC_ARC = YES; 260 | CLANG_WARN_BOOL_CONVERSION = YES; 261 | CLANG_WARN_CONSTANT_CONVERSION = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 269 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 270 | CLANG_WARN_UNREACHABLE_CODE = YES; 271 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 272 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 273 | COPY_PHASE_STRIP = NO; 274 | DEBUG_INFORMATION_FORMAT = dwarf; 275 | ENABLE_STRICT_OBJC_MSGSEND = YES; 276 | ENABLE_TESTABILITY = YES; 277 | GCC_C_LANGUAGE_STANDARD = gnu99; 278 | GCC_DYNAMIC_NO_PIC = NO; 279 | GCC_NO_COMMON_BLOCKS = YES; 280 | GCC_OPTIMIZATION_LEVEL = 0; 281 | GCC_PREPROCESSOR_DEFINITIONS = ( 282 | "DEBUG=1", 283 | "$(inherited)", 284 | ); 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 292 | MTL_ENABLE_DEBUG_INFO = YES; 293 | ONLY_ACTIVE_ARCH = YES; 294 | SDKROOT = iphoneos; 295 | }; 296 | name = Debug; 297 | }; 298 | B4C4A6431E014EB30077C972 /* Release */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | ALWAYS_SEARCH_USER_PATHS = NO; 302 | CLANG_ANALYZER_NONNULL = YES; 303 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 304 | CLANG_CXX_LIBRARY = "libc++"; 305 | CLANG_ENABLE_MODULES = YES; 306 | CLANG_ENABLE_OBJC_ARC = YES; 307 | CLANG_WARN_BOOL_CONVERSION = YES; 308 | CLANG_WARN_CONSTANT_CONVERSION = YES; 309 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 310 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 311 | CLANG_WARN_EMPTY_BODY = YES; 312 | CLANG_WARN_ENUM_CONVERSION = YES; 313 | CLANG_WARN_INFINITE_RECURSION = YES; 314 | CLANG_WARN_INT_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 317 | CLANG_WARN_UNREACHABLE_CODE = YES; 318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 319 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 320 | COPY_PHASE_STRIP = NO; 321 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 322 | ENABLE_NS_ASSERTIONS = NO; 323 | ENABLE_STRICT_OBJC_MSGSEND = YES; 324 | GCC_C_LANGUAGE_STANDARD = gnu99; 325 | GCC_NO_COMMON_BLOCKS = YES; 326 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 327 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 328 | GCC_WARN_UNDECLARED_SELECTOR = YES; 329 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 330 | GCC_WARN_UNUSED_FUNCTION = YES; 331 | GCC_WARN_UNUSED_VARIABLE = YES; 332 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 333 | MTL_ENABLE_DEBUG_INFO = NO; 334 | SDKROOT = iphoneos; 335 | VALIDATE_PRODUCT = YES; 336 | }; 337 | name = Release; 338 | }; 339 | B4C4A6451E014EB30077C972 /* Debug */ = { 340 | isa = XCBuildConfiguration; 341 | buildSettings = { 342 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 343 | DEVELOPMENT_TEAM = ""; 344 | INFOPLIST_FILE = SecurityiOS/Info.plist; 345 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 346 | PRODUCT_BUNDLE_IDENTIFIER = com.cocoa.SecurityiOS; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | }; 349 | name = Debug; 350 | }; 351 | B4C4A6461E014EB30077C972 /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 355 | DEVELOPMENT_TEAM = ""; 356 | INFOPLIST_FILE = SecurityiOS/Info.plist; 357 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 358 | PRODUCT_BUNDLE_IDENTIFIER = com.cocoa.SecurityiOS; 359 | PRODUCT_NAME = "$(TARGET_NAME)"; 360 | }; 361 | name = Release; 362 | }; 363 | /* End XCBuildConfiguration section */ 364 | 365 | /* Begin XCConfigurationList section */ 366 | B4C4A6281E014EB30077C972 /* Build configuration list for PBXProject "SecurityiOS" */ = { 367 | isa = XCConfigurationList; 368 | buildConfigurations = ( 369 | B4C4A6421E014EB30077C972 /* Debug */, 370 | B4C4A6431E014EB30077C972 /* Release */, 371 | ); 372 | defaultConfigurationIsVisible = 0; 373 | defaultConfigurationName = Release; 374 | }; 375 | B4C4A6441E014EB30077C972 /* Build configuration list for PBXNativeTarget "SecurityiOS" */ = { 376 | isa = XCConfigurationList; 377 | buildConfigurations = ( 378 | B4C4A6451E014EB30077C972 /* Debug */, 379 | B4C4A6461E014EB30077C972 /* Release */, 380 | ); 381 | defaultConfigurationIsVisible = 0; 382 | defaultConfigurationName = Release; 383 | }; 384 | /* End XCConfigurationList section */ 385 | }; 386 | rootObject = B4C4A6251E014EB30077C972 /* Project object */; 387 | } 388 | --------------------------------------------------------------------------------