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

yizhihongxing

下面我来详细讲解一下"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日

相关文章

  • linux之jq

    Linux之jq的完整攻略 jq是一个命令行工具,用于处理JSON格式的数据。它可以帮助用户快速地查询、过滤、转换和格式化JSON数据。本文将详细讲解jq的使用方法,并提供两个示例说明。 1. 安装jq 在Linux系统中,可以使用以下命令安装jq: sudo apt-get install jq 2. jq的基本用法 2.1 查询JSON数据 可以使用jq…

    other 2023年5月9日
    00
  • 简单高效有用的正则表达式

    简单高效有用的正则表达式攻略 正则表达式是一种强大的文本匹配工具,可以用于在字符串中查找、替换和提取特定的模式。下面是一份简单高效有用的正则表达式攻略,帮助您更好地理解和应用正则表达式。 1. 基本语法 正则表达式由普通字符和特殊字符组成。普通字符表示它们自身,而特殊字符具有特殊的含义。以下是一些常见的特殊字符: .:匹配任意字符(除了换行符) *:匹配前面…

    other 2023年8月18日
    00
  • Linux下快速比较两个目录的不同(多种方法)

    这里提供一份在Linux下快速比较两个目录的不同的攻略,主要介绍两种方法,分别是使用diff和rsync命令。 使用diff命令 diff命令可以用来比较两个文件之间的差异,我们可以使用它来比较两个目录中的文件。使用方法如下: diff -r dir1/ dir2/ 其中dir1/和dir2/分别代表需要比较的两个目录,-r参数是递归比较子目录。执行以上命令…

    other 2023年6月26日
    00
  • Java读取Oracle大字段数据(CLOB)的2种方法

    下面我将通过Markdown格式的文本向您详细讲解Java读取Oracle大字段数据(CLOB)的2种方法。 准备工作 在使用Java读取Oracle CLOB字段之前,需要先导入相关的Java库: import java.io.BufferedReader; import java.io.IOException; import java.io.InputS…

    other 2023年6月25日
    00
  • 如何利用adb卸载手机预装软件(系统软件)

    如何利用adb卸载手机预装软件(系统软件) 以下是利用adb卸载手机预装软件的完整攻略: 步骤1:启用开发者选项和USB调试模式 在手机的设置中,找到“关于手机”或“关于设备”选项,连续点击“版本号”或“构建号”多次,直到开启开发者选项。然后返回到设置主界面,找到“开发者选项”,进入并启用“USB调试”模式。 步骤2:连接手机到电脑 使用USB数据线将手机连…

    other 2023年10月13日
    00
  • linux cgroups详细介绍

    Linux cgroups详细介绍 什么是cgroups cgroups(control groups)是Linux内核提供的一种机制,它允许你限制、分配和监控系统资源(如CPU、内存、磁盘IO等)的使用。cgroups可以通过文件系统的形式,将一组进程放置在一个子系统中。 cgroups的应用场景 cgroups常用于以下场景: 系统性能优化:通过控制资源…

    other 2023年6月27日
    00
  • jupyter notebook内核启动失败问题及解决方法

    jupyter notebook内核启动失败问题及解决方法 问题描述 在使用jupyter notebook时,有时候会遇到内核启动失败的问题,具体表现为在notebook中无法执行代码或新建code cell,提示信息为“Kernel not found”、“No kernel”或“Connection failed”。 已知原因 该问题可能由多种原因导致…

    other 2023年6月26日
    00
  • C++11新特性之列表初始化的具体使用

    C++11引入了许多新特性,而其中之一便是列表初始化。本文将为读者介绍C++11中的列表初始化的具体使用和示例说明。 列表初始化的基本语法 列表初始化使用花括号 {} 包含可选的一个或多个逗号分隔的元素。可以使用列表初始化初始化基本类型、数组、结构体等各种数据类型。 下面是使用列表初始化初始化基本类型的示例: int num1{10}; // 使用列表初始化…

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