2017-06-06 2 views
1

Mir wurde kürzlich eine Aufgabe zugewiesen, meine Links und Parameter, die ich in dataskWithRequest in swift übergebe, zu verschlüsseln. Das Hauptproblem ist, sollte es die gleiche Ausgabe wie Android-Plattform produzieren. Das Android-Team hat bereits ein Backend mit Spring zur Entschlüsselung der Daten erstellt. Der Java-Code ist wie diese AESencrpWie mache ich eine plattformübergreifende Verschlüsselungsmethode, die sowohl in IOS als auch in Android funktioniert (nur AES-Verschlüsselung)?

Klasse {

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; 
} 

} Ich kann das hier verwendete Methode ändern und die eingebaute Verschlüsselungsmethode von schnellen verwenden. Gibt es eine Möglichkeit zu tun, AES-Verschlüsselung in swift, die effizient ist und passt die Ausgabe von Java-Code

Ich versuchte - 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 
    } 
JAVA CODE OUTPUT = "eJvkXYGzEjJ6RbYSp4a3OQ==" 

SWIFT CODE OUTPUT = "9UiyETvuHTsN7eIo0HfQ+w==" 

Da u sehen Es gibt einen Unterschied in beiden Ausgaben. Warum ist das?

+0

Haben Sie jemals geschafft, dies funktioniert? Ich sehe mir genau dieses Problem an. Mein Java-Code ist Server-Seite, aber alles andere ist gleich. – Slayer0248

+0

Ja, ich habe .. Ich werde die Antwort unter –

+0

posten Eine gute Cross-Plattform-Lösung, die auch mehrere Sprachen unterstützt, ist [RNCryptor] (https://github.com/RNCryptor). Sie erhalten auch eine Authentifizierung und bei Bedarf eine Schlüsselableitung. – zaph

Antwort

0

Ich tat dies mit Crypto Swift. Sie können diesen Pod über CocoaPods hinzufügen. Es wurde empfohlen, dass Sie eine native Möglichkeit finden, dieses Problem zu lösen, da crypto swift die Leistung Ihrer Anwendung beeinträchtigen kann. Jedenfalls konnte ich keinen anderen Ausweg finden.

Ich benutzte Swift 2.3. So konvertieren Sie den Code, wenn Sie die neuesten Versionen der schnellen

Schritt 1 verwenden: pod 'Cryptoswift', '0.5.2' (0.5.2 ist für SWIFT 2.3 nur.)

Schritt 2: eine Zeichenfolge Erweiterung

// Crypto Swift erstellen

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)) 
}} 

Schritt 3: Das wichtigste ist, Kreuz, um die Art und Weise alle Ihre Methoden in beiden Plattformen zu überprüfen. Befolgen Sie alle Schritte in einer Plattform in der anderen auch.

+0

Es ist am besten zu vermeiden, CryptoSwift zu verwenden, unter anderen Dingen ist es 500 bis 1000 mal langsamer als Common Crypto-basierte Implementierungen. Apples Common Crypto ist FIPS-zertifiziert und wurde daher gründlich geprüft. CryptoSwift nimmt die Chance auf Korrektheit und Sicherheit. – zaph

Verwandte Themen