iOS RSA加密算法詳解:保障iOS應用數據傳輸安全

一、什麼是RSA算法

RSA算法是一種公鑰加密算法,由三個名字的發明者Rivest、Shamir和Adleman共同發明,RSA算法是現代公鑰加密算法中最常用的一種,它是一種非對稱加密算法,用於數據加密和數字簽名。

非對稱加密算法需要一對密鑰,分別稱為公鑰和私鑰。公鑰可以自由發布,私鑰則需要保密。任何使用公鑰加密的數據,只有使用與之配對的私鑰才能解密。RSA算法的主要作用是進行加密和數字簽名。

二、RSA算法的加密和解密過程

下面通過以下步驟來介紹RSA算法的加密和解密過程:

1、隨機生成兩個大素數p和q(通常是1024位或2048位)。

2、計算n=pq,φ(n)=(p-1)(q-1)。

3、隨機選取一個整數e,1<e< φ(n),且e與φ(n)互質。

4、計算d,使得d×e ≡ 1(mod φ(n)),d為e的逆元。

5、公鑰為(n, e),私鑰為(n, d)。

6、加密過程:將明文M轉化為整數m,採用公鑰(n, e)對明文進行加密,c ≡ m^e (mod n)。

7、解密過程:採用私鑰(n, d)對密文進行解密,m ≡ c^d (mod n)。

三、iOS RSA加密算法的實現

在iOS中,可以使用Security.framework提供的API函數實現RSA加密和解密。

四、iOS RSA加密算法示例代碼

#include <Security/Security.h>

// RSA加密
+ (NSString *)rsaEncryptString:(NSString *)str publicKey:(NSString *)pubKey {
    NSData *plainData = [str dataUsingEncoding:NSUTF8StringEncoding];
    SecKeyRef keyRef = [self addPublicKey:pubKey];
    size_t cipherBufferSize = SecKeyGetBlockSize(keyRef);
    uint8_t *cipherBuffer = malloc(cipherBufferSize);
    memset(cipherBuffer, 0, cipherBufferSize);
    NSData *pubKeyData = [pubKey dataUsingEncoding:NSUTF8StringEncoding];
    NSString *tag = @"RSAEncryption";
    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
    [attributes setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
    [attributes setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    [attributes setObject:tag forKey:(__bridge id)kSecAttrApplicationTag];
    [attributes setObject:pubKeyData forKey:(__bridge id)kSecValueData];
    [attributes setObject:@(YES) forKey:(__bridge id)kSecReturnPersistentRef];
    CFTypeRef persistKey = nil;
    OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, &persistKey);
    if (persistKey != nil){
        CFRelease(persistKey);
    }
    if (status != noErr){
        return @"";
    }
    NSData *keyData = [self getPublicKey:pubKey];
    SecKeyRef key = [self addPublicKey:keyData];
    uint8_t *srcbuf = (uint8_t *)[plainData bytes];
    size_t srclen = strlen((char *)srcbuf);
    size_t outlen = cipherBufferSize;
    OSStatus status1 = SecKeyEncrypt(key, kSecPaddingPKCS1, srcbuf, srclen, &cipherBuffer[0], &outlen);
    NSData *cipherData = nil;
    if (status1 == noErr){
        cipherData = [NSData dataWithBytes:cipherBuffer length:outlen];
    }
    if (cipherBuffer){
        free(cipherBuffer);
    }
    return [cipherData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}

// RSA解密
+ (NSString *)rsaDecryptString:(NSString *)str privateKey:(NSString *)privKey {
    NSData *cipherData = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSData *prikeyData = [privKey dataUsingEncoding:NSUTF8StringEncoding];
    SecKeyRef keyRef = [self addPrivateKey:prikeyData];
    size_t plainBufferSize = SecKeyGetBlockSize(keyRef);
    uint8_t *plainBuffer = malloc(plainBufferSize);
    memset(plainBuffer, 0, plainBufferSize);
    size_t cipherBufferSize = [cipherData length];
    const void *cipherBuffer = [cipherData bytes];
    OSStatus status = SecKeyDecrypt(keyRef, kSecPaddingPKCS1, cipherBuffer, cipherBufferSize, plainBuffer, &plainBufferSize);
    NSMutableData *decryptedData = nil;
    if (status == noErr){
        decryptedData = [[NSMutableData alloc] initWithBytes:plainBuffer length:plainBufferSize];
    }
    if (plainBuffer){
        free(plainBuffer);
    }
    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}

// 添加公鑰
+ (SecKeyRef)addPublicKey:(NSString *)pubKey {
    NSRange spos = [pubKey rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
    NSRange epos = [pubKey rangeOfString:@"-----END PUBLIC KEY-----"];
    if (spos.location != NSNotFound && epos.location != NSNotFound){
        NSUInteger s = spos.location + spos.length;
        NSUInteger e = epos.location;
        NSRange range = NSMakeRange(s, e - s);
        pubKey = [pubKey substringWithRange:range];
    }
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@" " withString:@""];
    if (pubKey == nil){
        return nil;
    }
    NSData *data = [[NSData alloc] initWithBase64EncodedString:pubKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
    if (data == nil){
        return nil;
    }
    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
    [attributes setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
    [attributes setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    [attributes setObject:@(YES) forKey:(__bridge id)kSecReturnPersistentRef];
    SecItemDelete((__bridge CFDictionaryRef)attributes);
    [attributes setObject:data forKey:(__bridge id)kSecValueData];
    SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
    [attributes setObject:@(YES) forKey:(__bridge id)kSecReturnRef];
    [attributes setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    SecKeyRef keyRef = nil;
    SecItemCopyMatching((__bridge CFDictionaryRef)attributes, (CFTypeRef *)&keyRef);
    return keyRef;
}

// 添加私鑰
+ (SecKeyRef)addPrivateKey:(NSData *)priKey {
    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
    [attributes setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
    [attributes setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    [attributes setObject:@(YES) forKey:(__bridge id)kSecReturnPersistentRef];
    SecItemDelete((__bridge CFDictionaryRef)attributes);
    [attributes setObject:priKey forKey:(__bridge id)kSecValueData];
    [attributes setObject:(__bridge id)kSecAttrKeyClassPrivate forKey:(__bridge id)kSecAttrKeyClass];
    SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
    [attributes removeObjectForKey:(__bridge id)kSecValueData];
    [attributes setObject:@(YES) forKey:(__bridge id)kSecReturnRef];
    SecKeyRef keyRef = nil;
    SecItemCopyMatching((__bridge CFDictionaryRef)attributes, (CFTypeRef *)&keyRef);
    return keyRef;
}

// 獲取公鑰
+ (NSData *)getPublicKey:(NSString *)pubKey {
    NSRange spos = [pubKey rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
    NSRange epos = [pubKey rangeOfString:@"-----END PUBLIC KEY-----"];
    if (spos.location != NSNotFound && epos.location != NSNotFound){
        NSUInteger s = spos.location + spos.length;
        NSUInteger e = epos.location;
        NSRange range = NSMakeRange(s, e - s);
        pubKey = [pubKey substringWithRange:range];
    }
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    pubKey = [pubKey stringByReplacingOccurrencesOfString:@" " withString:@""];
    if (pubKey == nil){
        return nil;
    }
    NSData *data = [[NSData alloc] initWithBase64EncodedString:pubKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
    return data;
}

五、iOS RSA加密算法的應用

iOS RSA加密算法可以應用於iOS應用數據傳輸安全,例如在iOS應用進行網絡請求時,可以將敏感數據通過RSA加密後傳輸,保障數據傳輸的安全性。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/156517.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-18 01:56
下一篇 2024-11-18 01:56

相關推薦

  • Git secbit:一種新型的安全Git版本

    Git secbit是一種新型的安全Git版本,它在保持Git原有功能的同時,針對Git存在的安全漏洞做出了很大的改進。下面我們將從多個方面對Git secbit做詳細地闡述。 一…

    編程 2025-04-29
  • 手機安全模式怎麼解除?

    安全模式是一種手機自身的保護模式,它會禁用第三方應用程序並使用僅限基本系統功能。但有時候,安全模式會使你無法使用手機上的一些重要功能。如果你想解除手機安全模式,可以嘗試以下方法: …

    編程 2025-04-28
  • Powersploit:安全評估與滲透測試的利器

    本文將重點介紹Powersploit,並給出相關的完整的代碼示例,幫助安全人員更好地運用Powersploit進行安全評估和滲透測試。 一、Powersploit簡介 Powers…

    編程 2025-04-28
  • jiia password – 保護您的密碼安全

    你是否曾經遇到過忘記密碼、密碼泄露等問題?jiia password 正是一款為此而生的解決方案。本文將從加密方案、密碼管理、多平台支持等多個方面,為您詳細闡述 jiia pass…

    編程 2025-04-27
  • Rappor——谷歌推出的安全數據收集方案

    Rappor是一種隱私保護技術,可以在保持用戶私密信息的前提下,收集用戶的隨機信號數據。它可以用於應對廣泛的數據收集需求,讓用戶在參與數據收集的過程中感到安全和安心。 一、Rapp…

    編程 2025-04-27
  • 神經網絡代碼詳解

    神經網絡作為一種人工智能技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網絡的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網絡模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web服務器。nginx是一個高性能的反向代理web服務器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分布式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25

發表回復

登錄後才能評論