Swift AES实施

时间:2016-06-26 10:18:18

标签: java ios swift cryptography

您好我正在构建一个与安静服务器通信的iOS应用程序。这需要我的java AES代码和Swift AES代码使用CryptoSwift生成相同的结果,使用此处的教程(AES Encrypt and Decrypt)。然而,与我的java代码相比,这给了我不同的结果。

这是我的java代码:

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("AES");
    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("AES");
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
    byte[] decValue = c.doFinal(decordedValue);
    String decryptedValue = new String(decValue);
    return decryptedValue;
}

public static Key generateKey() throws Exception {
    Key key = new SecretKeySpec(keyValue, "AES");
    return key;
}

public static void main(String[] args) {
    try {
        System.out.println(AES.encrypt("test"));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

这段代码给了我xGdooY + 6V8q1cze7mR9TjQ ==

这是我在swift中的代码

import Foundation
import CryptoSwift

extension String {
func aesEncrypt(key: String, iv: String) throws -> String{                                   
    let data = self.dataUsingEncoding(NSUTF8StringEncoding)
    let enc = try AES(key: key, iv: iv, blockMode:.CBC).encrypt(data!.arrayOfBytes())
    let encData = NSData(bytes: enc, length: Int(enc.count))
    let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
    let result = String(base64String)
    return result
}

func aesDecrypt(key: String, iv: String) throws -> String {
    let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0))
    let dec = try AES(key: key, iv: iv, blockMode:.CBC).decrypt(data!.arrayOfBytes())
    let decData = NSData(bytes: dec, length: Int(dec.count))
    let result = NSString(data: decData, encoding: NSUTF8StringEncoding)
    return String(result!)
}
}

    let key = "TheBestSecretKey" // length == 32
    let iv = "gqLOHUioQ0QjhuvI" // length == 16
    let s = "test"
    let enc = try! s.aesEncrypt(key, iv: iv)
    let dec = try! enc.aesDecrypt(key, iv: iv)
    print(s)
    print("enc:\(enc)")
    print("dec:\(dec)")
    print("\(s == dec)")

这段代码给了我LQu3c4HaOQf7W0CfnMMy1w ==

正如您可能看到他们独立工作但我需要它们兼容

1 个答案:

答案 0 :(得分:6)

您正在进行两种不同类型的加密 您的Java代码使用的AES密码更准确AES/ECB/PKCS5Padding,而您的快速代码相当于AES/CBC/PKCS5Padding且使用的是IV。 换句话说,你的swift代码正在进行密码块链接并使用初始化向量。虽然你的java代码在没有IV的情况下进行ECB模式 如果您不知道自己在做什么,则不应该实施加密方案,但至少应始终使用随机IV和密码块链接。
你真的不应该使用ECB模式 如果您使用随机IV,那么每次加密某些内容时,结果都会有所不同 您应该测试是否可以加密/解密每个组件之间的消息,而不是检查密文是否相同。