2016-10-25 1 views
0
do { 
let JSONObject:[String:String] = 
[ 
"username" : "username", 
"password" : "Password", 
"domain": "domain" 
] 
let my64data:NSData = NSData(base64EncodedString:Credentials.SecretKey, options: NSDataBase64DecodingOptions(rawValue: UInt(0)))! 

let jsonData = try NSJSONSerialization.dataWithJSONObject(JSONObject, options: NSJSONWritingOptions.PrettyPrinted) 

let myString = String(data: jsonData, encoding: NSUTF8StringEncoding) 

    // let jsonString = AES1.encrypt(myString!, secretKey: Credentials.SecretKey, options:["iv":my64data]) 
    // print(" My Encrypted Json = \(jsonString)") 
    //    
    // let Decrypt = AES1.decrypt(jsonString, secretKey: Credentials.SecretKey, options: ["iv":my64data]) 
    //print(" My Decrypted Json = \(Decrypt)") 

let iv: Array<UInt8> = AES.randomIV(128/8) 
let salt: Array<UInt8> = AES.randomIV(128/8) 

let value = try! PKCS5.PBKDF2(password: Credentials.SecretKey.utf8.map({$0}), salt: salt, iterations: 1000, variant: .sha256).calculate() 
       value.toHexString() 

       _ = CryptoJS.mode.ECB() 
       _ = CryptoJS.pad.Iso97971() 
       _ = CryptoJS.pad.AnsiX923() 
       _ = CryptoJS.pad.Iso10126() 
       _ = CryptoJS.pad.ZeroPadding() 

       let encrypted : Array<UInt8> 

        encrypted = try AES(key: value, iv: iv, blockMode: .CBC, padding: PKCS7()).encrypt((myString?.utf8.map({$0}))!) 
        let decrypted = try AES(key: value, iv: iv, blockMode: .CBC, padding: PKCS7()).decrypt(encrypted) 

    //   let jsonString = AES1.encrypt(myString!, secretKey: String(value), options:["iv":iv.toHexString(),"mode":CryptoJS.mode().ECB,"padding":CryptoJS.pad().ZeroPadding]) 
       print(" My Encrypted Json = \(encrypted.toHexString())") 
    //    
    //   let pkcs = PKCS7() 
    //    
    //   let Decrypt = AES1.decrypt(jsonString, secretKey: String(value), options: ["iv":iv.toHexString(),"mode":CryptoJS.mode().ECB,"padding":pkcs]) 
       print(" My Decrypted Json = \(decrypted.toHexString())") 

       let myInputIV : String = String(iv.toHexString()) 
       let myInputSalt :String = String(salt.toHexString()) 

       let finalJSONObject:[String:String] = [ 

        "ciphertext" : "\(encrypted.toHexString())", 
        "iv" : "\(myInputIV)", 
        "salt": "\(myInputSalt)" 

       ] 

    print("Final Json Object = \(finalJSONObject)") 

       let requestURL: NSURL = NSURL(string:"<myURL>")! 
       print(requestURL) 
       let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL) 
       urlRequest.HTTPMethod = "POST" 
       urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") 
       urlRequest.HTTPBody = try!NSJSONSerialization.dataWithJSONObject(finalJSONObject, options:.PrettyPrinted) 

       let session = NSURLSession.sharedSession() 
       let task = session.dataTaskWithRequest(urlRequest, completionHandler:{ 
        data, response, error -> Void in 

        // Asynchronously call... 
        if (data != nil) { 

         print("Dataaa = \(data!)") 

         self.loginServiceResponse(data!) 

        }else{ 

         Singleton.SharedInstance.myAlert(alertTitle:Constants.SERVER_ERROR_TITLE, alertMessage: Constants.SERVER_ERROR_MESSAGE, alertButtonTitle:Constants.OK) 
         self.activityIndicator.stopAnimating() 

        } 


       }) 

       task.resume() 

      } catch { 
       print(error) 

      } 

Я получил эту ошибку:CryptoSwift + CryptoJS делает неправильный JSON в Swift 2.3

Error with Json Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}

+0

В почтальоне у меня есть ошибка заполнения – iPhone25

+0

Лучше всего избегать использования CryptoSwift, кроме других вещей, это от 500 до 1000 раз медленнее, чем на основе Common Crypto. Common Crypto от Apple является сертифицированным FIPS и, как таковой, был хорошо проверен, использование CryptoSwift дает шанс на правильность и безопасность. – zaph

+0

Увеличьте код с помощью [mcve], включите входы и выходы функции шифрования wityh. Сначала получите простое шифрование для работы, затем добавьте JSON, а затем добавьте связи. Постройте постепенно по рабочему коду, подход «большой удар» трудно отлаживать. – zaph

ответ

0

использовать общие Crypto от Swift

  1. Добавить заголовок связующую
  2. Добавить #import <CommonCrypto/CommonCrypto.h> в заголовок.

В примере используется режим CBC и префикс зашифрованных данных с помощью IV, который является методом, обычно используемым для обработки IV.

Пример из устаревшего раздела документации:

шифрования AES в режиме CBC со случайным IV (Swift 3.0)

ХВ предваряются к зашифрованным данным

aesCBC128Encrypt создаст случайный IV и с префиксом шифрованного кода.
aesCBC128Decrypt будет использовать префикс IV во время дешифрования.

Входы - это данные и ключ - объекты данных. Если закодированная форма, такая как Base64, если требуется, конвертировать в и/или из вызывающего метода.

Ключ должен быть ровно 128-битным (16-байтным), 192-битным (24 байта) или 256-битным (32 байта) в длину. Если используется другой размер ключа, будет выдана ошибка.

PKCS#7 padding устанавливается по умолчанию.

Этот пример требует общего Crypto
Необходимо иметь мостовую заголовок проекта:
#import <CommonCrypto/CommonCrypto.h>
Добавить в Security.framework к проекту.

Это пример, а не производственный код. Использование

enum AESError: Error { 
    case KeyError((String, Int)) 
    case IVError((String, Int)) 
    case CryptorError((String, Int)) 
} 

// The iv is prefixed to the encrypted data 
func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data { 
    let keyLength = keyData.count 
    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256] 
    if (validKeyLengths.contains(keyLength) == false) { 
     throw AESError.KeyError(("Invalid key length", keyLength)) 
    } 

    let ivSize = kCCBlockSizeAES128; 
    let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128) 
    var cryptData = Data(count:cryptLength) 

    let status = cryptData.withUnsafeMutableBytes {ivBytes in 
     SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes) 
    } 
    if (status != 0) { 
     throw AESError.IVError(("IV generation failed", Int(status))) 
    } 

    var numBytesEncrypted :size_t = 0 
    let options = CCOptions(kCCOptionPKCS7Padding) 

    let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in 
     data.withUnsafeBytes {dataBytes in 
      keyData.withUnsafeBytes {keyBytes in 
       CCCrypt(CCOperation(kCCEncrypt), 
         CCAlgorithm(kCCAlgorithmAES), 
         options, 
         keyBytes, keyLength, 
         cryptBytes, 
         dataBytes, data.count, 
         cryptBytes+kCCBlockSizeAES128, cryptLength, 
         &numBytesEncrypted) 
      } 
     } 
    } 

    if UInt32(cryptStatus) == UInt32(kCCSuccess) { 
     cryptData.count = numBytesEncrypted + ivSize 
    } 
    else { 
     throw AESError.CryptorError(("Encryption failed", Int(cryptStatus))) 
    } 

    return cryptData; 
} 

// The iv is prefixed to the encrypted data 
func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? { 
    let keyLength = keyData.count 
    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256] 
    if (validKeyLengths.contains(keyLength) == false) { 
     throw AESError.KeyError(("Invalid key length", keyLength)) 
    } 

    let ivSize = kCCBlockSizeAES128; 
    let clearLength = size_t(data.count - ivSize) 
    var clearData = Data(count:clearLength) 

    var numBytesDecrypted :size_t = 0 
    let options = CCOptions(kCCOptionPKCS7Padding) 

    let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in 
     data.withUnsafeBytes {dataBytes in 
      keyData.withUnsafeBytes {keyBytes in 
       CCCrypt(CCOperation(kCCDecrypt), 
         CCAlgorithm(kCCAlgorithmAES128), 
         options, 
         keyBytes, keyLength, 
         dataBytes, 
         dataBytes+kCCBlockSizeAES128, clearLength, 
         cryptBytes, clearLength, 
         &numBytesDecrypted) 
      } 
     } 
    } 

    if UInt32(cryptStatus) == UInt32(kCCSuccess) { 
     clearData.count = numBytesDecrypted 
    } 
    else { 
     throw AESError.CryptorError(("Decryption failed", Int(cryptStatus))) 
    } 

    return clearData; 
} 

Пример:

let clearData = "clearData".data(using:String.Encoding.utf8)! 
let keyData = "keyData89".data(using:String.Encoding.utf8)! 
print("clearData: \(clearData as NSData)") 
print("keyData:  \(keyData as NSData)") 

var cryptData :Data? 
do { 
    cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData) 
    print("cryptData: \(cryptData! as NSData)") 
} 
catch (let status) { 
    print("Error aesCBCEncrypt: \(status)") 
} 

let decryptData :Data? 
do { 
    let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData) 
    print("decryptData: \(decryptData! as NSData)") 
} 
catch (let status) { 
    print("Error aesCBCDecrypt: \(status)") 
} 

Результат:

clearData: <636c6561 72446174 61303132 33343536> 
keyData:  <6b657944 61746138 39303132 33343536> 
cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0> 
decryptData: <636c6561 72446174 61303132 33343536> 

Примечания:
Одна типичная проблема с CBC, например режим кода является то, что он оставляет создание и совместное использование случайной IV пользователю. Этот пример включает в себя создание IV, префиксацию зашифрованных данных и использование префикса IV во время дешифрования. Это освобождает случайного пользователя от деталей, которые необходимы для CBC mode.

Для обеспечения безопасности зашифрованные данные также должны иметь аутентификацию, этот примерный код не предусматривает того, чтобы быть небольшим и обеспечивать лучшую совместимость для других платформ.

Также отсутствует ключевой вывод ключа из пароля, предлагается использовать PBKDF2, поскольку текстовые пароли используются в качестве материала для ввода ключей.

Для надежного производства готового многоплатформенного кода шифрования см. RNCryptor.