iOS oc的res加密、解密,以及rsa解密

rsa部分使用了openssl,如何打包使用请看另一篇文字 iOS使用openssl库以及DSA加密_strong90的博客-CSDN博客

.h 文件

//
//  Openssl_Decrypt.h
//
//  Created by kk on 2022/7/1.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Openssl_Decrypt : NSObject

/* 功能:Rsa公钥解密
 * 参数:
 *     encryptFile:加密文件路径+名字
 *     rsaKey:Rsa Public Key
*/
+ (NSData *)rsaDecryptData:(NSData *)encryptedData rsaKey:(NSString *)rsaKey;


/* 功能:计算MD5摘要
 * 参数:
 *     data:原数据
*/
+ (NSString*)getMD5WithData:(NSData *)data;

/* 功能:Aes解密
 * 参数:
 *     encryptFile:加密文件路径+名字
 *     aesKey:Aes Key
*/
+ (NSData *)decryptAESWithData:(NSData *)data key:(NSString *)key;

// 加密方法
+ (NSData *)encryptAES:(NSData *)contentData key:(NSString *)key;

@end

NS_ASSUME_NONNULL_END

.m 文件

//
//  Openssl_Decrypt.m
//
//  Created by kk on 2022/7/1.
//

#import "Openssl_Decrypt.h"
#include "include/openssl/rsa.h"
#include "include/openssl/md5.h"
#include "include/openssl/pem.h"
#include "include/openssl/aes.h"
#include "include/openssl/crypto.h"
#include "include/openssl/evp.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import "HelpUtils.h"
#import "GTMBase64.h"
#import "stdio.h"

@implementation Openssl_Decrypt
// RSA 解密
+ (NSData *)rsaDecryptData:(NSData *)encryptedData rsaKey:(NSString *)rsaKey {
    if (encryptedData && [encryptedData length]) {

        BIO *in = BIO_new(BIO_s_mem());
        int bio_result = BIO_puts(in, [rsaKey cStringUsingEncoding: NSUTF8StringEncoding]);
        if (bio_result < 0) {
            NSLog(@"CDecrypt::rsaDecrypt() BIO_puts failed!");
            BIO_free(in);
            return nil;
        }

        RSA *rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
        BIO_free(in);
        if (rsa == nil) {
            NSLog(@"CDecrypt::rsaDecrypt() create rsa failed!");
            return nil;
        }

        //计划解密长度
        int planSubLength = 256;
        //数据总长度
        NSInteger sumLength = [encryptedData length];
        //分段数
        NSInteger blockCount = sumLength/planSubLength + ((sumLength%planSubLength)?1:0);
        //存放解密后的数据
        NSMutableData *sumData = [[NSMutableData alloc ] initWithCapacity:0];
        for(int i = 0;i < blockCount; i++)
        {
            //实际分段的长度,注意最后一段不够的情况
            int realSubLength = (int)MIN(planSubLength, sumLength - i*planSubLength);
            //定义存放待解密数据的数组encryptedArr(密文,较长)
            unsigned char encryptedArr[planSubLength];
            //C函数,初始化置空encryptedArr数组
            bzero(encryptedArr, sizeof(encryptedArr));
            //将待解密的data数据存放入encryptedArr数组中
            memcpy(encryptedArr, [[encryptedData subdataWithRange:NSMakeRange(i*planSubLength, realSubLength)] bytes], realSubLength);
            //定义存放解密出来的数据的数组expressArr(明文,较短)
            unsigned char expressArr[realSubLength];
            //初始化置空expressArr数组
            bzero(expressArr, sizeof(expressArr));
            //解密encryptedArr中的数据并存入expressArr中
            int status =  RSA_public_decrypt(realSubLength, encryptedArr, expressArr, rsa, RSA_PKCS1_PADDING);
            if (status < 0) {
                NSLog(@"CDecrypt::rsaDecrypt() rsa decrypt failed!");
                return nil;
            }
            int k=0;
            // 拼接
            for(int j = 0;j< planSubLength;j++)
            {
                if(expressArr[j] != '\0')
                {
                    k = j+1;
                }
            }
            // 拼接解密出来的数据
            [sumData appendData:[NSData dataWithBytes:expressArr length:k]];
        }
//        NSString *str = [[NSString alloc] initWithData:sumData encoding:NSASCIIStringEncoding];
        NSLog(@"rsa sumData == %@", sumData);
        return sumData;
    }
    return nil;
}

#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ (NSString*)getMD5WithData:(NSData *)data{
    CC_MD5_CTX md5;
    CC_MD5_Init(&md5);
    CC_MD5_Update(&md5, data.bytes, (uint32_t)data.length);
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5_Final(result, &md5);
    NSMutableString *resultString = [NSMutableString string];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
      [resultString appendFormat:@"%02x", result[i]];
    }
    return resultString;
}

+ (NSData *)encryptAES:(NSData *)contentData key:(NSString *)key {
    NSUInteger dataLength = contentData.length;
    // 为结束符'\0' +1
    char keyPtr[kCCKeySizeAES256 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    // 密文长度 <= 明文长度 + BlockSize
    size_t encryptSize = dataLength + kCCBlockSizeAES128;
    void *encryptedBytes = malloc(encryptSize);
    size_t actualOutSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(
                                kCCEncrypt,//kCCEncrypt 代表加密 kCCDecrypt代表解密
                                kCCAlgorithmAES,//加密算法
                                kCCOptionPKCS7Padding | kCCOptionECBMode,  // 系统默认使用 CBC,然后指明使用 PKCS7Padding,iOS只有CBC和ECB模式,如果想使用ECB模式,可以这样编写  kCCOptionPKCS7Padding | kCCOptionECBMode
                                keyPtr,//公钥
                                kCCKeySizeAES128,//密钥长度128
                                NULL,//偏移字符串
                                contentData.bytes,//编码内容
                                dataLength,//数据长度
                                encryptedBytes,//加密输出缓冲区
                                encryptSize,//加密输出缓冲区大小
                                &actualOutSize);//实际输出大小
    
    if (cryptStatus == kCCSuccess) {
        // 返回编码后的数据
        return [NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize];
    }
    free(encryptedBytes);
    return nil;
}

// AES ECB 解密
+ (NSData *)decryptAESWithData:(NSData *)data key:(NSString *)key{

    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    BOOL tryKeyPtr = [unicodeString getCString:keyPtr maxLength:sizeof(keyPtr) encoding:1];

    NSLog(@"tryKeyPtr == %d",tryKeyPtr);
    NSLog(@"AES keyPtr == %s",keyPtr);

    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(
                                kCCDecrypt,
                                kCCAlgorithmAES,
                                kCCOptionPKCS7Padding | kCCOptionECBMode,
                                keyPtr,
                                kCCBlockSizeAES128,
                                NULL,
                                [data bytes],
                                dataLength,
                                buffer,
                                bufferSize,
                                &numBytesDecrypted
                                );

    if (cryptStatus == kCCSuccess) {
        NSData *outData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

        NSLog(@"加密data == %lu", data.length);
        NSLog(@"解密data == %lu", outData.length);
        
        return outData;
    }
    free(buffer);
    return nil;
}


@end

ps:使用openssl进行解密,同时java后台使用 byte[] 数组进行加密的情况下的,aes解密代码

+ (NSData *)aesDecrypt:(NSData *)encryptData key:(NSString *)inKey {
    
    int write_len = (int)[encryptData length];
    
    
    unsigned char aesKey[kCCKeySizeAES192 + 1] = {0};
    for(int i = 0; i < inKey.length; i += 2)
    {
        sscanf([inKey cStringUsingEncoding:NSUTF8StringEncoding] + i,"%2hhx", aesKey + i / 2);
    }
    AES_KEY key;
    AES_set_decrypt_key(aesKey, 192, &key);
    
    size_t bufferSize = write_len + kCCBlockSizeAES128;
    unsigned char *decryptData = malloc(bufferSize);
    size_t decryptDataLen = 0;
    
    for (int i = 0; i < write_len/16; i++){
        AES_decrypt(([encryptData bytes] + i * AES_BLOCK_SIZE), (decryptData + i * AES_BLOCK_SIZE), &key);
    }
    unsigned char data = decryptData[write_len - 1];
    int same = 0;
    for (int i = 0; i < write_len; i++)
    {
        if (data == decryptData[write_len - 1 - i])
        {
            same++;
        }
        else
        {
            break;
        }
    }
    if (same > 0 && same >= data)
    {
        write_len = write_len - data;
    }
    decryptDataLen = write_len;
    NSData *outData = [NSData dataWithBytesNoCopy:decryptData length:decryptDataLen];

    NSLog(@"加密data == %lu", encryptData.length);
    NSLog(@"解密data == %lu", outData.length);
    return outData;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值