在iOS Swift中使用CBC模式进行AES 128解密

时间:2015-11-03 10:56:49

标签: ios iphone swift cryptography

我正在使用CommonCrypto来解密从服务器获取的加密MP3文件。 实际上,服务器端使用 AES 128 位加密与 CBC 模式和PKCS5Padding。所以我想以相同的方式解密它。

我使用下面的代码进行解密。

    #import <CommonCrypto/CommonCrypto.h

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

    let ivBytes = UnsafePointer<UInt8>(ivData.bytes)
    print("ivLength    = \(ivData.length), ivData    = \(ivData)")

    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(kCCOptionPKCS7Padding)

    var numBytesEncrypted :size_t = 0

    let cryptStatus = CCCrypt(operation,
        algoritm,
        options,
        keyBytes, keyLength,
        ivBytes,
        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;
}

如何在此代码中指定 CBC 模式和PKCS5Padding

提前致谢

1 个答案:

答案 0 :(得分:2)

AES的块大小始终使用 16 字节。 PKCS5Padding的块大小定义为 8 字节。所以你不能使用像AES/CBC/PKCS5Padding这样的组合。 只有当您的区块大小不超过 8 字节时才能使用PKCS5Padding

另一件事

CCCrypt默认适用于CBC模式,因此在这种情况下您无需提及CBC模式。例如,如果您想要ECB模式,那么您应该提及kCCOptionECBMode

不幸的是,Apple文档没有PKCS5Padding。当您的块大小精确 8 字节时,您可以使用PKCS7Padding替代PKCS5Padding