2017-06-06 43 views
1

我最近分配了一個加密我的鏈接和參數的任務,我在swift中傳遞dataTaskWithRequest。最主要的是它應該產生與Android平臺相同的輸出。 android團隊已經使用spring創建了一個用於解密數據的後端。 Java代碼是這樣的我該如何做一個跨平臺的加密方法在IOS和Android(僅適用於AES加密..)?

類AESencrp {

private static final String ALGO = "AES"; 
private static final byte[] keyValue = 
     new byte[]{'T', 'h', 'e', 'B', 'e', 's', 't', 
       'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y'}; 

public static String encrypt(String Data) throws Exception { 
    Key key = generateKey(); 
    Cipher c = Cipher.getInstance(ALGO); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encVal = c.doFinal(Data.getBytes()); 
    String encryptedValue = new BASE64Encoder().encode(encVal); 
    return encryptedValue; 
} 

public static String decrypt(String encryptedData) throws Exception { 
    Key key = generateKey(); 
    Cipher c = Cipher.getInstance(ALGO); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 

    return decryptedValue; 
} 

private static Key generateKey() throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGO); 
    return key; 
} 

} 我不能改變這裏使用的方法和使用SWIFT的內置加密方法。是否有迅速是高效和Java代碼的輸出

我想匹配做的AES加密的方式 - POD Cryptoswift

do { 

     let encrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .ECB).encrypt(inputBytes) 
     let encrypted2: [UInt8] = try AES(key: key, iv: iv, blockMode: .ECB, padding: PKCS5).encrypt(inputBytes) 


     let encryptedNSData = NSData(bytes: encrypted, length: encrypted.count) 
     encryptedBase64 = encryptedNSData.base64EncodedStringWithOptions([]) 

     let encryptedNSData2 = NSData(bytes: encrypted2, length: encrypted2.count) 
     encryPadded = encryptedNSData2.base64EncodedStringWithOptions([]) 


     let decrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .ECB).decrypt(encrypted) 
     let result = String(bytes: decrypted, encoding: NSUTF8StringEncoding)! 
     print("result\t\(result)") 

    } catch { 
     // some error 
    } 
​​

就像你看到的兩種產品都有差異。爲什麼是這樣?

+0

你有沒有設法得到這個工作?我正在研究這個確切的問題。我的java代碼是服務器端,但其他都是一樣的。 – Slayer0248

+0

是的,我做了..我會在 –

+0

以下發布答案一個很好的支持多種語言的跨平臺解決方案是[RNCryptor](https://github.com/RNCryptor)。您還可以獲得身份驗證以及是否需要密鑰派生。 – zaph

回答

0

我通過使用crypto swift來做到這一點。您可以通過CocoaPods添加此窗格。建議您找到解決此問題的原生方法,因爲加密swift可能會影響您的應用性能。無論如何,除了它,我無法找到出路。

我使用的是swift 2.3。所以,請,如果您使用SWIFT

步驟1最新版本的轉換代碼:莢 'CryptoSwift', '0.5.2'(0.5.2僅用於SWIFT 2.3。)

第2步:創建一個字符串擴展

//加密斯威夫特

func AES_EncryptionKey() -> String { 
    let date = NSDate() 
    let calender = NSCalendar.currentCalendar() 
    let components = calender.components([.Day,.Month,.Year], fromDate: NSDate()) 
    let year = components.year 
    var day = String(components.day) 
    var month = String(components.month) 
    if day.characters.count == 1 { 
     day = "0\(String(day))" 
    } 
    if month.characters.count == 1 { 
     month = "0\(String(month))" 
    } 
    //Mark: Please change the key as per your requirment! I am using a dynamic key now rather the one specified in question . i.e It changes everday 
    let secretKey = "\(String(day))20\(month)u\(String(year))e" 
    return secretKey 

} 


func AESencrypt() throws -> String { 

    //Mark: You have to do the same thing in Android too. If u skip this here skip in android too 
    let secretKeyTest = AES_EncryptionKey().toBase64()! 



    let inputBytes: [UInt8] = Array(self.utf8) 
    let key:  [UInt8] = Array(secretKeyTest.utf8) //16 
    let iv:   [UInt8] = Array("0000000000000000".utf8) //16 

    var encryptedBase64 = "" 
    do 
    { 
     let encrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .ECB).encrypt(inputBytes) 
     let encryptedNSData = NSData(bytes: encrypted, length: encrypted.count) 
     encryptedBase64 = encryptedNSData.base64EncodedStringWithOptions([]) 

     //Mark: You have to do the same thing in Android too. If u skip this here skip in android too 
     encryptedBase64=encryptedBase64.toBase64()! 

     //Mark: Follow the same blockMode in both platform. ECB Mode is not recommended. I did it in ECB cuz it was already done in other platform 
     let decrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .ECB).decrypt(encrypted) 
     let result = String(bytes: decrypted, encoding: NSUTF8StringEncoding)! 
     print("result\t\(result)") 
    } 
    catch 
    { 
     print("FAIL ENCRYPT") 
    } 
    print("encryptedBase64: \(encryptedBase64)") 

    return encryptedBase64 

} 

func AESdecrypt() throws -> String { 
    var decryptedString = "NIL" 
    let secretKeyTest = AES_EncryptionKey().toBase64()! 

    let key:  [UInt8] = Array(secretKeyTest.utf8) //16 
    let iv:   [UInt8] = Array("0000000000000000".utf8) //16 

    //Step1 
    let encryptedData = self.dataUsingEncoding(NSUTF8StringEncoding)! 
    if let base64Decoded_ = NSData(base64EncodedData: encryptedData, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 
    { 

     if var stringBase64 = String(data:base64Decoded_, encoding: NSUTF8StringEncoding) 
     { 
      //Step2 
      let encryptedDataSecond = stringBase64.dataUsingEncoding(NSUTF8StringEncoding)! 
      let base64DecodedSecond_ = NSData(base64EncodedData: encryptedDataSecond, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) 
      //Step3 
      let encrypted = Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(base64DecodedSecond_!.bytes), count: base64DecodedSecond_!.length)) 
      do 
      { 
       let decryptedData = try AES(key: key, iv: iv, blockMode: .ECB).decrypt(encrypted) 
       decryptedString = String(bytes: decryptedData, encoding: NSUTF8StringEncoding)! 
       print("decryptedString: \(decryptedString)") 
       print("ALL DECRYPTED") 

      } 
      catch 
      { 
       print("FAIL DECRYPT") 
      } 
     } 
    } 


    return decryptedString 


} 



func fromBase64() -> String? { 
    guard let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0)) else { 
     return nil 
    } 

    return String(data: data, encoding: NSUTF8StringEncoding) 
} 

func toBase64() -> String? { 
    guard let data = self.dataUsingEncoding(NSUTF8StringEncoding) else { 
     return nil 
    } 

    return data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) 
}} 

步驟3:最重要的是交叉檢查的這兩個平臺所有方法的方式。請遵循所有在另一個平臺上完成的步驟..

+0

最好避免使用CryptoSwift,其他事情比基於Common Crypto的實現慢500到1000倍。 Apple的Common Crypto已通過FIPS認證,並且經過充分審查,使用CryptoSwift正在考慮正確性和安全性。 – zaph