您的位置:首页 > 其它

RSA加密解密

2015-12-24 17:54 239 查看
和后台弄人脸识别这一块时真是欲仙欲死。NND,一直想记录一下,以免以后再掉坑里,拖了个把月才写,真是拖延症加懒癌晚期。网上找的找了很久只有加密,没解密,自己写了个解密。废话不多说了,上代码和解释:其实自己还是不太懂,仿照加密啊写的解密。有错误的话多多欢迎来打脸

。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分。。谁让你懒呢。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: