123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- //
- // JXMsgUtil.m
- // shiku_im
- //
- // Created by p on 2019/7/31.
- // Copyright © 2019 Reese. All rights reserved.
- //
- #import "JXMsgUtil.h"
- #import "ECkeyUtils.h"
- #import "MD5Util.h"
- #import "AESUtil.h"
- #import "JXUserPublicKeyObj.h"
- @interface JXMsgUtil()
- @end
- @implementation JXMsgUtil
- +(instancetype)sharedManager {
- static dispatch_once_t onceToken;
- static JXMsgUtil *instance;
- dispatch_once(&onceToken, ^{
- instance = [[JXMsgUtil alloc] init];
- });
- return instance;
- }
- - (instancetype)init {
- if ([super init]) {
-
- self.verifyFailedDic = [NSMutableDictionary dictionary];
- self.getDHListIds = [NSMutableArray array];
- [g_notify addObserver:self selector:@selector(newMsgCome:) name:kXMPPNewMsgNotifaction object:nil];//收到了一条新消息
- }
- return self;
- }
- #pragma mark 接受新消息广播
- -(void)newMsgCome:(NSNotification *)notifacation {
- JXMessageObject *msg = notifacation.object;
- if ([msg.type intValue] == kWCMessageTypeUpdateFriendPublicKey) {
-
- NSArray *keys = [msg.content componentsSeparatedByString:@","];
- if (keys.count > 0) {
-
- // 更新好友的DH和RSA公钥
- JXUserObject *user = [[JXUserObject sharedInstance] getUserById:msg.fromUserId];
- user.publicKeyDH = keys.firstObject;
- user.publicKeyRSARoom = keys.lastObject;
- [user updateDHPublicKeyAndRSAPublicKey];
-
-
- // 插入到公钥表
- JXUserPublicKeyObj *keyObj = [[JXUserPublicKeyObj alloc] init];
- keyObj.userId = msg.fromUserId;
- keyObj.publicKey = keys.firstObject;
- keyObj.keyCreateTime = msg.timeSend;
- [keyObj insert];
- }
- }
- }
- - (void)setDhPublicKey:(NSString *)dhPublicKey {
- _dhPublicKey = dhPublicKey;
- _dhPublicPem = [ECkeyUtils getPemKeyFromKey:dhPublicKey isPrivate:NO];
- }
- - (void)setDhPrivateKey:(NSString *)dhPrivateKey{
- _dhPrivateKey = dhPrivateKey;
- _dhPrivatePem = [ECkeyUtils getPemKeyFromKey:dhPrivateKey isPrivate:YES];
- }
- - (void)setDhPublicPem:(NSString *)dhPublicPem {
- _dhPublicPem = dhPublicPem;
- _dhPublicKey = [ECkeyUtils getKeyFromPemKey:dhPublicPem isPrivate:NO];
- }
- - (void)setDhPrivatePem:(NSString *)dhPrivatePem {
- _dhPrivatePem = dhPrivatePem;
- _dhPrivateKey = [ECkeyUtils getKeyFromPemKey:dhPrivatePem isPrivate:YES];
- }
- // 生成DH秘钥对
- - (void) generatekeyPairsDH {
- ECkeyUtils *keyUtils = [[ECkeyUtils alloc] init];
- [keyUtils generatekeyPairs];
- self.dhPrivatePem = keyUtils.eckeyPairs.privatePem;
- self.dhPrivateKey = keyUtils.eckeyPairs.privateKey;
- self.dhPublicPem = keyUtils.eckeyPairs.publicPem;
- self.dhPublicKey = keyUtils.eckeyPairs.publicKey;
-
- }
- // 生成群组使用的RSA秘钥对
- - (void) generatekeyPairsRSA {
-
- SecKeyRef privateKey = [g_securityUtil getRSAPrivateKey];
- SecKeyRef publicKey = [g_securityUtil getRSAPublicKeyWithPrivateKey:privateKey];
- NSData *privateData = [g_securityUtil getKeyBitsFromKey:privateKey];
- NSData *publicData = [g_securityUtil getKeyBitsFromKey:publicKey];
- NSString *privateStr = [privateData base64EncodedStringWithOptions:0];
-
- self.rsaPrivateKey = privateStr;
- self.rsaPublicKey = [g_securityUtil getKeyForJavaServer:publicData];
- }
- // 获取对称秘钥S
- - (NSData *)getMsgContentKeyWithMsgId:(NSString *)msgId key:(NSString *)key; {
-
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:APIKEY];
- [appendStr appendString:msgId];
- [appendStr appendString:key];
-
- NSData *data = [MD5Util getMD5DataWithString:appendStr];
- return data;
- }
- // 获取单聊存储本地数据库aes加密后的content
- - (NSString *)encryptInsertChatMsgContent:(NSString *)content msgId:(NSString *)msgId {
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:APIKEY];
- [appendStr appendString:msgId];
- NSData *keyData= [MD5Util getMD5DataWithString:appendStr];
-
- NSData *aesData = [AESUtil encryptAESData:[content dataUsingEncoding:NSUTF8StringEncoding] key:keyData];
- NSString *aesStr = [aesData base64EncodedStringWithOptions:0];
- return aesStr;
- }
- // 获取单聊存储本地数据库aes解密后的content
- - (NSString *)decryptInsertChatMsgContent:(NSString *)content msgId:(NSString *)msgId {
-
- if (!content || content.length <= 0) {
- return @"";
- }
-
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:APIKEY];
- [appendStr appendString:msgId];
- NSData *keyData= [MD5Util getMD5DataWithString:appendStr];
-
- NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
- NSData *aesData = [AESUtil decryptAESData:contentData key:keyData];
- NSString *aesStr = [[NSString alloc] initWithData:aesData encoding:NSUTF8StringEncoding];
- return aesStr;
- }
- // 获取单聊消息验参
- - (NSString *)getChatMsgMacWithContent:(NSString *)content fromUserId:(NSString *)fromUserId toUserId:(NSString *)toUserId isEncrypt:(NSInteger)isEncrypt msgId:(NSString *)msgId publicKey:(NSString *)publicKey {
-
- NSString *pubPem = [ECkeyUtils getPemKeyFromKey:publicKey isPrivate:NO];
-
- NSString *shareKey = [ECkeyUtils getShareKeyFromPeerPubPem:pubPem privatePem:g_msgUtil.dhPrivatePem length:32];
- if (!shareKey || shareKey.length <= 0) {
- return nil;
- }
- NSData *keyData = [self getMsgContentKeyWithMsgId:msgId key:shareKey];
- NSString *msgKey = [keyData base64EncodedStringWithOptions:0];
-
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:fromUserId];
- [appendStr appendString:toUserId];
- [appendStr appendString:[NSString stringWithFormat:@"%ld",(long)isEncrypt]];
- [appendStr appendString:msgId];
- [appendStr appendString:msgKey];
-
- NSData *macData = [g_securityUtil getHMACMD5:[content dataUsingEncoding:NSUTF8StringEncoding] key:[appendStr dataUsingEncoding:NSUTF8StringEncoding]];
- NSString *mac = [macData base64EncodedStringWithOptions:0];
- return mac;
- }
- // 获取群聊存储本地数据库aes加密后的对称秘钥
- - (NSString *)encryptRoomMsgKey:(NSString *)roomJid randomKey:(NSString *)randomKey {
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:APIKEY];
- [appendStr appendString:roomJid];
- NSData *keyData= [MD5Util getMD5DataWithString:appendStr];
-
- NSData *aesData = [AESUtil encryptAESData:[randomKey dataUsingEncoding:NSUTF8StringEncoding] key:keyData];
- NSString *aesStr = [aesData base64EncodedStringWithOptions:0];
- return aesStr;
- }
- // 获取群聊存储本地数据库aes解密后的对称秘钥
- - (NSString *)decryptRoomMsgKey:(NSString *)roomJid randomKey:(NSString *)randomKey {
-
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:APIKEY];
- [appendStr appendString:roomJid];
- NSData *keyData= [MD5Util getMD5DataWithString:appendStr];
-
- NSData *randomData = [[NSData alloc] initWithBase64EncodedString:randomKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
- NSData *data = [AESUtil decryptAESData:randomData key:keyData];
- NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- return str;
- }
- // 获取群聊消息验参
- - (NSString *)getRoomMsgMacWithContent:(NSString *)content fromUserId:(NSString *)fromUserId isEncrypt:(NSInteger)isEncrypt msgId:(NSString *)msgId randomKey:(NSString *)randomKey {
- NSMutableString *appendStr = [NSMutableString string];
- [appendStr appendString:fromUserId];
- [appendStr appendString:[NSString stringWithFormat:@"%ld",(long)isEncrypt]];
- [appendStr appendString:msgId];
- [appendStr appendString:randomKey];
-
- NSData *macData = [g_securityUtil getHMACMD5:[content dataUsingEncoding:NSUTF8StringEncoding] key:[appendStr dataUsingEncoding:NSUTF8StringEncoding]];
- NSString *mac = [macData base64EncodedStringWithOptions:0];
- return mac;
- }
- // 单聊发消息加密
- - (NSString *)encryptContentWithPublicKey:(NSString *)publicKey content:(NSString *)content msgId:(NSString *)msgId{
-
- NSString *pubPem = [ECkeyUtils getPemKeyFromKey:publicKey isPrivate:NO];
-
- NSString *shareKey = [ECkeyUtils getShareKeyFromPeerPubPem:pubPem privatePem:g_msgUtil.dhPrivatePem length:32];
- if (!shareKey || shareKey.length <= 0) {
- return nil;
- }
- NSData *keyData = [self getMsgContentKeyWithMsgId:msgId key:shareKey];
- NSData *encryptData = [AESUtil encryptAESData:[content dataUsingEncoding:NSUTF8StringEncoding] key:keyData];
- NSString *encryptStr = [encryptData base64EncodedStringWithOptions:0];
- return encryptStr;
- }
- // 单聊发消息解密
- - (NSString *)decryptContentWithPublicKey:(NSString *)publicKey content:(NSString *)content msgId:(NSString *)msgId {
-
- NSString *pubPem = [ECkeyUtils getPemKeyFromKey:publicKey isPrivate:NO];
-
- NSString *shareKey = [ECkeyUtils getShareKeyFromPeerPubPem:pubPem privatePem:g_msgUtil.dhPrivatePem length:32];
- NSData *keyData = [self getMsgContentKeyWithMsgId:msgId key:shareKey];
- NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
- NSData *decryptData = [AESUtil decryptAESData:contentData key:keyData];
- NSString *decryptStr = [[NSString alloc]initWithData:decryptData encoding:NSUTF8StringEncoding];
- return decryptStr;
- }
- // 群聊消息加密
- - (NSString *)encryptRoomContentWithUser:(JXUserObject *)user content:(NSString *)content {
- NSString *chatKeyGroup = [g_msgUtil decryptRoomMsgKey:user.roomId randomKey:user.chatKeyGroup];
- NSData *encryptData = [AESUtil encryptAESData:[content dataUsingEncoding:NSUTF8StringEncoding] key:[chatKeyGroup dataUsingEncoding:NSUTF8StringEncoding]];
- NSString *encryptStr = [encryptData base64EncodedStringWithOptions:0];
- return encryptStr;
- }
- // 群聊消息解密
- - (NSString *)decryptRoomContentWithUser:(JXUserObject *)user content:(NSString *)content {
- NSString *chatKeyGroup = [g_msgUtil decryptRoomMsgKey:user.roomId randomKey:user.chatKeyGroup];
- NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
- NSData *decryptData = [AESUtil decryptAESData:contentData key:[chatKeyGroup dataUsingEncoding:NSUTF8StringEncoding]];
-
- NSString *decryptStr = [[NSString alloc]initWithData:decryptData encoding:NSUTF8StringEncoding];
- return decryptStr;
- }
- // 获取好友公钥list
- - (void)getDHPublicKeyWithUserId:(NSString *)userId {
-
- [g_server authkeysGetDHMsgKeyListWithUserId:userId toView:self];
- }
- // 获取群组的消息秘钥
- - (void)getChatKeyGroupWithRoomId:(NSString *)roomId {
- [g_server getRoom:roomId toView:self];
- }
- - (void)didServerResultSucces:(JXConnection *)task dict:(NSDictionary *)dict array:(NSArray *)array1{
-
- if ([task.action isEqualToString:act_AuthkeysGetDHMsgKeyList]) {
-
- NSString *userId = [NSString stringWithFormat:@"%@",[dict objectForKey:@"userId"]];
-
- NSArray *publicKeyList = [dict objectForKey:@"publicKeyList"];
- for (NSInteger i = 0; i < publicKeyList.count; i ++) {
- NSDictionary *dic = publicKeyList[i];
-
- [[JXUserPublicKeyObj sharedManager] deletePublicKeyWIthUserId:userId];
-
- JXUserPublicKeyObj *obj =[[JXUserPublicKeyObj alloc] init];
- obj.userId = userId;
- obj.publicKey = [dic objectForKey:@"key"];
- obj.keyCreateTime = [NSDate dateWithTimeIntervalSince1970:[[dic objectForKey:@"time"] doubleValue]];
- [obj insert];
- }
-
- JXUserObject *user = [[JXUserObject sharedInstance] getUserById:userId];
- if (!user.publicKeyDH || user.publicKeyDH.length > 0) {
- [g_server getUser:userId toView:self];
- }
-
- // 获取好友公钥表
- NSMutableArray *keys = [[JXUserPublicKeyObj sharedManager] fetchPublicKeyWithUserId:userId];
- NSArray *msgArr = [g_msgUtil.verifyFailedDic objectForKey:userId];
- for (NSInteger i = 0; i < msgArr.count; i ++) {
- JXMessageObject *msg = msgArr[i];
-
- BOOL flag = NO;
- // 公钥表里公钥依次解密
- for (NSInteger i = 0; i < keys.count; i ++) {
- JXUserPublicKeyObj *obj = keys[i];
- if (obj.publicKey && obj.publicKey.length > 0) {
- NSString *signature = [g_msgUtil getChatMsgMacWithContent:msg.content fromUserId:msg.fromUserId toUserId:msg.toUserId isEncrypt:[msg.isEncrypt integerValue] msgId:msg.messageId publicKey:obj.publicKey];
- if ([signature isEqualToString:msg.signature]) {
- flag = YES;
- msg.content = [g_msgUtil decryptContentWithPublicKey:obj.publicKey content:msg.content msgId:msg.messageId];
- [msg update];
- break;
- }
- }
- }
-
- // if (flag) {
- // [msg update];
- // }else {
- // [msg delete];
- // }
- }
- [g_msgUtil.verifyFailedDic removeObjectForKey:userId];
- NSInteger index = 0;
- for (NSInteger i = 0; i < g_msgUtil.getDHListIds.count; i ++) {
- NSString *str = g_msgUtil.getDHListIds[i];
- if ([str isEqualToString:userId]) {
- index = i;
- break;
- }
- }
-
- [g_msgUtil.getDHListIds removeObjectAtIndex:index];
-
- }
-
- if ([task.action isEqualToString:act_UserGet]) {
- JXUserObject* user = [[JXUserObject alloc]init];
- user.userId = [dict objectForKey:@"userId"];
- user.publicKeyDH = [[dict objectForKey:@"friends"] objectForKey:@"dhMsgPublicKey"];
- user.publicKeyRSARoom = [[dict objectForKey:@"friends"] objectForKey:@"rsaMsgPublicKey"];
- [user updateDHPublicKeyAndRSAPublicKey];
- }
-
- if ([task.action isEqualToString:act_roomGet]) {
- JXUserObject* user = [[JXUserObject alloc]init];
- [user getDataFromDict:dict];
- [user updateChatKeyGroup];
-
-
- NSArray *msgArr = [g_msgUtil.verifyFailedDic objectForKey:user.userId];
- for (NSInteger i = 0; i < msgArr.count; i ++) {
- JXMessageObject *msg = msgArr[i];
-
- NSString *chatKeyGroup = [g_msgUtil decryptRoomMsgKey:user.roomId randomKey:user.chatKeyGroup];
- NSString *encryptStr = [g_msgUtil encryptRoomContentWithUser:user content:msg.content];
- NSString *signature = [g_msgUtil getRoomMsgMacWithContent:encryptStr fromUserId:msg.fromUserId isEncrypt:[msg.isEncrypt integerValue] msgId:msg.messageId randomKey:chatKeyGroup];
- if ([signature isEqualToString:msg.signature]) {
- msg.content = [g_msgUtil decryptRoomContentWithUser:user content:msg.content];
- [msg update];
- }
-
- }
- [g_msgUtil.verifyFailedDic removeObjectForKey:user.userId];
- NSInteger index = 0;
- for (NSInteger i = 0; i < g_msgUtil.getDHListIds.count; i ++) {
- NSString *str = g_msgUtil.getDHListIds[i];
- if ([str isEqualToString:user.userId]) {
- index = i;
- break;
- }
- }
-
- [g_msgUtil.getDHListIds removeObjectAtIndex:index];
- }
- }
- -(int) didServerResultFailed:(JXConnection*)aDownload dict:(NSDictionary*)dict{
- return hide_error;
- }
- -(int) didServerConnectError:(JXConnection*)aDownload error:(NSError *)error{
- return hide_error;
- }
- -(void) didServerConnectStart:(JXConnection*)aDownload{
- }
- @end
|