rsa部分使用了openssl,如何打包使用请看另一篇文字 iOS使用openssl库以及DSA加密_strong90的博客-优快云博客
.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;
}