· 8 years ago · Jan 08, 2018, 03:58 AM
1enum CryptoAlgorithm {
2 case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
3
4 var HMACAlgorithm: CCHmacAlgorithm {
5 var result: Int = 0
6 switch self {
7 case .MD5: result = kCCHmacAlgMD5
8 case .SHA1: result = kCCHmacAlgSHA1
9 case .SHA224: result = kCCHmacAlgSHA224
10 case .SHA256: result = kCCHmacAlgSHA256
11 case .SHA384: result = kCCHmacAlgSHA384
12 case .SHA512: result = kCCHmacAlgSHA512
13 }
14 return CCHmacAlgorithm(result)
15 }
16
17 var digestLength: Int {
18 var result: Int32 = 0
19 switch self {
20 case .MD5: result = CC_MD5_DIGEST_LENGTH
21 case .SHA1: result = CC_SHA1_DIGEST_LENGTH
22 case .SHA224: result = CC_SHA224_DIGEST_LENGTH
23 case .SHA256: result = CC_SHA256_DIGEST_LENGTH
24 case .SHA384: result = CC_SHA384_DIGEST_LENGTH
25 case .SHA512: result = CC_SHA512_DIGEST_LENGTH
26 }
27 return Int(result)
28 }
29}
30
31extension String {
32
33 func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
34 let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
35 let strLen = Int(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
36 let digestLen = algorithm.digestLength
37 let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
38 let keyStr = key.cStringUsingEncoding(NSUTF8StringEncoding)
39 let keyLen = Int(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
40
41 CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
42
43 let digest = stringFromResult(result, length: digestLen)
44
45 result.dealloc(digestLen)
46
47 return digest
48 }
49
50 private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
51 var hash = NSMutableString()
52 for i in 0..<length {
53 hash.appendFormat("%02x", result[i])
54 }
55 return String(hash)
56 }
57
58}
59
60enum CryptoAlgorithm {
61 case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
62
63 var HMACAlgorithm: CCHmacAlgorithm {
64 var result: Int = 0
65 switch self {
66 case .MD5: result = kCCHmacAlgMD5
67 case .SHA1: result = kCCHmacAlgSHA1
68 case .SHA224: result = kCCHmacAlgSHA224
69 case .SHA256: result = kCCHmacAlgSHA256
70 case .SHA384: result = kCCHmacAlgSHA384
71 case .SHA512: result = kCCHmacAlgSHA512
72 }
73 return CCHmacAlgorithm(result)
74 }
75
76 var digestLength: Int {
77 var result: Int32 = 0
78 switch self {
79 case .MD5: result = CC_MD5_DIGEST_LENGTH
80 case .SHA1: result = CC_SHA1_DIGEST_LENGTH
81 case .SHA224: result = CC_SHA224_DIGEST_LENGTH
82 case .SHA256: result = CC_SHA256_DIGEST_LENGTH
83 case .SHA384: result = CC_SHA384_DIGEST_LENGTH
84 case .SHA512: result = CC_SHA512_DIGEST_LENGTH
85 }
86 return Int(result)
87 }
88}
89
90extension String {
91
92 func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
93 let str = self.cString(using: String.Encoding.utf8)
94 let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
95 let digestLen = algorithm.digestLength
96 let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
97 let keyStr = key.cString(using: String.Encoding.utf8)
98 let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
99
100 CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
101
102 let digest = stringFromResult(result: result, length: digestLen)
103
104 result.deallocate(capacity: digestLen)
105
106 return digest
107 }
108
109 private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
110 let hash = NSMutableString()
111 for i in 0..<length {
112 hash.appendFormat("%02x", result[i])
113 }
114 return String(hash)
115 }
116
117}
118
119// This enum is in HMAC.h
120typedef NS_ENUM(NSInteger, HMACAlgorithm)
121{
122 SHA1,
123 MD5,
124 SHA256,
125 SHA384,
126 SHA512,
127 SHA224
128};
129
130// Class methods here
131+ (NSData *)calculateWithAlgorithm:(HMACAlgorithm)algorithm forKey:(const void *)key andData:(const void *)data
132{
133 NSInteger digestLength = [self digestLengthForAlgorithm:algorithm];
134 unsigned char hmac[digestLength];
135
136 CCHmac(algorithm, &key, strlen(key), &data, strlen(data), &hmac);
137
138 NSData *hmacBytes = [NSData dataWithBytes:hmac length:sizeof(hmac)];
139 return hmacBytes;
140}
141
142+ (NSInteger)digestLengthForAlgorithm:(HMACAlgorithm)algorithm
143{
144 switch (algorithm)
145 {
146 case MD5: return CC_MD5_DIGEST_LENGTH;
147 case SHA1: return CC_SHA1_DIGEST_LENGTH;
148 case SHA224: return CC_SHA224_DIGEST_LENGTH;
149 case SHA256: return CC_SHA256_DIGEST_LENGTH;
150 case SHA384: return CC_SHA384_DIGEST_LENGTH;
151 case SHA512: return CC_SHA512_DIGEST_LENGTH;
152 default: return 0;
153 }
154}
155
156class SwiftHMAC
157{
158 // Swift will automatically pull the enum from Obj-C
159
160 func calculate(algorithm:HMACAlgorithm, key:Byte[], data:Byte[]) -> Byte[]
161 {
162 let computedHMAC = HMAC.calculateWithAlgorithm(algorithm, forKey: key, andData: data)
163
164 var rawBytes = Byte[](count: computedHMAC.length, repeatedValue: 0)
165 computedHMAC.getBytes(&rawBytes)
166
167 return rawBytes
168 }
169}
170
171#import <CommonCrypto/CommonHMAC.h>
172
173private func hmac(string: NSString, key: NSData) -> NSData {
174 let keyBytes = UnsafePointer<CUnsignedChar>(key.bytes)
175 let data = string.cStringUsingEncoding(NSUTF8StringEncoding)
176 let dataLen = Int(string.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
177 let digestLen = Int(CC_SHA1_DIGEST_LENGTH)
178 let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
179 CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), keyBytes, key.length, data, dataLen, result);
180 return NSData(bytes: result, length: digestLen)
181}
182
183let strLen = UInt(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
184let keyLen = UInt(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
185
186let strLen = self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
187let keyLen = key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
188
189//
190// HMAC.swift
191//
192// Created by Mihael Isaev on 21.04.15.
193// Copyright (c) 2014 Mihael Isaev inc. All rights reserved.
194//
195// ***********************************************************
196//
197// How to import CommonCrypto in Swift project without Obj-c briging header
198//
199// To work around this create a directory called CommonCrypto in the root of the project using Finder.
200// In this directory create a file name module.map and copy the following into the file.
201// You will need to alter the paths to ensure they point to the headers on your system.
202//
203// module CommonCrypto [system] {
204// header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
205// export *
206// }
207// To make this module visible to Xcode, go to Build Settings, Swift Compiler – Search Paths
208// and set Import Paths to point to the directory that contains the CommonCrypto directory.
209//
210// You should now be able to use import CommonCrypto in your Swift code.
211//
212// You have to set the Import Paths in every project that uses your framework so that Xcode can find it.
213//
214// ***********************************************************
215//
216// Modification for Swift 3.0 by Sanjay Sampat on 04.Jan.2017
217//
218// ***********************************************************
219
220import Foundation
221import CommonCrypto
222
223extension String {
224 var md5: String {
225 return HMAC.hash(inp: self, algo: HMACAlgo.MD5)
226}
227
228var sha1: String {
229 return HMAC.hash(inp: self, algo: HMACAlgo.SHA1)
230}
231
232var sha224: String {
233 return HMAC.hash(inp: self, algo: HMACAlgo.SHA224)
234}
235
236var sha256: String {
237 return HMAC.hash(inp: self, algo: HMACAlgo.SHA256)
238}
239
240var sha384: String {
241 return HMAC.hash(inp: self, algo: HMACAlgo.SHA384)
242}
243
244var sha512: String {
245 return HMAC.hash(inp: self, algo: HMACAlgo.SHA512)
246}
247
248func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
249 if let keyData = key.data(using: String.Encoding.utf8),
250 let data = self.data(using: String.Encoding.utf8),
251 let cryptData = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {
252
253
254 let keyLength = size_t(kCCKeySizeAES128)
255 let operation: CCOperation = UInt32(kCCEncrypt)
256 let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
257 let options: CCOptions = UInt32(options)
258
259
260
261 var numBytesEncrypted :size_t = 0
262
263 let base64cryptStringOut = keyData.withUnsafeBytes {(keyBytes: UnsafePointer<CChar>)->String? in
264 return data.withUnsafeBytes {(dataBytes: UnsafePointer<CChar>)->String? in
265
266 let cryptStatus = CCCrypt(operation,
267 algoritm,
268 options,
269 keyBytes, keyLength,
270 iv,
271 dataBytes, data.count,
272 cryptData.mutableBytes, cryptData.length,
273 &numBytesEncrypted)
274
275 if UInt32(cryptStatus) == UInt32(kCCSuccess) {
276 cryptData.length = Int(numBytesEncrypted)
277 let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
278 return base64cryptString
279
280
281 }
282 else {
283 return nil
284 }
285 }
286 }
287 return base64cryptStringOut
288 }
289 return nil
290}
291
292func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
293 if let keyData = key.data(using: String.Encoding.utf8),
294 let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
295 let cryptData = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {
296
297 let keyLength = size_t(kCCKeySizeAES128)
298 let operation: CCOperation = UInt32(kCCDecrypt)
299 let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
300 let options: CCOptions = UInt32(options)
301
302 var numBytesEncrypted :size_t = 0
303
304 let unencryptedMessageOut = keyData.withUnsafeBytes {(keyBytes: UnsafePointer<CChar>)->String? in
305 let cryptStatus = CCCrypt(operation,
306 algoritm,
307 options,
308 keyBytes, keyLength,
309 iv,
310 data.bytes, data.length,
311 cryptData.mutableBytes, cryptData.length,
312 &numBytesEncrypted)
313
314 if UInt32(cryptStatus) == UInt32(kCCSuccess) {
315 cryptData.length = Int(numBytesEncrypted)
316 let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
317 return unencryptedMessage
318 }
319 else {
320 return nil
321 }
322 }
323 return unencryptedMessageOut
324 }
325 return nil
326}
327}
328
329public struct HMAC {
330
331static func hash(inp: String, algo: HMACAlgo) -> String {
332 if let stringData = inp.data(using: String.Encoding.utf8, allowLossyConversion: false) {
333 return hexStringFromData(input: digest(input: stringData as NSData, algo: algo))
334 }
335 return ""
336}
337
338private static func digest(input : NSData, algo: HMACAlgo) -> NSData {
339 let digestLength = algo.digestLength()
340 var hash = [UInt8](repeating: 0, count: digestLength)
341 switch algo {
342 case .MD5:
343 CC_MD5(input.bytes, UInt32(input.length), &hash)
344 break
345 case .SHA1:
346 CC_SHA1(input.bytes, UInt32(input.length), &hash)
347 break
348 case .SHA224:
349 CC_SHA224(input.bytes, UInt32(input.length), &hash)
350 break
351 case .SHA256:
352 CC_SHA256(input.bytes, UInt32(input.length), &hash)
353 break
354 case .SHA384:
355 CC_SHA384(input.bytes, UInt32(input.length), &hash)
356 break
357 case .SHA512:
358 CC_SHA512(input.bytes, UInt32(input.length), &hash)
359 break
360 }
361 return NSData(bytes: hash, length: digestLength)
362}
363
364private static func hexStringFromData(input: NSData) -> String {
365 var bytes = [UInt8](repeating: 0, count: input.length)
366 input.getBytes(&bytes, length: input.length)
367
368 var hexString = ""
369 for byte in bytes {
370 hexString += String(format:"%02x", UInt8(byte))
371 }
372
373 return hexString
374}
375
376}
377
378enum HMACAlgo {
379case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
380
381func digestLength() -> Int {
382 var result: CInt = 0
383 switch self {
384 case .MD5:
385 result = CC_MD5_DIGEST_LENGTH
386 case .SHA1:
387 result = CC_SHA1_DIGEST_LENGTH
388 case .SHA224:
389 result = CC_SHA224_DIGEST_LENGTH
390 case .SHA256:
391 result = CC_SHA256_DIGEST_LENGTH
392 case .SHA384:
393 result = CC_SHA384_DIGEST_LENGTH
394 case .SHA512:
395 result = CC_SHA512_DIGEST_LENGTH
396 }
397 return Int(result)
398}
399}
400
401// TEST for Encryption and Decryption through HMAC Swift 3.0
402 let iv = "iv-salt-Sanjay--" // fixed 16 chars.
403 let cryptoKeyString = "01234567890123456789012345678901"
404 let originalString = "My Name is Sanjay Sampat, Password is IL0ve2view2Kill@4#"
405 print("Original String: (originalString)")
406 if let encodedString = originalString.aesEncrypt(key: cryptoKeyString, iv: iv){
407 print("String Encoded: (encodedString)")
408 if let decryptedString = encodedString.aesDecrypt(key: cryptoKeyString, iv: iv)
409 {
410 print("String Decoded: (decryptedString)")
411 }
412 else{
413 print("Decoding failed")
414 }
415 }
416 else{
417 print("Encoding failed")
418 }
419
420
421 // Example To create sha1 from string
422 let testString = "This is string to test sha1 hash string."
423 let sha1Digest = testString.sha1
424 print("sha1-hash-string: (sha1Digest)")
425
426import Foundation
427import Security
428
429var error: Unmanaged<CFError>?
430let transform = SecDigestTransformCreate(kSecDigestHMACSHA1, 0, &error)
431let input = "Hi There"
432let inputData = input.dataUsingEncoding(NSUTF8StringEncoding)!
433let key = [UInt8](count: 20, repeatedValue: 0x0b)
434let keyData = key.withUnsafeBufferPointer { buffer in NSData(bytes: buffer.baseAddress, length: buffer.count) }
435SecTransformSetAttribute(transform, kSecTransformInputAttributeName, inputData, &error)
436SecTransformSetAttribute(transform, kSecDigestHMACKeyAttribute, keyData, &error)
437let outputData = SecTransformExecute(transform, &error) as! NSData
438
439enum CryptoAlgorithm {
440case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
441
442 var HMACAlgorithm: CCHmacAlgorithm {
443 var result: Int = 0
444 switch self {
445 case .MD5: result = kCCHmacAlgMD5
446 case .SHA1: result = kCCHmacAlgSHA1
447 case .SHA224: result = kCCHmacAlgSHA224
448 case .SHA256: result = kCCHmacAlgSHA256
449 case .SHA384: result = kCCHmacAlgSHA384
450 case .SHA512: result = kCCHmacAlgSHA512
451 }
452 return CCHmacAlgorithm(result)
453 }
454
455 var digestLength: Int {
456 var result: Int32 = 0
457 switch self {
458 case .MD5: result = CC_MD5_DIGEST_LENGTH
459 case .SHA1: result = CC_SHA1_DIGEST_LENGTH
460 case .SHA224: result = CC_SHA224_DIGEST_LENGTH
461 case .SHA256: result = CC_SHA256_DIGEST_LENGTH
462 case .SHA384: result = CC_SHA384_DIGEST_LENGTH
463 case .SHA512: result = CC_SHA512_DIGEST_LENGTH
464 }
465 return Int(result)
466 }
467}
468
469extension String {
470
471func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
472 let str = self.cString(using: String.Encoding.utf8)
473 let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
474 let digestLen = algorithm.digestLength
475 let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
476 let keyStr = key.cString(using: String.Encoding.utf8)
477 let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
478
479 CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
480
481 let digest = stringFromResult(result: result, length: digestLen)
482
483 result.deallocate(capacity: digestLen)
484
485 return digest
486}
487
488private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
489 let hash = NSMutableString()
490 for i in 0..<length {
491 hash.appendFormat("%02x", result[i])
492 }
493 return String(hash)
494}
495
496func sha256(StringToSign : String, secretKey : String) -> String{
497
498 let hex = StringToSign.hmac(algorithm: .SHA256, key: secretKey)
499 let hexData = hex.data(using: String.Encoding.utf8)
500 let finalString = hexData?.base64EncodedString(options: [.lineLength64Characters])
501
502 return finalString!
503
504}