【问题标题】:Why does this AES128 Decryption take so long on iPhone?为什么这个 AES128 解密在 iPhone 上需要这么长时间?
【发布时间】:2015-05-18 17:13:56
【问题描述】:

我正在解密从 php 服务器发送的图像。 我正在使用 CryptoSwift 库来解密图像,图像以 NSData 的形式出现,解密后,我从 NSData 创建一个 UIImage。

但是解密大约需要1分10秒,非常慢。 图片数据大小:

println(imageData.length)
result: 32592

我相信这不是一个大文件,对吧? 这是我用来解密图像数据的代码:

let aes = AES(key: keyData, iv: ivData, blockMode: .ECB) 
let decryptedData = aes?.decrypt(encryptedSnap, removePadding: true)
let image = UIImage(data: decryptedData!)

我尝试在不同的线程上运行该进程,但结果相同。 当我解密图像时,模拟器使用 100% 的 CPU,以及大约 21.5MB 的内存。

感谢任何帮助,谢谢!

【问题讨论】:

  • 1.还有其他事情发生,对于 32,592 字节的文件大小,加密应该几乎是瞬时的。 2.不要使用ECB模式,原因见here(向下滚动到企鹅图片)。
  • 绝对取决于设备以及是否有硬件支持加密。
  • 好吧,我不是加密图像的人,所以我无法更改加密模式。不过我也是这么想的,应该是瞬间吧?我在这里错过了什么?
  • 尝试使用SO answer 中的代码,看看是否是您使用的库有问题。只需添加kCCOptionECBMode 选项并忽略iv。
  • SO Answer 给出了一个关于加密的例子,但我需要解密。

标签: ios objective-c swift encryption nsdata


【解决方案1】:

斯威夫特 2.0

这里是一些使用 ECB 模式和 128 位 AES 密钥加密和解密 NSData 的简单示例代码。

测试代码

let keyString = "M02cnQ51Ji97vwT4"
let keyData = (keyString as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!

let message = "Don´t try to read this text. Top Secret Stuff"
let data = (message as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!

print("data: \(data)")
if let encryptedData = testCrypt(data, keyData:keyData, operation:UInt32(kCCEncrypt)) {
    print("encryptedData: \(encryptedData)")
    if let decryptedData = testCrypt(encryptedData, keyData:keyData, operation:UInt32(kCCDecrypt)) {
        print("decryptedData: \(decryptedData)")
    }
}

加密方法:

func testCrypt(data:NSData, keyData:NSData, operation:CCOperation) -> NSData? {
    let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
    print("keyLength   = \(keyData.length), keyData   = \(keyData)")

    let dataLength = Int(data.length)
    let dataBytes  = UnsafePointer<UInt8>(data.bytes)
    print("dataLength  = \(dataLength), data      = \(data)")

    let cryptData: NSMutableData! = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
    let cryptPointer = UnsafeMutablePointer<UInt8>(cryptData.mutableBytes)
    let cryptLength  = size_t(cryptData.length)

    let keyLength              = size_t(kCCKeySizeAES128)
    let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
    let options:   CCOptions   = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)

    var numBytesEncrypted :size_t = 0

    let cryptStatus = CCCrypt(operation,
        algoritm,
        options,
        keyBytes, keyLength,
        nil,
        dataBytes, dataLength,
        cryptPointer, cryptLength,
        &numBytesEncrypted)

    if UInt32(cryptStatus) == UInt32(kCCSuccess) {
        cryptData.length = Int(numBytesEncrypted)
        print("cryptLength = \(numBytesEncrypted), cryptData = \(cryptData)")

    } else {
        print("Error: \(cryptStatus)")
    }

    return cryptData;
}

输出:

data:                         <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>
keyLength   = 16, keyData   = <4d303263 6e513531 4a693937 76775434>
dataLength  = 46, data      = <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>

cryptLength = 48, cryptData = <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>
encryptedData:                <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>
keyLength   = 16, keyData   = <4d303263 6e513531 4a693937 76775434>
dataLength  = 48, data      = <5fd86c65 6544720c 9659b43f 2e77bf8d 9c2373d9 e1042a3d ce9a19f8 2900521e c3f8075a b6866ba5 2fcd5793 bbeb8e0c>

cryptLength = 46, cryptData = <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>
decryptedData:                <446f6ec2 b4742074 72792074 6f207265 61642074 68697320 74657874 2e20546f 70205365 63726574 20537475 6666>

【讨论】:

  • 谢谢,我会试试,让你知道:)
  • 仍然存在您使用的密钥和加密密钥大小的问题:128 位或 256 位。确保您的密钥长度与加密密钥大小匹配。还有使用什么填充,php不使用标准PKCS#7填充。
  • 我不确定密钥大小,它只是一个字符串,我怎么知道?它用 PKCS#5 填充,但应该与 #7 兼容吧?
  • PKCS#5 和 7 对于填充是相同的。密钥大小是您提供的密钥的长度(以位为单位),即 NSData 的长度。 AES 的选项有:128、192 和 256,128 就足够了,192 很少使用。请注意,加密适用于 8 位 数据,它没有任何数据表示的概念。不应使用文本,如果这将是密钥,则需要使用诸如 PKDF2(密码密钥派生函数)之类的方法进行扩展。实际加密很容易,获得安全权限很难。
  • 创建 ECB 所需要的只是删除 IV 代码并添加 kCCOptionECBMode。注意:不要在新作品中使用ECB模式并尽快更新旧作品,它不安全,请参阅ECB mode,向下滚动到企鹅。而是使用带有随机IV的CBC模式,只需在加密数据前加上IV用于解密即可,它不需要保密。
猜你喜欢
  • 2011-08-27
  • 2011-12-07
  • 2012-08-09
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多