ios android rsa加密解密,iOS常用加密之RSA加密解密

RSA基本原理

RSA使用"秘匙对"对数据进行加密解密.在加密解密数据前,需要先生成公钥(public key)和私钥(private key).

公钥(public key): 用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端.

私钥(private key): 用于解密数据. 必须保密, 私钥泄露会造成安全问题

第一步:公钥、私钥的生成

iOS开发者可直接在Mac终端生成,命令如下,生成公钥der文件的时候需要填写国家地区等基本信息,也可直接忽略不填。生成私p12文件的时候需要填写密码,这个必填而且要记住,后面会用得着。

// 生成1024位私钥

openssl genrsa -out private_key.pem 1024

// 根据私钥生成CSR文件

openssl req -new -key private_key.pem -out rsaCertReq.csr

// 根据私钥和CSR文件生成crt文件

openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

// 为IOS端生成公钥der文件

openssl x509 -outform der -in rsaCert.crt -out public_key.der

// 将私钥导出为这p12文件

openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

第二步:加密相关的代码

在加密加密的时候需要定义公有变量公钥和私钥

SecKeyRef _publicKey;

SecKeyRef _privateKey;

加密相关的代码

#pragma mark - 加密相关

//用本地证书加载公钥

- (void)loadPublicKeyWithPath:(NSString *)derFilePath

{

NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath];

if (derData.length > )

{

[self loadPublicKeyWithData:derData];

}

else

{

NSLog(@"load public key fail with path: %@", derFilePath);

}

}

//加载公钥方法

- (void)loadPublicKeyWithData:(NSData *)derData

{

SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)derData);

SecPolicyRef myPolicy = SecPolicyCreateBasicX509();

SecTrustRef myTrust;

OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);

SecTrustResultType trustResult;

if (status == noErr) {

status = SecTrustEvaluate(myTrust, &trustResult);

}

SecKeyRef securityKey = SecTrustCopyPublicKey(myTrust); CFRelease(myCertificate); CFRelease(myPolicy); CFRelease(myTrust);

_publicKey = securityKey;

}

//将文本内容加密

- (NSString *)rsaEncryptText:(NSString *)text

{

NSData *encryptedData = [self rsaEncryptData:[text dataUsingEncoding:NSUTF8StringEncoding]];

NSString *base64EncryptedString = [encryptedData base64EncodedStringWithOptions:];

return base64EncryptedString;

}

//分段再加密数据

- (NSData *)rsaEncryptData:(NSData *)data

{

SecKeyRef key = _publicKey;

size_t cipherBufferSize = SecKeyGetBlockSize(key);

uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));

size_t blockSize = cipherBufferSize - ;

size_t blockCount = (size_t)ceil([data length] / (double)blockSize);

NSMutableData *encryptedData = [[NSMutableData alloc] init] ;

for (int i = ; i < blockCount; i++)

{

size_t bufferSize = MIN(blockSize,[data length] - i * blockSize);

NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];

OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,(const uint8_t *)[buffer bytes],[buffer length],cipherBuffer,&cipherBufferSize);

if (status == noErr)

{

NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length: cipherBufferSize];

[encryptedData appendData:encryptedBytes];

}

else

{

if (cipherBuffer) {

free(cipherBuffer);

} return nil;

}

}

if (cipherBuffer)

{

free(cipherBuffer);

}

return encryptedData;

}

第三步:解密相关代码

#pragma mark - 解密相关

- (void)loadPrivateKeyWithPath:(NSString *)p12FilePath password:(NSString *)p12Password

{

NSData *data = [NSData dataWithContentsOfFile:p12FilePath];

if (data.length > )

{

[self loadPrivateKeyWithData:data password:p12Password];

}

else

{ NSLog(@"load private key fail with path: %@", p12FilePath);

}

}

//生成私钥

- (void)loadPrivateKeyWithData:(NSData *)p12Data password:(NSString *)p12Password

{

SecKeyRef privateKeyRef = NULL;

NSMutableDictionary * options = [[NSMutableDictionary alloc] init];

[options setObject:p12Password forKey:(__bridge id)kSecImportExportPassphrase]; CFArrayRef items = CFArrayCreate(NULL, , , NULL);

OSStatus securityError = SecPKCS12Import((__bridge CFDataRef)p12Data,

(__bridge CFDictionaryRef)options,

&items); if (securityError == noErr && CFArrayGetCount(items) > ) { CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, );

SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict,

kSecImportItemIdentity);

securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef); if (securityError != noErr) {

privateKeyRef = NULL;

}

}

_privateKey = privateKeyRef;

CFRelease(items);

}

//调用下面方法进行解密,最后返回一个字符串

- (NSString *)rsaDecryptText:(NSString *)text

{

NSData *data = [[NSData alloc] initWithBase64EncodedString:text options:];

NSData *decryptData = [self rsaDecryptData:data];

NSString *result = [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];

return result;

}

//用私钥解密的方法,被上面方法调用

- (NSData *)rsaDecryptData:(NSData *)data

{

SecKeyRef key = _privateKey;

size_t cipherLen = [data length];

void *cipher = malloc(cipherLen);

[data getBytes:cipher length:cipherLen];

size_t plainLen = SecKeyGetBlockSize(key) - ;

void *plain = malloc(plainLen);

OSStatus status = SecKeyDecrypt(key, kSecPaddingPKCS1, cipher, cipherLen, plain, &plainLen);

if (status != noErr)

{

return nil;

}

NSData *decryptedData = [[NSData alloc] initWithBytes:(const void *)plain length:plainLen];

return decryptedData;

}

第四步:RSA加密解密的应用

在加密活解密之前一定要闲加载证书,然后再调用加密方法,直接上代码

- (IBAction)decryptionBtnClick:(id)sender {

NSString *path = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];

[self loadPublicKeyWithPath:path];

path = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"];

[self loadPrivateKeyWithPath:path password:@"bestnet"];

NSString *encryptStr = self.encryptTextFeild.text;

if (encryptStr.length > )

{

NSString *miwen = [self rsaEncryptText:encryptStr];

self.miWenLabel.text = [NSString stringWithFormat:@"加密结果:%@", miwen];

if (miwen.length > )

{

self.decryptionTextFeild.text = [self rsaDecryptText:miwen];

}

}

}

效果图

122c7fc514c859ac9249bc1d183a802c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值