iOS常用加密之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;

加密相关的代码

 1 #pragma mark - 加密相关
 2 //用本地证书加载公钥
 3 - (void)loadPublicKeyWithPath:(NSString *)derFilePath
 4 {
 5     NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath];
 6     if (derData.length > 0)
 7     {
 8         [self loadPublicKeyWithData:derData];
 9     }
10     else
11     {
12         NSLog(@"load public key fail with path: %@", derFilePath);
13     }
14 }
15 //加载公钥方法
16 - (void)loadPublicKeyWithData:(NSData *)derData
17 {
18     SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)derData);
19     SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
20     SecTrustRef myTrust;
21     OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
22     SecTrustResultType trustResult;
23     if (status == noErr) {
24         status = SecTrustEvaluate(myTrust, &trustResult);
25     }
26
27     SecKeyRef securityKey = SecTrustCopyPublicKey(myTrust);  CFRelease(myCertificate);  CFRelease(myPolicy);  CFRelease(myTrust);
28
29     _publicKey = securityKey;
30 }
31
32
33 //将文本内容加密
34 - (NSString *)rsaEncryptText:(NSString *)text
35 {
36     NSData *encryptedData = [self rsaEncryptData:[text dataUsingEncoding:NSUTF8StringEncoding]];
37     NSString *base64EncryptedString = [encryptedData base64EncodedStringWithOptions:0];
38     return base64EncryptedString;
39 }
40
41
42 //分段再加密数据
43 - (NSData *)rsaEncryptData:(NSData *)data
44 {
45     SecKeyRef key = _publicKey;
46
47     size_t cipherBufferSize = SecKeyGetBlockSize(key);
48     uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
49     size_t blockSize = cipherBufferSize - 11;
50     size_t blockCount = (size_t)ceil([data length] / (double)blockSize);
51     NSMutableData *encryptedData = [[NSMutableData alloc] init] ;
52     for (int i = 0; i < blockCount; i++)
53     {
54         size_t bufferSize = MIN(blockSize,[data length] - i * blockSize);
55         NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
56         OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,(const uint8_t *)[buffer bytes],[buffer length],cipherBuffer,&cipherBufferSize);
57         if (status == noErr)
58         {
59             NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length: cipherBufferSize];
60             [encryptedData appendData:encryptedBytes];
61         }
62         else
63         {
64             if (cipherBuffer) {
65                 free(cipherBuffer);
66             }      return nil;
67         }
68
69     }
70     if (cipherBuffer)
71     {
72         free(cipherBuffer);
73
74     }
75     return encryptedData;
76 }

第三步:解密相关代码

#pragma mark - 解密相关
- (void)loadPrivateKeyWithPath:(NSString *)p12FilePath password:(NSString *)p12Password
{
    NSData *data = [NSData dataWithContentsOfFile:p12FilePath];
    if (data.length > 0)
    {
        [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, 0, 0, NULL);
    OSStatus securityError = SecPKCS12Import((__bridge CFDataRef)p12Data,
                                             (__bridge CFDictionaryRef)options,
                                             &items);  if (securityError == noErr && CFArrayGetCount(items) > 0) {    CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
        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:0];
    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) - 12;
    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加密解密的应用

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

 1 - (IBAction)decryptionBtnClick:(id)sender {
 2
 3     NSString *path = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
 4     [self loadPublicKeyWithPath:path];
 5     path = [[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"];
 6     [self loadPrivateKeyWithPath:path password:@"bestnet"];
 7
 8     NSString *encryptStr = self.encryptTextFeild.text;
 9     if (encryptStr.length > 0)
10     {
11         NSString *miwen = [self rsaEncryptText:encryptStr];
12         self.miWenLabel.text = [NSString stringWithFormat:@"加密结果:%@", miwen];
13         if (miwen.length > 0)
14         {
15             self.decryptionTextFeild.text = [self rsaDecryptText:miwen];
16         }
17     }
18 }

效果图

时间: 2024-08-10 02:40:38

iOS常用加密之RSA加密解密的相关文章

MD5加密和RSA加密

1.MD5加密  MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),MD5算法的使用不需要支付任何版权费用. MD5的功能:     ①.输入任意长度的信息,经过处理,输出为128位的信息(数字指纹):    ②.不同的输入得到的不同的结果(唯一性):    ③.根据128位的输出结果不可能反推出输入的信息(不可逆),也就是只能加密,不能解密:  MD5的用途:     1.防止被篡改:    1)比如发送一个电子文档,发送前,我先得到MD5的

Java MD5加密与RSA加密

区别: MD5加密: 加密时通过原字符串加密成另一串字符串 解密时需要原加密字符串进行重新加密比较两次加密结果是否一致 T=RSA加密: 加密时通过原字符串生成密钥对(公钥+私钥) 解密时通过公钥和私钥进行解密,解密出原字符串进行比较是否一致 个人观点: RSA加密略比MD5加密牛逼一点点 但凡事都有好坏    MD5加密执行效率比RSA慢 废话不多说上栗子: MD5加密: package cn.news.util; import java.security.MessageDigest; /**

iOS and JAVA 的 RSA 加密解密 (转载整理 )

参考原文地址:http://www.cnblogs.com/makemelike/articles/3802518.html (至于RSA的基本原理,大家可以看 阮一峰的网络日志 的 RSA算法原理(一) 和 RSA算法原理(二) ) 这篇文章只是做一个整理,帮大家理清一下步骤的而已( 英文版本请看 RSA Encrypt and Decrypt in IOS and JAVA ). 一.首先,打开终端Terminal, 生成必要的公钥.私钥.证书: openssl genrsa -out pr

android md5加密与rsa加解密实现代码

import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException; public class MD5 {/* * MD5加密 */  public static String getDigest(String str) { MessageDigest messageDigest = null; try { mess

iOS,一行代码进行RSA、DES 、AES、MD5加密、解密

最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,服务器也会返回数据,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的数据加密的时候遇到了一些问题.起初采取的方案是DES加密,老大说DES加密是对称的,网络抓包加上反编译可能会被破解,故采取RSA方式加密.RSA加密时需要公钥和私钥,客户端保存公钥加密数据,服务器保存私钥解密数据.(iOS端公钥加密私钥解密.java端公钥加密私钥解密,java端私钥加密公钥解密都容易做到,iOS不

全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件

一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时.由于 .Net.Java 的RSA类库存在很多细节区别,尤其是它们支持的密钥格式不同.导致容易出现“我加密的数据对方不能解密,对方加密的数据我不能解密,但是自身是可以正常加密解密”等情况.虽然网上已经有很多文章讨论 .Net与Java互通的RSA加解密,但是存在不够全面.需要第三方dll.方案复杂 等问题.于是我仔细研究了这一课题,得到了一

iOS rsa加密与解密

转自 --响铃  IOS rsa加密与解密 ras加密需要两组秘钥,一组公共秘钥,一组私有秘钥. 生成命令: openssl req -x509 -out public_key.der -outform der -new -newkey rsa:2048 -keyout private_key.pem public_key.der为公共秘钥文件,private_key.pem为私有秘钥文件. 生成ios可引用的私有秘钥文件.pfx: 1. OpenSSL rsa -in private_key.

ios下使用RSA算法加密与java后台解密配合demo

首先了解一下几个相关概念,以方便后面遇到的问题的解决: 原网址:http://blog.csdn.net/jinglijun/article/details/7770315RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数论:将两个大素数相乘非常容易,但要对这个乘积的结果进行因式分解却非常困难,因此可以把乘积公开作为公钥.该算法能够抵抗目前已知的所有密码攻击.RSA算法是一种非对称算法,算法需要一对密钥

ios RSA加密解密一些相关问题

前言: 最近在做一个类似支付宝的理财项目,涉及到了RSA加解密方面的知识,在这里也遇到了不少的问题.写出来与大家分享心得. 1.什么是RSA加密解密(ios RSA加密解密过程) 这些网上都说的很清楚,大家可以从网上查找一下. 理论上是可以用公钥加密,私钥解密,或者是私钥加密,公钥解密. 我的理解是:A向B请求数据:A把自己的信息用私钥签名,并且把自己的公钥传送给B, B受到A的数据:B将A的公钥取出,并且用A的公钥确认签名, B向A发送数据:B将自己的数据用A公钥加密,再将自己的公钥暴露给A,