ios常见加密解密方法(RSA、DES 、AES、MD5)

下面我来详细讲解一下"iOS常见加密解密方法(RSA、DES、AES、MD5)"的完整攻略。

RSA加密解密方法

RSA加密原理:

RSA加密算法是一种非对称加密算法,加密和解密使用不同的密钥,分别称为公钥和私钥。公钥可以随意传播,任何人都可以获得,但私钥只有加密者才持有。加密时使用公钥进行加密,解密时使用私钥进行解密。

iOS中RSA加解密的步骤:

(1)生成RSA密钥对。

SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
NSMutableDictionary * privateKeyAttr = [NSMutableDictionary dictionaryWithCapacity:0];
NSMutableDictionary * publicKeyAttr = [NSMutableDictionary dictionaryWithCapacity:0];
NSMutableDictionary * keyPairAttr = [NSMutableDictionary dictionaryWithCapacity:0];

NSString * pubKeyPath = [[NSBundle mainBundle] pathForResource:@"rsa_public_key.der" ofType:nil];
NSString * privKeyPath = [[NSBundle mainBundle] pathForResource:@"rsa_private_key.p12" ofType:nil];

NSData * pubKeyData = [[NSData alloc] initWithContentsOfFile:pubKeyPath];
NSData * privKeyData = [[NSData alloc] initWithContentsOfFile:privKeyPath];

[privateKeyAttr setObject:@"Your_password_for_private_key" forKey:(__bridge id)kSecImportExportPassphrase];

OSStatus err = noErr;

[publicKeyAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[publicKeyAttr setObject:@(1024) forKey:(__bridge id)kSecAttrKeySizeInBits];

[keyPairAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[keyPairAttr setObject:@(1024) forKey:(__bridge id)kSecAttrKeySizeInBits];
[keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs];
[keyPairAttr setObject:privateKeyAttr forKey:(__bridge id)kSecPrivateKeyAttrs];

err = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);

if (err != noErr) {
    NSLog(@"生成密钥对出错 err = %d", (int)err);
}

(2) 使用公钥进行加密。

+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKeyPath{
    NSData * pubKeyData = [[NSData alloc] initWithContentsOfFile:pubKeyPath];
    NSString * encryptedStr = nil;
    SecKeyRef pubKeyRef = [self getPublicKeyRefFromData:pubKeyData];
    encryptedStr = [self encryptString:str usingPublicKey:pubKeyRef];
    return encryptedStr;
}

+ (SecKeyRef)getPublicKeyRefFromData:(NSData *)derData{
    SecCertificateRef myCertificate = nil;
    myCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(derData));
    SecKeyRef publicKeyRef = NULL;
    SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
    SecTrustRef myTrust = nil;
    OSStatus status = SecTrustCreateWithCertificates(myCertificate, myPolicy, &myTrust);
    SecTrustResultType trustResult = 0;
    if (status == noErr) {
        status = SecTrustEvaluate(myTrust, &trustResult);
    }
    if (status == noErr && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified)) {
        publicKeyRef = SecTrustCopyPublicKey(myTrust);
    }
    CFRelease(myCertificate);
    CFRelease(myPolicy);
    CFRelease(myTrust);
    return publicKeyRef;
}

+ (NSString *)encryptString:(NSString *)str usingPublicKey:(SecKeyRef)publicKey{
    NSData * plainData = [str dataUsingEncoding:NSUTF8StringEncoding];
    size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
    uint8_t * cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
    memset(cipherBuffer, 0x0, cipherBufferSize);
    size_t blockSize = cipherBufferSize - 11;

    NSMutableData * encryptedData = [NSMutableData dataWithCapacity:0];

    for (int i=0; i<[plainData length] / blockSize + 1; i++) {
        size_t chunkSize = MIN(blockSize, [plainData length]-i*blockSize);
        NSData *chunk = [plainData subdataWithRange:NSMakeRange(i*blockSize, chunkSize)];
        OSStatus status = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, [chunk bytes], [chunk length], cipherBuffer, &cipherBufferSize);
        if (status == noErr) {
            NSData * encryptedChunk = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];
            [encryptedData appendData:encryptedChunk];
        } else {
            if (cipherBuffer) {
                free(cipherBuffer);
            }
            return nil;
        }
    }

    if (cipherBuffer) {
        free(cipherBuffer);
    }

    NSString * base64EncryptedString = [encryptedData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    return base64EncryptedString;
}

示例一:加密字符串。

NSString * encryptedStr = [RSAUtils encryptString:@"123456" publicKey:[NSString stringWithFormat:@"%@/rsa_public_key.der", [[NSBundle mainBundle]bundlePath]]];
NSLog(@"加密后的字符串:%@", encryptedStr);

示例二:iOS中发送加密RSA请求的过程。

NSURL * url = [NSURL URLWithString:@"https://api.example.com/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
NSString * encryptedStr = [RSAUtils encryptString:@"123456" publicKey:[NSString stringWithFormat:@"%@/rsa_public_key.der", [[NSBundle mainBundle]bundlePath]]];
NSString * paramsString = [NSString stringWithFormat:@"username=%@&password=%@", @"user@example.com", encryptedStr];
NSData * postData = [paramsString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
[request setValue:[NSString stringWithFormat:@"%d", (int)([postData length])] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (!error) {
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@", jsonDict);
    } else {
        NSLog(@"%@", error.localizedDescription);
    }
}];
[task resume];

DES加密解密方法

DES加密原理:

DES是一种对称加密算法,加密和解密使用相同的密钥。由于DES加密算法加密过程比较简单,因此在网络传输过程中,如果不加密会导致数据泄露的风险。DES加密算法使用一个64位的密钥对数据进行加密和解密,如果密钥长度不足64位,则可以在密钥后面使用0进行填充。

iOS中DES加解密的步骤:

(1)对需要加密的字符串进行填充,使其长度为8的整数倍。

+ (NSData *) padding
{
    NSString *text = @"123456";
    int paddingSize = DES_BLOCK_SIZE - text.length % DES_BLOCK_SIZE;
    char padding[paddingSize];
    memset(padding, (char) paddingSize, paddingSize);
    NSString *append = [[NSString alloc] initWithBytes:padding length:paddingSize encoding:NSASCIIStringEncoding];
    NSString *plaintext = [text stringByAppendingString:append];
    return [plaintext dataUsingEncoding:NSASCIIStringEncoding];
}

(2) 用DES加密算法对填充后的数据进行加密。

+ (NSData *)desEncrypt:(NSString *)plainText withKey:(NSString *)key
{
    NSData * textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [textData length];

    // 对字符串使用PKCS7 Padding填充
    int paddingSize = DES_BLOCK_SIZE - dataLength % DES_BLOCK_SIZE;
    char padding[paddingSize];
    memset(padding, (char)paddingSize, paddingSize);
    NSString *append = [[NSString alloc] initWithBytes:padding length:paddingSize encoding:NSASCIIStringEncoding];
    NSString *plaintext = [plainText stringByAppendingString:append];
    NSData *textToEncrypt = [plaintext dataUsingEncoding:NSUTF8StringEncoding];

    // 将NSString类型的密钥转换为NSData类型
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    char keyBytes[32];
    memset(keyBytes, 0, sizeof(keyBytes));
    [keyData getBytes:keyBytes length:sizeof(keyBytes)];

    // 对加密结果进行长度校验、输出、填充
    NSUInteger newLength = textToEncrypt.length + kCCBlockSizeDES;
    char *newPointer = malloc(newLength);
    memset(newPointer, 0, newLength);
    size_t bytesWritten = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding,
                                          keyBytes, kCCKeySizeDES,
                                          NULL,
                                          textToEncrypt.bytes, textToEncrypt.length,
                                          newPointer, newLength, &bytesWritten);
    if (cryptStatus == kCCSuccess) {
        NSData *result = [NSData dataWithBytesNoCopy:newPointer length:bytesWritten];
        return result;
    }

    free(newPointer);
    return nil;
}

示例一:使用DES加密字符串。

NSData *data = [DesUtils desEncrypt:@"123456" withKey:@"1234567890abcdefghijk"];
NSString *base64Str = [data base64EncodedStringWithOptions:0];
NSLog(@"加密后的Base64字符串:%@", base64Str);

示例二:iOS中发送加密DES请求的过程。

//加密数据
NSData *data = [DesUtils desEncrypt:@"123456" withKey:@"1234567890abcdefghijk"];

//将加密后的数据转成Base64字符串
NSString *base64Str = [data base64EncodedStringWithOptions:0];

//构造请求url
NSString *url = [NSString stringWithFormat:@"http://www.example.com/login?username=user@example.com&password=%@", base64Str];

//发送请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"请求失败:%@", error);
    } else {
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@", jsonDict);
    }
}];

[task resume];

AES加密解密方法

AES加密原理:

AES是一种对称加密算法,加密和解密使用相同的密钥。AES加密算法运用了一些更高级的加密技术,比如迭代、替代和置换,因此AES加密算法的安全级别比起DES加密算法来说更高。AES加密算法支持多种密钥长度,比如128位、192位和256位。

iOS中AES加解密的步骤:

(1)对需要加密的字符串进行填充。

+ (NSData *)padding:(NSString *)plainText
{
    NSMutableData *mutableData = [NSMutableData dataWithData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
    //若总长度不是blockSize倍数,补充长度(blockSize-totalBytes%blockSize)的填充字节
    NSUInteger totalBytes = mutableData.length;
    NSUInteger paddingBytes = DES_BLOCK_SIZE - (totalBytes % DES_BLOCK_SIZE);
    if (paddingBytes == 0) {
        paddingBytes = DES_BLOCK_SIZE;
    }
    for (NSInteger i = 0; i < paddingBytes; i++) {
        [mutableData appendBytes:&paddingBytes length:1];
    }
    return [mutableData copy];
}

(2)用AES加密算法对填充后的数据进行加密。

+ (NSData *) encryptUseAES128:(NSString *)plainText withKey:(NSString *)key
{
    NSData *data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    NSUInteger keyLength = [key length];
    unsigned char keyBytes[kCCKeySizeAES256+1];
    memset(keyBytes, 0, sizeof(keyBytes));
    [key getCString:(char *)keyBytes maxLength:sizeof(keyBytes) encoding:NSUTF8StringEncoding];
    unsigned char iv[kCCBlockSizeAES128+1];
    memset(iv, 0, sizeof(iv));
    int base64ResultLength = ((dataLength + kCCBlockSizeAES128) / kCCBlockSizeAES128) * kCCBlockSizeAES128;
    unsigned char *base64Result = malloc(base64ResultLength);
    memset(base64Result, 0, base64ResultLength);
    size_t outLength;
    CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyBytes, kCCKeySizeAES256, iv, [data bytes], dataLength, base64Result, base64ResultLength, &outLength);
    NSData *nsResult = [NSData dataWithBytes:base64Result length:outLength];
    free(base64Result);
    return nsResult;
}

(3)对AES加密结果进行解密。

+ (NSData *) decryptUseAES128:(NSString *)cipherText withKey:(NSString *)key
{
    NSData * data = [[NSData alloc]initWithBase64EncodedString:cipherText options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSUInteger dataLength = [data length];
    NSUInteger keyLength = [key length];
    unsigned char keyBytes[kCCKeySizeAES256+1];
    memset(keyBytes, 0, sizeof(keyBytes));
    [key getCString:(char *)keyBytes maxLength:sizeof(keyBytes) encoding:NSUTF8StringEncoding];
    unsigned char iv[kCCBlockSizeAES128+1];
    memset(iv, 0, sizeof(iv));
    int base64ResultLength = ((dataLength + kCCBlockSizeAES128) / kCCBlockSizeAES128) * kCCBlockSizeAES128;
    unsigned char *base64Result = malloc(base64ResultLength);
    memset(base64Result, 0, base64ResultLength);
    size_t outLength;
    CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyBytes, kCCKeySizeAES256, iv, [data bytes], dataLength, base64Result, base64ResultLength, &outLength);
    NSData *nsResult = [NSData dataWithBytes:base64Result length:outLength];
    free(base64Result);
    return nsResult;
}

示例一:使用AES加密字符串。

NSString *encryptedStr = [AesUtils encryptString:@"123456" withKey:@"1234567890abcdefghijklmnopqrstuvwxy"];
NSLog(@"加密后的字符串:%@", encryptedStr);

示例二:iOS中发送加密AES请求的过程。

//构造请求url
NSString *base64Str = [[AesUtils encryptString:@"123456" withKey:@"1234567890abcdefghijklmnopqrstuvwxy"] base64EncodedStringWithOptions:0];
NSString *url = [NSString stringWithFormat:@"http://www.example.com/login?username=user@example.com&password=%@", base64Str];

//发送请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"请求失败:%@", error);
    } else {
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"%@", jsonDict);
    }
}];

[task resume];

MD5加密方法

MD5加密原理:

MD5算法是一种单向散列函数,它可以把任意长度的数据“散列”成128位的数值。散列函数的特征是,对于不同的输入,输出的结果是不同的,而且对于同样的输入,输出结果也是不同的。MD5算法产生的128位的散列值通常是表示为32个十六进制数(0-F)的字符串。MD5算法适合用于信息摘要和消息认证。

iOS中MD5加密的步骤:

(1)对需要加密的字符串转化为NSData。

+ (NSData *)dataFromString:(NSString *)string
{
    return [string dataUsingEncoding:NSUTF8StringEncoding];
}

(2) 使用系统提供的Secrity框架的MD5函数进行加密。

```
+ (NSString )md5WithString:(NSString )string
{
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
NSData data = [self dataFromString:string];
CC_MD5_Update(&md5, [data bytes], (CC_LONG)[data length]);
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &md5);
NSMutableString
stringBuffer = [NSMutableString stringWithCapacity:(CC_MD5_DIGEST_LENGTH * 2)];
for (

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ios常见加密解密方法(RSA、DES 、AES、MD5) - Python技术站

(2)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 详细解析命令行的getopt_long()函数

    详细解析命令行的getopt_long()函数 什么是getopt_long()函数 getopt_long()函数是一个用于解析命令行参数的函数。它可以将命令行参数转换成易于处理的形式,便于程序进行后续的处理。getopt_long()函数基于POSIX标准,可以在UNIX/Linux操作系统及GNU系统中使用。 getopt_long()函数的用法 ge…

    other 2023年6月26日
    00
  • Linux修改fstab文件后 系统无法启动的解决方法

    下面是关于“Linux修改fstab文件后系统无法启动的解决方法”的具体攻略: 问题描述 当我们对Linux系统进行一些配置后,比如挂载新的磁盘、分区等操作,就需要修改fstab文件来使其永久化。但是,如果在修改fstab文件时出现错误,可能就会导致系统无法启动,无法进入操作系统界面。 解决方案 为了解决这个问题,我们可以按照以下步骤进行操作: 1.使用Li…

    other 2023年6月27日
    00
  • SpringBoot yml配置文件读取方法详解

    下面是关于“SpringBoot yml配置文件读取方法详解”的完整攻略。 什么是yml配置文件? yml文件,全称为YAML Ain’t Markup Language,它是一种简洁的文本格式,通常被用来作为各种数据的存储和传输方式。yml文件相对于其他配置文件来说,具有非常好的可读性和可维护性。 在Spring Boot中,我们可以使用yml文件来配置我…

    other 2023年6月25日
    00
  • 基于Python的接口自动化unittest测试框架和ddt数据驱动详解

    以下是基于Python的接口自动化unittest测试框架和ddt数据驱动的完整攻略: 1. 安装unittest和ddt库 首先,确保您已经安装了Python,并使用pip命令安装unittest和ddt库: pip install unittest pip install ddt 2. 创建测试类和测试方法 在Python中,使用unittest库创建测…

    other 2023年10月16日
    00
  • ES6字符串的扩展实例

    ES6字符串的扩展是 ECMAScript 2015 标准(以下简称ES6)中增加的一系列字符串相关的功能。这些新特性包括模板字符串、多行字符串、字符串的扩展方法等。本文将给出一份扩展实例攻略,来帮助你更好地了解 ES6 字符串的使用方法。 模板字符串 模板字符串是ES6中一种新的字符串类型,用一对反引号(`)括起来,并且可以在其中嵌入表达式或变量。 下面是…

    other 2023年6月20日
    00
  • openwrt安装tcpdump

    OpenWrt安装tcpdump tcpdump是一款常用的网络抓包工具,可以用于分析网络流量。在OpenWrt中,我们可以使用opkg命令来安装tcpdump。以下是安装tcpdump的完整攻略。 步骤 以下是在OpenWrt中安装tcpdump的步骤: 连接Wrt:我们需要连接到Wrt路由器。 安装tcpdump:我们需要使用opkg命令来安装tcpdu…

    other 2023年5月6日
    00
  • TypeScript数组的定义与使用详解

    TypeScript数组的定义与使用详解 在 TypeScript 中,可以使用数组来存储一系列的值,本文将详细讲解 TypeScript 数组的定义与使用。 1. 定义数组 在 TypeScript 中,可以通过以下方式定义一个数组: // 定义一个字符串数组 let arr1: string[] = [‘apple’, ‘banana’, ‘orange…

    other 2023年6月25日
    00
  • css样式的优先级究竟庞杂到什么程度

    标题:CSS样式的优先级完整攻略 1. 优先级的概念 在CSS中,样式的优先级决定了多个样式规则之间的应用顺序。当同一个元素有多个样式规则时,优先级规则帮助确定哪些样式会被应用在元素上。 2. 优先级的计算规则 下面是计算优先级的规则,按照顺序依次比较: 2.1. 选择器的特殊性(Specificity) 特殊性指的是选择器的权重,权重越高,优先级别越高。计…

    other 2023年6月28日
    00
合作推广
合作推广
分享本页
返回顶部