[iOS开发笔记 数据安全]对非对称加密理解

来源:互联网 发布:神彩彩票源码 编辑:程序博客网 时间:2024/06/08 11:08

最近一直做的项目由于都是金融股票方面的app,加密要求比较高,自己了解了一些加密相关的知识,给大家分享一下。


POST请求,https协议,以及苹果自己的SSKeyChain这些就不用多说了,应该都了解。

主要说一下非对称加密。他的数据传输过程是:明文通过接收人的公钥加密,传输给接收人,因为只有接收人拥有对应的私钥,别人不可能拥有或者不可能通过公钥推算出私钥,所传输过程中无法被中间人截获。只有拥有私钥的接收人才能解密得到原文。比如,在登录时在客户端生成随机密钥,然后使用公钥加密传输到服务端,服务端使用私钥解密得到随机密钥,此密钥就用于后续的AES加密/解密使用通俗一点的说:前面的几种加密方法是:一把钥匙可以开对应的一把锁。而非对称加密是指:这把钥匙,在特定的情况下,才能打开它所对应的那把锁。例如:我拿着钥匙,在门口和屋里的管家对上暗号后(钥匙相当于公钥,你和屋里面的管家的暗号相当于私钥),得到里面人的允许并且里面的人知道我进来只是拿我的mac电脑的情况,才能打开门。

非对称加密的组成主要是RSA公钥和DSA私人密钥组成。

用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质,这样说应该够好理解。

原理大致就是这样了。犹豫我现在主要做的是移动端的开发,咱们直接代码撸起来。看一下这个加密过程、


首先在自己的mac上装上openssl

OpenSSL安装步骤


下载

git clone git://git.openssl.org/openssl.git

安装

sudo ./config --prefix=/usr/local/openssl 

.执行

make  

make install 

查看版本

openssl version

出现:

OpenSSL 0.9.8zh 14 Jan 2016


则表示安装ok。


加密过程中的思路是:
1、定义一个方法,把证书文件需要加密的数据传入一个方法中,生成一个公钥。

2、创建一个能够将数据进行base64加密的方法。将需要加密的文本通过base加密,加密完成后再调用公钥加密的方法对base加密后的数据进行二次加密。加密时是讲二进制数据分段,切片后进行加密再拼接到二进制数据的变量中


生成公钥和私钥:

    生成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;

}@end@implementation HYBRSAEncrypt- (void)dealloc {  if (nil != _publicKey) {    CFRelease(_publicKey);

if (nil != _privateKey) {    CFRelease(_privateKey);

}

}#pragma mark - 加密相关//用本地证书加载公钥- (void)loadPublicKeyWithPath:(NSString *)derFilePath {  NSData *derData = [[NSData alloc] initWithContentsOfFile:derFilePath];  if (derData.length > 0) {

[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 hdf_toData]];  NSString *base64EncryptedString = [NSString hdf_base64StringFromData:encryptedData

length:encryptedData.length];  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 - 11;

size_t blockCount = (size_t)ceil([data length] / (double)blockSize);  NSMutableData *encryptedData = [[NSMutableData alloc] init] ;  for (int i = 0; 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 > 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 hdf_base64DataFromString:text];  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;}@end
复制代码



这样一个非对称加密就完成了。

时间仓促,写的有点糙。有时间补充。







原创粉丝点击