RSA加密解密
2015-12-24 17:54
239 查看
和后台弄人脸识别这一块时真是欲仙欲死。NND,一直想记录一下,以免以后再掉坑里,拖了个把月才写,真是拖延症加懒癌晚期。网上找的找了很久只有加密,没解密,自己写了个解密。废话不多说了,上代码和解释:其实自己还是不太懂,仿照加密啊写的解密。有错误的话多多欢迎来打脸
。h文件
。m文件
用的时候直接 调用
-(NSString )signTheDataSHA1WithRSA:(NSString )plainText;
这两个方法就行了。
当然了,公钥,私钥要换成自己的。注意文件类型。别怕烦,不然你会更烦。。
里面有签名,不需要可以注释了。
懒人可以直接下载,我把这俩文件上传。不过要2分。。谁让你懒呢。。
。h文件
#import <Foundation/Foundation.h> @interface W3r_RSA : NSObject { SecKeyRef publicKey; SecKeyRef server_privateKey; //服务器私钥 SecKeyRef myself_privateKey;//自己私钥,签名 SecCertificateRef certificate; SecPolicyRef Public_certificate; SecPolicyRef policy; SecTrustRef trust; size_t maxPlainLen; } +(instancetype)sharedManager; - (NSData *) encryptWithData:(NSData *)content; - (NSData *) encryptWithString:(NSString *)content; - (NSString *) encryptToString:(NSString *)content; #pragma mark - (NSString *)DecryptToString:(NSString *)content; -(NSString *)signTheDataSHA1WithRSA:(NSString *)plainText; @e
。m文件
// // RSA.m // Shsm // // Created by lihui on 15/10/28. // // #import "W3r_RSA.h" #import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> #import <Security/Security.h> #import "NSData+Base64.h" #import "Base64.h" #define kChosenDigestLength CC_SHA1_DIGEST_LENGTH // SHA-1消息摘要的数据位数160位 @implementation W3r_RSA +(instancetype)sharedManager{ static W3r_RSA *_sharedManager = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _sharedManager = [[self alloc] init]; }); return _sharedManager; } - (id)init { self = [super init]; //公钥 NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"server_public_key" ofType:@"der"]; if (publicKeyPath == nil) { NSLog(@"Can not find pub.der"); return nil; } NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath]; if (publicKeyFileContent == nil) { NSLog(@"Can not read from pub.der"); return nil; } certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent); if (certificate == nil) { NSLog(@"Can not read certificate from pub.der"); return nil; } policy = SecPolicyCreateBasicX509(); OSStatus returnCode = SecTrustCreateWithCertificates(certificate, policy, &trust); if (returnCode != 0) { NSLog(@"SecTrustCreateWithCertificates fail. Error Code: %ld", returnCode); return nil; } SecTrustResultType trustResultType; returnCode = SecTrustEvaluate(trust, &trustResultType); if (returnCode != 0) { return nil; } publicKey = SecTrustCopyPublicKey(trust); if (publicKey == nil) { NSLog(@"SecTrustCopyPublicKey fail"); return nil; } maxPlainLen = SecKeyGetBlockSize(publicKey) - 12; //服务器私钥解密 NSString *server_privateKeyPath = [[NSBundle mainBundle] pathForResource:@"server_private_key" ofType:@"p12"]; NSData *p12Data=[NSData dataWithContentsOfFile:server_privateKeyPath]; NSMutableDictionary *server_option=[[NSMutableDictionary alloc] init]; SecKeyRef server_privateKeyRef =NULL; //change to the actual password you usedd here [server_option setObject:@"" forKey:(id)kSecImportExportPassphrase]; CFArrayRef server_items=CFArrayCreate(NULL, 0, 0, NULL); OSStatus server_securityError=SecPKCS12Import((CFDataRef)p12Data, (CFDictionaryRef)server_option, &server_items); if (server_securityError==noErr&&CFArrayGetCount(server_items)>0) { CFDictionaryRef identityDict =CFArrayGetValueAtIndex(server_items, 0); SecIdentityRef identityApp=(SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); server_securityError=SecIdentityCopyPrivateKey(identityApp, &server_privateKeyRef); if (server_securityError !=noErr) { server_privateKeyRef=NULL; } } CFRelease(server_items); server_privateKey=server_privateKeyRef; //自己私钥,签名 NSString *myself_privateKeyPath = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"]; NSData *myself_pemData=[NSData dataWithContentsOfFile:myself_privateKeyPath]; NSMutableDictionary *myself_option=[[NSMutableDictionary alloc] init]; SecKeyRef myself_privateKeyRef =NULL; //change to the actual password you usedd here [myself_option setObject:@"" forKey:(id)kSecImportExportPassphrase]; CFArrayRef items=CFArrayCreate(NULL, 0, 0, NULL); OSStatus securityError=SecPKCS12Import((CFDataRef)myself_pemData, (CFDictionaryRef)myself_option, &items); if (securityError==noErr&&CFArrayGetCount(items)>0) { CFDictionaryRef identityDict =CFArrayGetValueAtIndex(items, 0); SecIdentityRef identityApp=(SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); securityError=SecIdentityCopyPrivateKey(identityApp, &myself_privateKeyRef); if (securityError !=noErr) { myself_privateKeyRef=NULL; } } CFRelease(items); myself_privateKey=myself_privateKeyRef; return self; } - (NSData *)encryptWithData:(NSData *)content { size_t plainLen = [content length]; if (plainLen > maxPlainLen) { NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen); return nil; } void *plain = malloc(plainLen); [content getBytes:plain length:plainLen]; size_t cipherLen = 128; // currently RSA key length is set to 128 bytes void *cipher = malloc(cipherLen); OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain, plainLen, cipher, &cipherLen); NSData *result = nil; if (returnCode != 0) { NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode); } else { result = [NSData dataWithBytes:cipher length:cipherLen]; } free(plain); free(cipher); return result; } - (NSData *) encryptWithString:(NSString *)content { return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]]; } - (NSString *)encryptToString:(NSString *)content { NSData *data = [self encryptWithString:content]; return [self base64forData:data]; } // convert NSData to NSString - (NSString*)base64forData:(NSData*)theData { const uint8_t* input = (const uint8_t*)[theData bytes]; NSInteger length = [theData length]; static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t* output = (uint8_t*)data.mutableBytes; NSInteger i; for (i=0; i < length; i += 3) { NSInteger value = 0; NSInteger j; for (j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { value |= (0xFF & input[j]); } } NSInteger theIndex = (i / 3) * 4; output[theIndex + 0] = table[(value >> 18) & 0x3F]; output[theIndex + 1] = table[(value >> 12) & 0x3F]; output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; } return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; } #pragma mark 解密 - (NSString *)DecryptToString:(NSString *)content { NSData *data = [self DecryptWithString:content]; return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } - (NSData *)DecryptWithString:(NSString *)content { // return [self DecryptWithData:[Base64 decodeString:content]]; return [self decryptWithPrivateKey:[Base64 decodeString:content]]; } - (NSData *)DecryptWithData:(NSData *)content { size_t plainLen = [content length]; void *plain = malloc(plainLen); [content getBytes:plain length:plainLen]; size_t cipherLen = SecKeyGetBlockSize(server_privateKey)-12; // currently RSA key length is set to 128 bytes void *cipher = malloc(cipherLen); OSStatus returnCode =SecKeyDecrypt(server_privateKey, kSecPaddingPKCS1, plain, plainLen, cipher, &cipherLen); NSData *result = nil; if (returnCode != 0) { NSLog(@"SecKeyDecrypt fail. Error Code: %ld", returnCode); } else { result = [NSData dataWithBytes:cipher length:cipherLen]; } free(plain); free(cipher); return result; } - (NSData *)decryptWithPrivateKey:(NSData *)cipherData { // 分配内存块,用于存放解密后的数据段 size_t plainBufferSize = SecKeyGetBlockSize(server_privateKey); NSLog(@"plainBufferSize = %zd", plainBufferSize); uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t)); // 计算数据段最大长度及数据段的个数 double totalLength = [cipherData length]; size_t blockSize = plainBufferSize; size_t blockCount = (size_t)ceil(totalLength / blockSize); NSMutableData *decryptedData = [NSMutableData data]; // 分段解密 for (int i = 0; i < blockCount; i++) { NSUInteger loc = i * blockSize; // 数据段的实际大小。最后一段可能比blockSize小。 int dataSegmentRealSize = MIN(blockSize, totalLength - loc); // 截取需要解密的数据段 NSData *dataSegment = [cipherData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)]; OSStatus status = SecKeyDecrypt(server_privateKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, plainBuffer, &plainBufferSize); if (status == errSecSuccess) { NSData *decryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)plainBuffer length:plainBufferSize]; [decryptedData appendData:decryptedDataSegment]; } else { if (plainBuffer) { free(plainBuffer); } return nil; } } if (plainBuffer) { free(plainBuffer); } return decryptedData; } //签名 - (NSData *)getHashBytes:(NSData *)plainText { CC_SHA1_CTX ctx; uint8_t * hashBytes = NULL; NSData * hash = nil; // Malloc a buffer to hold hash. hashBytes = malloc( kChosenDigestLength * sizeof(uint8_t) ); memset((void *)hashBytes, 0x0, kChosenDigestLength); // Initialize the context. CC_SHA1_Init(&ctx); // Perform the hash. CC_SHA1_Update(&ctx, (void *)[plainText bytes], [plainText length]); // Finalize the output. CC_SHA1_Final(hashBytes, &ctx); // Build up the SHA1 blob. hash = [NSData dataWithBytes:(const void *)hashBytes length:(NSUInteger)kChosenDigestLength]; if (hashBytes) free(hashBytes); return hash; } -(NSString *)signTheDataSHA1WithRSA:(NSString *)plainText { uint8_t* signedBytes = NULL; size_t signedBytesSize = 0; OSStatus sanityCheck = noErr; NSData* signedHash = nil; NSString * path = [[NSBundle mainBundle]pathForResource:@"private_key" ofType:@"p12"]; NSData * data = [NSData dataWithContentsOfFile:path]; NSMutableDictionary * options = [[NSMutableDictionary alloc] init]; // Set the private key query dictionary. [options setObject:@"" forKey:(id)kSecImportExportPassphrase]; CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); OSStatus securityError = SecPKCS12Import((CFDataRef) data, (CFDictionaryRef)options, &items); if (securityError!=noErr) { return nil ; } CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity); SecKeyRef privateKeyRef=nil; SecIdentityCopyPrivateKey(identityApp, &privateKeyRef); signedBytesSize = SecKeyGetBlockSize(privateKeyRef); NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding]; signedBytes = malloc( signedBytesSize * sizeof(uint8_t) ); // Malloc a buffer to hold signature. memset((void *)signedBytes, 0x0, signedBytesSize); sanityCheck = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1SHA1, (const uint8_t *)[[self getHashBytes:plainTextBytes] bytes], kChosenDigestLength, (uint8_t *)signedBytes, &signedBytesSize); if (sanityCheck == noErr) { signedHash = [NSData dataWithBytes:(const void *)signedBytes length:(NSUInteger)signedBytesSize]; } else { return nil; } if (signedBytes) { free(signedBytes); } NSString *signatureResult=[NSString stringWithFormat:@"%@",[signedHash base64EncodedString]]; return signatureResult; } - (void)dealloc{ CFRelease(certificate); CFRelease(trust); CFRelease(policy); CFRelease(publicKey); } @end
用的时候直接 调用
pragma mark
(NSString )DecryptToString:(NSString )content;-(NSString )signTheDataSHA1WithRSA:(NSString )plainText;
这两个方法就行了。
当然了,公钥,私钥要换成自己的。注意文件类型。别怕烦,不然你会更烦。。
里面有签名,不需要可以注释了。
懒人可以直接下载,我把这俩文件上传。不过要2分。。谁让你懒呢。。
相关文章推荐
- IOS系列教程
- 关于INADDR_ANY
- iOS开发中怎么抓包
- QT 窗口设置可拉伸背景图
- iOS在AppDelegate类中获取其他类中属性的值
- 我们为什么需要DTO(数据传输对象)
- django使用mysql
- 【Java并发编程实战】-----“J.U.C”:AQS分析(二):获取锁、释放锁
- Python的操作符
- Fatal error: Class 'Illuminate\Foundation\Application' not found in /[path_to_laravel_app]/bootstrap/start.php on line 14
- 如何删除xcode 中过期的描述性文件
- I.MX6 Linux mipi配置数据合成
- 关于中国红十字会
- iOS小demo之获取内存大小
- C++之路起航——标准模板库(set)
- Cocos2d-x3.2 TextureCache类异步载入功能解说
- Alter Log中VKTM时间drift漂移现象
- 百度搜索附近加盟店等基于LBS云搜索功能的实现
- 集合已修改;可能无法执行枚举操作。
- C# 字符串转义和反转义