· 7 years ago · Jul 02, 2018, 02:24 AM
1@implementation CryptoHelper
2
3#pragma mark -
4#pragma mark Init Methods
5- (id)init
6{
7 if(self = [super init])
8 {
9
10 }
11 return self;
12}
13
14#pragma mark -
15#pragma mark String Specific Methods
16
17/**
18 * Encrypts a string for social blast service.
19 *
20 * @param plainString The string to encrypt;
21 *
22 * @return NSString The encrypted string.
23 */
24- (NSString *)encryptString: (NSString *) plainString{
25
26 // Convert string to data and encrypt
27 NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];
28
29
30
31 // Get encrypted string from data
32 return [data base64EncodingWithLineLength:1024];
33
34}
35
36
37/**
38 * Descrypts a string from social blast service.
39 *
40 * @param plainString The string to decrypt;
41 *
42 * @return NSString The decrypted string.
43 */
44- (NSString *)decryptString: (NSString *) encryptedString{
45
46 // decrypt the data
47 NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];
48
49 // extract and return string
50 return [NSString stringWithUTF8String:[data bytes]];
51
52}
53
54
55#pragma mark -
56#pragma mark Crypto Methods
57
58- (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
59 return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
60}
61
62- (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
63 return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
64}
65
66- (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
67{
68 NSLog(@"helper data = %@", inData);
69
70 static const char gSalt[] =
71 {
72 (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
73 (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA
74 };
75
76 unsigned char *salt = (unsigned char *)gSalt;
77 int saltLen = strlen(gSalt);
78 int iterations = 15;
79
80 EVP_CIPHER_CTX cipherCtx;
81
82
83 unsigned char *mResults; // allocated storage of results
84 int mResultsLen = 0;
85
86 const char *cPassword = [password UTF8String];
87
88 unsigned char *mData = (unsigned char *)[inData bytes];
89 int mDataLen = [inData length];
90
91
92 SSLeay_add_all_algorithms();
93 /*X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
94 iterations, salt, saltLen);*/
95 const EVP_CIPHER *cipher = EVP_des_cbc();
96
97 // Need to set with iv
98 X509_ALGOR *algorithm = PKCS5_pbe2_set_iv(cipher, iterations,
99 salt, saltLen, salt, NID_hmacWithMD5);
100
101
102 memset(&cipherCtx, 0, sizeof(cipherCtx));
103
104 if (algorithm != NULL)
105 {
106 EVP_CIPHER_CTX_init(&(cipherCtx));
107
108
109
110 if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword),
111 algorithm->parameter, &(cipherCtx), direction))
112 {
113
114 EVP_CIPHER_CTX_set_padding(&cipherCtx, 1);
115
116 int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx);
117 int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt
118 mResults = (unsigned char *)OPENSSL_malloc(allocLen);
119
120
121 unsigned char *in_bytes = mData;
122 int inLen = mDataLen;
123 unsigned char *out_bytes = mResults;
124 int outLen = 0;
125
126
127
128 int outLenPart1 = 0;
129 if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen))
130 {
131 out_bytes += outLenPart1;
132 int outLenPart2 = 0;
133 if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2))
134 {
135 outLen += outLenPart1 + outLenPart2;
136 mResults[outLen] = 0;
137 mResultsLen = outLen;
138 }
139 } else {
140 unsigned long err = ERR_get_error();
141
142 ERR_load_crypto_strings();
143 ERR_load_ERR_strings();
144 char errbuff[256];
145 errbuff[0] = 0;
146 ERR_error_string_n(err, errbuff, sizeof(errbuff));
147 NSLog(@"OpenSLL ERROR:ntlib:%sntfunction:%sntreason:%sn",
148 ERR_lib_error_string(err),
149 ERR_func_error_string(err),
150 ERR_reason_error_string(err));
151 ERR_free_strings();
152 }
153
154
155 NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; //(NSData *)encr_buf;
156
157
158 //NSLog(@"encryption result: %@n", [encryptedData base64EncodingWithLineLength:1024]);
159
160 EVP_cleanup();
161
162 return encryptedData;
163 }
164 }
165 EVP_cleanup();
166 return nil;
167
168}
169
170@end
171
172public DesEncrypter(String passPhrase) {
173 try {
174 // Create the key
175 KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
176 SecretKey key = SecretKeyFactory.getInstance(
177 "PBEWithMD5AndDES").generateSecret(keySpec);
178 ecipher = Cipher.getInstance(key.getAlgorithm());
179 dcipher = Cipher.getInstance(key.getAlgorithm());
180
181 // Prepare the parameter to the ciphers
182 AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
183
184 // Create the ciphers
185 ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
186 dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
187 } catch (java.security.InvalidAlgorithmParameterException e) {
188 } catch (java.security.spec.InvalidKeySpecException e) {
189 } catch (javax.crypto.NoSuchPaddingException e) {
190 } catch (java.security.NoSuchAlgorithmException e) {
191 } catch (java.security.InvalidKeyException e) {
192 }
193}
194
195#include <CommonCrypto/CommonDigest.h>
196#include <CommonCrypto/CommonCryptor.h>
197
198
199+(NSData*) cryptPBEWithMD5AndDES:(CCOperation)op usingData:(NSData*)data withPassword:(NSString*)password andSalt:(NSData*)salt andIterating:(int)numIterations {
200 unsigned char md5[CC_MD5_DIGEST_LENGTH];
201 memset(md5, 0, CC_MD5_DIGEST_LENGTH);
202 NSData* passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
203
204 CC_MD5_CTX ctx;
205 CC_MD5_Init(&ctx);
206 CC_MD5_Update(&ctx, [passwordData bytes], [passwordData length]);
207 CC_MD5_Update(&ctx, [salt bytes], [salt length]);
208 CC_MD5_Final(md5, &ctx);
209
210 for (int i=1; i<numIterations; i++) {
211 CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
212 }
213
214 size_t cryptoResultDataBufferSize = [data length] + kCCBlockSizeDES;
215 unsigned char cryptoResultDataBuffer[cryptoResultDataBufferSize];
216 size_t dataMoved = 0;
217
218 unsigned char iv[kCCBlockSizeDES];
219 memcpy(iv, md5 + (CC_MD5_DIGEST_LENGTH/2), sizeof(iv)); //iv is the second half of the MD5 from building the key
220
221 CCCryptorStatus status =
222 CCCrypt(op, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, (CC_MD5_DIGEST_LENGTH/2), iv, [data bytes], [data length],
223 cryptoResultDataBuffer, cryptoResultDataBufferSize, &dataMoved);
224
225 if(0 == status) {
226 return [NSData dataWithBytes:cryptoResultDataBuffer length:dataMoved];
227 } else {
228 return NULL;
229 }
230}
231
232@interface NSData (PBEEncryption)
233
234/**
235 * Decrypt the receiver using PKCS#5 PBE with MD5 and DES assuming that the salt is prefixed into the first 8 bytes of
236 * the data and the number of key obtention iterations is 1000. This is compatible with Java's PBEWithMD5AndDES
237 * encryption when the encryption generates a random salt for the data (the default when providing no salt).
238 */
239- (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password;
240
241/**
242 * Decrypt the receiver using PKCS#5 PBE with MD5 and DES. Explicitly provide the salt and number of key obtention
243 * iterations.
244 */
245- (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations;
246
247@end
248
249
250@implementation NSData (PBEEncryption)
251
252- (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password {
253 NSData *salt = nil;
254 NSData *input = self;
255 if ([input length] > 8) {
256 salt = [input subdataWithRange:NSMakeRange(0, 8)];
257 input = [input subdataWithRange:NSMakeRange(8, [input length] - 8)];
258 }
259 return [input decrytpPBEWithMD5AndDESUsingPassword:password salt:salt iterations:1000];
260}
261
262- (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations {
263 unsigned char md5[CC_MD5_DIGEST_LENGTH] = {};
264
265 CC_MD5_CTX ctx;
266 CC_MD5_Init(&ctx);
267 CC_MD5_Update(&ctx, [password bytes], [password length]);
268 CC_MD5_Update(&ctx, [salt bytes], [salt length]);
269 CC_MD5_Final(md5, &ctx);
270
271 for (NSUInteger i = 1; i < iterations; i++) {
272 CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
273 }
274
275 // initialization vector is the second half of the MD5 from building the key
276 unsigned char iv[kCCBlockSizeDES];
277 assert(kCCBlockSizeDES == CC_MD5_DIGEST_LENGTH / 2);
278 memcpy(iv, md5 + kCCBlockSizeDES, sizeof(iv));
279
280 NSMutableData *output = [NSMutableData dataWithLength:([self length] + kCCBlockSize3DES)];
281 size_t outputLength = 0;
282 CCCryptorStatus status =
283 CCCrypt(kCCDecrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, kCCBlockSizeDES, iv,
284 [self bytes], [self length], [output mutableBytes], [output length], &outputLength);
285
286 if (status == kCCSuccess) { [output setLength:outputLength]; }
287 else { output = nil; }
288
289 return output;
290}
291
292@end
293
294NSString *password = @"myTopSecretPassword";
295NSData *inputData = [NSData dataFromBase64String:@"base64string"];
296NSData *outputData = [inputData decrytpPBEWithMD5AndDESUsingPassword:
297 [password dataUsingEncoding:NSUTF8StringEncoding]];
298
299@implementation CryptoHelper
300
301#pragma mark -
302#pragma mark Init Methods
303- (id)init
304{
305 if(self = [super init])
306 {
307
308 }
309 return self;
310}
311
312#pragma mark -
313#pragma mark String Specific Methods
314
315/**
316 * Encrypts a string for social blast service.
317 *
318 * @param plainString The string to encrypt;
319 *
320 * @return NSString The encrypted string.
321 */
322- (NSString *)encryptString: (NSString *) plainString{
323
324 // Convert string to data and encrypt
325 NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];
326
327
328
329 // Get encrypted string from data
330 return [data base64EncodingWithLineLength:1024];
331
332}
333
334
335/**
336 * Descrypts a string from social blast service.
337 *
338 * @param plainString The string to decrypt;
339 *
340 * @return NSString The decrypted string.
341 */
342- (NSString *)decryptString: (NSString *) encryptedString{
343
344 // decrypt the data
345 NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];
346
347 // extract and return string
348 return [NSString stringWithUTF8String:[data bytes]];
349
350}
351
352
353#pragma mark -
354#pragma mark Crypto Methods
355
356- (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
357 return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
358}
359
360- (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
361 return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
362}
363
364- (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
365{
366 NSLog(@"helper data = %@", inData);
367
368 static const char gSalt[] =
369 {
370 (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
371 (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
372 (unsigned char)0x00
373 };
374
375 unsigned char *salt = (unsigned char *)gSalt;
376 int saltLen = strlen(gSalt);
377 int iterations = 15;
378
379 EVP_CIPHER_CTX cipherCtx;
380
381
382 unsigned char *mResults; // allocated storage of results
383 int mResultsLen = 0;
384
385 const char *cPassword = [password UTF8String];
386
387 unsigned char *mData = (unsigned char *)[inData bytes];
388 int mDataLen = [inData length];
389
390
391 SSLeay_add_all_algorithms();
392 X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
393 iterations, salt, saltLen);
394
395
396
397 memset(&cipherCtx, 0, sizeof(cipherCtx));
398
399 if (algorithm != NULL)
400 {
401 EVP_CIPHER_CTX_init(&(cipherCtx));
402
403
404
405 if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword),
406 algorithm->parameter, &(cipherCtx), direction))
407 {
408
409 EVP_CIPHER_CTX_set_padding(&cipherCtx, 1);
410
411 int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx);
412 int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt
413 mResults = (unsigned char *)OPENSSL_malloc(allocLen);
414
415
416 unsigned char *in_bytes = mData;
417 int inLen = mDataLen;
418 unsigned char *out_bytes = mResults;
419 int outLen = 0;
420
421
422
423 int outLenPart1 = 0;
424 if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen))
425 {
426 out_bytes += outLenPart1;
427 int outLenPart2 = 0;
428 if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2))
429 {
430 outLen += outLenPart1 + outLenPart2;
431 mResults[outLen] = 0;
432 mResultsLen = outLen;
433 }
434 } else {
435 unsigned long err = ERR_get_error();
436
437 ERR_load_crypto_strings();
438 ERR_load_ERR_strings();
439 char errbuff[256];
440 errbuff[0] = 0;
441 ERR_error_string_n(err, errbuff, sizeof(errbuff));
442 NSLog(@"OpenSLL ERROR:ntlib:%sntfunction:%sntreason:%sn",
443 ERR_lib_error_string(err),
444 ERR_func_error_string(err),
445 ERR_reason_error_string(err));
446 ERR_free_strings();
447 }
448
449
450 NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; //(NSData *)encr_buf;
451
452
453 //NSLog(@"encryption result: %@n", [encryptedData base64EncodingWithLineLength:1024]);
454
455 EVP_cleanup();
456
457 return encryptedData;
458 }
459 }
460 EVP_cleanup();
461 return nil;
462
463}
464
465@end
466
467@implementation NSData (PBEEncryption)
468
469- (NSData *)encryptPBEWithMD5AndDESUsingPassword:(NSData *)password {
470 unsigned char gSalt[] =
471 {
472 (unsigned char)0x18, (unsigned char)0x79, (unsigned char)0x6D, (unsigned char)0x6D,
473 (unsigned char)0x35, (unsigned char)0x3A, (unsigned char)0x6A, (unsigned char)0x60,
474 (unsigned char)0x00
475 };
476
477 NSData *salt = nil;
478 salt = [NSData dataWithBytes:gSalt length:strlen(gSalt)];
479
480 NSData* encrypted = [self encryptPBEWithMD5AndDESUsingPassword:password salt:salt iterations:1000];
481 NSMutableData* result = [NSMutableData dataWithData:salt];
482 [result appendData:encrypted];
483 return [NSData dataWithData:result];
484
485}
486
487- (NSData *)encryptPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations {
488 unsigned char md5[CC_MD5_DIGEST_LENGTH] = {};
489
490 CC_MD5_CTX ctx;
491 CC_MD5_Init(&ctx);
492 CC_MD5_Update(&ctx, [password bytes], [password length]);
493 CC_MD5_Update(&ctx, [salt bytes], [salt length]);
494 CC_MD5_Final(md5, &ctx);
495
496 for (NSUInteger i = 1; i < iterations; i++) {
497 CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
498 }
499
500 // initialization vector is the second half of the MD5 from building the key
501 unsigned char iv[kCCBlockSizeDES];
502 assert(kCCBlockSizeDES == CC_MD5_DIGEST_LENGTH / 2);
503 memcpy(iv, md5 + kCCBlockSizeDES, sizeof(iv));
504
505 NSMutableData *output = [NSMutableData dataWithLength:([self length] + kCCBlockSize3DES)];
506 size_t outputLength = 0;
507 CCCryptorStatus status =
508 CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, kCCBlockSizeDES, iv,
509 [self bytes], [self length], [output mutableBytes], [output length], &outputLength);
510
511 if (status == kCCSuccess) { [output setLength:outputLength]; }
512 else { output = nil; }
513
514 return output;
515}
516
517
518@end
519
520static func encryptForOverTheWire(string: String) -> String {
521 let stringData = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
522 let passwordData = PASSWORD.dataUsingEncoding(NSUTF8StringEncoding)
523 let encryptedData = stringData?.encryptPBEWithMD5AndDESUsingPassword(passwordData)
524 let base64 = encryptedData?.base64EncodedDataWithOptions(NSDataBase64EncodingOptions())
525
526 guard base64 != nil else { return "" }
527
528 let result = String(data: base64!, encoding: NSUTF8StringEncoding)
529 return result ?? ""
530}
531
532static func encrypt(inString: String) -> String? {
533
534 let passwordStr = "blablalba"
535 let iterations:Int32 = 19
536 let salt = [0x44, 0x44, 0x22, 0x22, 0x56, 0x35, 0xE3, 0x03] as [UInt8]
537 let operation: CCOperation = UInt32(kCCEncrypt)
538 let saltData = NSData(bytes: salt, length: salt.count)
539
540 let out = CryptoHelper.cryptPBE(withMD5AndDES: operation, using: inString.data(using: .utf8), withPassword: passwordStr, andSalt: saltData as Data, andIterating: iterations) as Data
541
542 let outString = String.init(data: out, encoding: .utf8)
543
544 return outString
545}