1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// TAPEncryptorManager.m
// TapTalk
//
// Created by Dominic Vedericho on 15/08/18.
// Copyright © 2018 Moselo. All rights reserved.
//
#import "TAPEncryptorManager.h"
static NSString * const kKeyPasswordEncryptor = @"kHT0sVGIKKpnlJE5BNkINYtuf19u6+Kk811iMuWQ5tM";
@implementation TAPEncryptorManager
#pragma mark - Lifecycle
+ (TAPEncryptorManager *)sharedManager {
static TAPEncryptorManager *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
- (id)init {
self = [super init];
if (self) {
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
}
#pragma mark - Custom Method
+ (TAPMessageModel *)encryptMessage:(TAPMessageModel *)message {
//DV Note
//Encryption Flow
// 1. Obtain message length, local ID length
// 2. Get local ID index (message length modulo by local ID length)
// 3. Generate random number from 1-9
// 4. Obtain salt character from local ID string with character position of local ID index
// 5. Insert salt character to encrypted message to the position index (index is calculated using this formula (((encrypted message length + random number) * random number) % encrypted message length)))
//6. Add random number to the first index of the encrypted message with salt
//END DV note
NSString *localID = message.localID;
NSString *substringLocalID = [localID substringWithRange:NSMakeRange(8, 16)];
NSMutableString *reversedSubstringLocalID = [NSMutableString string];
NSInteger charIndex = [substringLocalID length];
while (charIndex > 0) {
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedSubstringLocalID appendString:[substringLocalID substringWithRange:subStrRange]];
}
//password is generated based on 16 first characters of kKeyPasswordEncryptor + reversedSubstringLocalID
NSString *substringKeyPassword = [kKeyPasswordEncryptor substringWithRange:NSMakeRange(0, 16)];
NSString *password = [NSString stringWithFormat:@"%@%@", substringKeyPassword, reversedSubstringLocalID];
NSInteger messageLength = [message.body length];
NSInteger localIDLength = [localID length];
NSInteger localIDIndex = messageLength % localIDLength;
NSString *saltString = [localID substringWithRange:NSMakeRange(localIDIndex, 1)];
NSString *encryptedMessage = [AESCrypt encrypt:message.body password:password];
NSInteger randomNumber = 1 + (arc4random() % 9); //Random number from 1 - 9
NSInteger encryptedMessageLength = [encryptedMessage length];
NSInteger saltCharIndexPosition = (((encryptedMessageLength + randomNumber) * randomNumber) % encryptedMessageLength);
NSMutableString *encryptedMessageWithSalt = [NSMutableString stringWithString:encryptedMessage];
[encryptedMessageWithSalt insertString:saltString atIndex:saltCharIndexPosition];
[encryptedMessageWithSalt insertString:[NSString stringWithFormat:@"%ld", (long)randomNumber] atIndex:0];
TAPMessageModel *messageForReturn = [[TAPMessageModel alloc] initWithDictionary:[message toDictionary] error:nil];
messageForReturn.body = encryptedMessageWithSalt;
return messageForReturn;
}
+ (TAPMessageModel *)decryptMessage:(TAPMessageModel *)message {
if (!message) {
return nil;
}
NSString *localID = message.localID;
NSString *substringLocalID = [localID substringWithRange:NSMakeRange(8, 16)];
NSMutableString *reversedSubstringLocalID = [NSMutableString string];
NSInteger charIndex = [substringLocalID length];
while (charIndex > 0) {
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedSubstringLocalID appendString:[substringLocalID substringWithRange:subStrRange]];
}
//password is generated based on 16 first characters of kKeyPasswordEncryptor + reversedSubstringLocalID
NSString *substringKeyPassword = [kKeyPasswordEncryptor substringWithRange:NSMakeRange(0, 16)];
NSString *password = [NSString stringWithFormat:@"%@%@", substringKeyPassword, reversedSubstringLocalID];
NSString *encryptedMessageWithSalt = message.body;
NSInteger encryptedMessageLength = [encryptedMessageWithSalt length] - 2; //-2 for removing random number and salt character
NSString *randomNumberString = [encryptedMessageWithSalt substringWithRange:NSMakeRange(0, 1)];
NSInteger randomNumber = [randomNumberString integerValue];
NSInteger saltCharIndexPosition = (((encryptedMessageLength + randomNumber) * randomNumber) % encryptedMessageLength);
NSString *encryptedMessage = [encryptedMessageWithSalt stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""];
encryptedMessage = [encryptedMessage stringByReplacingCharactersInRange:NSMakeRange(saltCharIndexPosition, 1) withString:@""];
NSString *decryptedMessage = [AESCrypt decrypt:encryptedMessage password:password];
TAPMessageModel *messageForReturn = [[TAPMessageModel alloc] initWithDictionary:[message toDictionary] error:nil];
messageForReturn.body = decryptedMessage;
return messageForReturn;
}
@end